Pandas equivalent to calculate False Positive Rate

Viewed 547

I have a pandas dataframe df from a ML classifier that has the following fields userid, classifier_score, truth. I want to calculate the false positive rate per userid at a threshold of 0.62. classifier_score ranges in the data go from 0.1999 to a 0.89. Right now, I use a series of conditions and create a new column col that states whether if the relationship between truth and classifier score is a false positive, false negative, true positive or true negative

df['col'] = df.apply(condition, axis=1)

Then I store the the unique userids in a list

unique_users = df.user.unique().tolist() Then I loop through each one to calculate False positive score.

fpr_dict = {}
for id in user_ids:
   fn, tn, fp, tp = 0, 0, 0, 0 
   elems = df[df.userid==id].tolist()
   for elem in col:
       if elem == 'fn': fn += 1
       elif elem == 'fp': fp += 1
       elif elem == 'tp': tp += 1
       elif elem == 'tn': tn += 1
   try:
      fpr = fp / (fp + tn) 
   except ZeroDivisionError:
      fpr = 0.0
   fpr_dict[id] = fpr

Is there a better way of doing this with just pandas functions? Note: I initialize fn, tn, fp, tp to 0 because some user ids might not have all 4 of them, they will have some combination of the 4

Edit: Dataframe

userid | classifier_score | truth  | col 
0001      0.6721            1        TP
0001      0.2918            1        FP
0001      0.1236            0        TN
.
.
.
0064      0.7168            0        FN
1 Answers

I didn't test it with an actual dataframe, maybe try this

th = 0.62
predicted_pos = df['classifier_score'] > th

userid_group = df.groupby('userid', sort=False)

userid_count = userid_group.size()

df['fp'] = predicted_pos & (df['truth'] == 0)
fpr = userid_group['fp'].sum() / userid_count

if you want a dictionary, you can put dict(fpr) in the end


Edit: As OP pointed out, fpr = fp/(fp + tn), the calculation should be:

th = 0.62
predicted_pos = df['classifier_score'] > th

userid_group = df.groupby('userid', sort=False)

df['fp'] = predicted_pos & (df['truth'] == 0)
df['tn'] = df['truth'] == 0

fp = userid_group['fp'].sum()
tn = userid_group['tn'].sum()
fpr =  fp / (fp + tn)
Related