def ROC_prop(df, rate, attn, novel='matched'):
'''
input: subject df
rating - Familiarity score (float between 1.0 and 4.0)
attn - at time of encoding (string)
output: proportion of images encoded at ATTENTION LEVEL
given a score of RATE or higher, sorted by
CATEGORY (if category == True)
'''
# proportions
combined = float(df.loc[(df['Attention Level'] == attn) & (df['Familiarity Rating'] >= rate)].shape[0])/(df.loc[(df['Attention Level'] == attn) & (df['Familiarity Rating'] > 0)].shape[0])
if novel == 'all':
# all novel images for desired ratings in both categories
denom_f = df.loc[(df['Attention Level'] == attn) & (df['Familiarity Rating'] > 0)].shape[0]
denom_p = denom_f
else:
if novel == 'matched':
f_nov,p_nov = 'Face','Place'
elif novel == 'opposite':
p_nov,f_nov = 'Place','Face'
denom_p = df.loc[(df['Attention Level'] == attn) & (df['Category'] == p_nov) & (df['Familiarity Rating'] > 0)].shape[0]
denom_f = (df.loc[(df['Attention Level'] == attn) & (df['Category'] == f_nov) & (df['Familiarity Rating'] > 0)].shape[0])
if df.loc[(df['Attention Level'] == attn) & (df['Category'] == 'Face')].shape[0] > 0:
face = float(df.loc[(df['Attention Level'] == attn) & (df['Familiarity Rating'] >= rate) & (df['Category'] == 'Face')].shape[0])/denom_f
else:
face = np.nan
if df.loc[(df['Attention Level'] == attn) & (df['Category'] == 'Place')].shape[0] > 0:
house = float(df.loc[(df['Attention Level'] == attn) & (df['Familiarity Rating'] >= rate) & (df['Category'] == 'Place')].shape[0])/denom_p
else:
house = np.nan
props = [combined, face, house]
return(props)
def ROC_data(df, novel='matched'):
'''
input: subject df
output: list of three ROC proportion sets (list of dicts): 1) all images, 2) faces, 3) places
'''
ratings = [4.0, 3.0, 2.0, 1.0]
ROC, ROC_f, ROC_h = {},{},{}
# for each attention level
for attn in ['Novel', 'None', 'Side', 'Full', 'Category']:
for idx,roc in enumerate([ROC, ROC_f, ROC_h]):
roc[attn] = [0]
#roc[attn] = []
# for each possible number rating
for rate in ratings:
roc[attn].append(ROC_prop(df, rate, attn, novel=novel)[idx])
return(ROC, ROC_f, ROC_h)
def ROC_plot(ROC_data):
'''
input: ROC proportions (dictionary)
output: displays plot of ROC curve
'''
fig, ax = plt.subplots()
for attn,color in zip(['Category', 'Full', 'None', 'Side'],['purple','blue','orange','red']):
ax.plot(ROC_data['Novel'], ROC_data[attn], '-o', label=attn, color=color)
plt.legend(loc='upper left');
plt.ylim(0, 1)
plt.xlim(0, 1)
plt.gca().set_aspect('equal', adjustable='box')
plt.show()
def ROC_df(df):
'''
input: full df
output: list of subject df's with run-wise ROC data
'''
subject_list = []
for sub in df['Subject'].unique():
subject=[]
for run in df['Run'].unique():
subject.append(ROC_data(df[(df['Run']==run) & (df['Subject']==sub)]))
subject_list.append(subject)
return(subject_list)
def AUC(x_vals, y_vals):
'''
input:
x_vals - x values for ROC curve, arranged left to right (list of floats)
y_vals - y values for ROC curve, index matched to x_vals (list of floats)
output:
Area under the curve (AUC)
'''
AUC = 0
for i,(x,y) in enumerate(zip(x_vals, y_vals)):
if i>0:
x_delt = x - x_vals[i-1]
y_delt = y - y_vals[i-1]
AUC += (y_vals[i-1] * x_delt) + (.5 * x_delt * y_delt)
return(AUC)