KirstensGitHub
8/5/2019 - 12:17 AM

ROC_code_from_AM

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)