privacytrustlab / ml_privacy_meter

Privacy Meter: An open-source library to audit data privacy in statistical and machine learning algorithms.
MIT License
588 stars 100 forks source link

ROC visualization problem #25

Closed luigitropiano closed 1 year ago

luigitropiano commented 3 years ago

In some situations there seems to be problems with how the ROC curve is calculated. This is clearly visible when there is a very high number of False Positives or False Negatives. I'll post an example where IMHO the auc should be 0.5 (and not 1.0), as all my samples are classified as positives and there are no negatives.

privacy_risk roc

The error is probably due to following line in meminf.py: https://github.com/privacytrustlab/ml_privacy_meter/blob/abf42232dfd712bc377db690190dfdff53db7eac/ml_privacy_meter/attack/meminf.py#L592

I think it should be something like: fpr, tpr, _ = roc_curve(target, probs > 0.5)

From what I can see, in fact, the error comes from the way SKLearn sets the thresholds for computing the false positive rate and the true positive rate when passing an array with float values: If your target vector is [[1], [0], [1], [1], [0]] and your predictions vector (probs) is [[0.9], [0.9], [0.9], [0.9], [0.9]] the auc(fpr, tpr) value returned by SKLearn is 0.5, (meaning there are 0 false negatives and 2 false positives, and that's fine), but if your predictions vector is [[0.9], [0.8], [0.9], [0.9], [0.8]] the auc(fpr, tpr) value returned by SKLearn is 1, (like there were 0 false negatives and 0 false positives))

If I get this right, this is an unwanted behavior for your use-case, as you want an auc of 0.5 in both cases (both 0.8 and 0.9 are values greater then 0.5 and a prediction value greater than 0.5 should count as false positive if the target value is 0)

By doing probs > 0.5, however, it returns a vector of booleans of the same size as probs with True where the original values were greater then 0.5 and with False otherwhere; passing this vector instead of probs seems to work.

amad-person commented 3 years ago

Hi @tr0p1x, thanks for opening the issue.

From what I can see, in fact, the error comes from the way SKLearn sets the thresholds for computing the false positive rate and the true positive rate when passing an array with float values.

Yes, you're right. sklearn is computing the threshold after seeing the data instead of fixing it at 0.5. However, this is desired behaviour for our library - because in membership inference attacks we want to find the best threshold that separates out members and non-members.

Hope this clears things up!

luigitropiano commented 3 years ago

One more doubt then: isn't that conflicting with how the attack accuracy is computed (with a fixed threshold at 0.5) ? https://github.com/privacytrustlab/ml_privacy_meter/blob/abf42232dfd712bc377db690190dfdff53db7eac/ml_privacy_meter/attack/meminf.py#L429 I think there may be situations where the tool reports a very low attack accuracy but an almost perfect ROC curve.