<jupyter_start><jupyter_text>APPENDIX A  APPENDIX A.1 : Distributions of Scores for The BHOCS Data<jupyter_code>from src.data.preprocessing.preprocess_sentiment import PreprocessSentiment
from src.feature_extraction.build_sentiment_features import BuildSentimentFeature
from src.data.make_dataset import MakeDataset

def extract_features(data_file, score_name='', score_range=None):
    # 1. Read Data
    make_dataset=MakeDataset()
    data = make_dataset.read_data(data_file)
    data['label']=data.sexist.apply(lambda x: 'sexist' if x == 1 else 'nonsexist')
    
    # 2. Preprocess
    preprocessed=PreprocessSentiment().transform(data.text)
    data['preprocessed_sent']=preprocessed
    
    # 3. Extract sentiment features
    features = BuildSentimentFeature().transform(preprocessed)
    data['negative score']=[feature[0] for feature in features]
    data['neutral score']=[feature[1] for feature in features]
    data['positive score']=[feature[2] for feature in features]
    data['compound score']=[feature[3] for feature in features]    
    return data

import seaborn as sns
sns.set_style("whitegrid")

def get_boxplot(df, score_name, score_range):
    ax=sns.boxplot(x="label", y=score_name, data=df, palette="Set1")
        
    ax.axes.set_title("bhocs data",fontsize=15)
    ax.set_xlabel("class",fontsize=20)
    ax.set_ylabel(score_name,fontsize=20)
    ax.tick_params(labelsize=15)
    ax.set_ylim(score_range[0], score_range[1])
    
def get_plots(df, score_name, score_range, binwidth=0.05):
    #Plot
    g=sns.displot(df, x=score_name, binrange=score_range, col="label", multiple="dodge", binwidth=binwidth)
    g.set_titles("{col_name} class")
    g.set_ylabels("Frequency")
data_file='/path/all_data_augmented.csv'
df=extract_features(data_file)

make_dataset=MakeDataset()
splits=make_dataset.prepare_data_splits(df, random_state=1)
X_train, y_train= make_dataset.get_data_split('BHOCS', splits, train=True, random_state=1)
#compound score 

score_range=(-1, 1)

df_fil=X_train

score_name='compound score'
sc_name='compound'
filter_name='-'

#BoxPlot
df_fil=df_fil.sort_values(by=['label'], ascending=False)
get_boxplot(df_fil, score_name, score_range)

#Statistics
desc=df_fil.groupby(['label'])[score_name].describe()
desc['count']=desc['count'].astype('int32')
desc['median']=df_fil.groupby(['label'])[score_name].median().values
desc=desc.round(2)
desc['score name']=[sc_name, sc_name]
desc['filter']=[filter_name, filter_name]
desc
#positive score

score_range=(0, 1)

df_fil=X_train

score_name='positive score'
sc_name='positive'
filter_name='-'

#BoxPlot
df_fil=df_fil.sort_values(by=['label'], ascending=False)
get_boxplot(df_fil, score_name, score_range)

#Statistics
desc=df_fil.groupby(['label'])[score_name].describe()
desc['count']=desc['count'].astype('int32')
desc['median']=df_fil.groupby(['label'])[score_name].median().values
desc=desc.round(2)
desc['score name']=[sc_name, sc_name]
desc['filter']=[filter_name, filter_name]
desc
#negative score

score_range=(0, 1)

df_fil=X_train

score_name='negative score'
sc_name='negative'
filter_name='-'

#BoxPlot
df_fil=df_fil.sort_values(by=['label'], ascending=False)
get_boxplot(df_fil, score_name, score_range)

#Statistics
desc=df_fil.groupby(['label'])[score_name].describe()
desc['count']=desc['count'].astype('int32')
desc['median']=df_fil.groupby(['label'])[score_name].median().values
desc=desc.round(2)
desc['score name']=[sc_name, sc_name]
desc['filter']=[filter_name, filter_name]
desc
#neutral score

score_range=(0, 1)

df_fil=X_train

score_name='neutral score'
sc_name='neutral'
filter_name='-'

#BoxPlot
df_fil=df_fil.sort_values(by=['label'], ascending=False)
get_boxplot(df_fil, score_name, score_range)

#Statistics
desc=df_fil.groupby(['label'])[score_name].describe()
desc['count']=desc['count'].astype('int32')
desc['median']=df_fil.groupby(['label'])[score_name].median().values
desc=desc.round(2)
desc['score name']=[sc_name, sc_name]
desc['filter']=[filter_name, filter_name]
desc<jupyter_output><empty_output><jupyter_text>APPENDIX A.2 : Distributions of Filtered Scores for The BHOCS Data<jupyter_code>#compound score != 0.0

score_range=(-1, 1)

df_fil=X_train[X_train['compound score'] != 0.0]
df_fil=make_dataset.downsample(df_fil, 1)

score_name='compound score'
sc_name='compound'
filter_name='!= 0.0'

#BoxPlot
df_fil=df_fil.sort_values(by=['label'], ascending=False)
get_boxplot(df_fil, score_name, score_range)

#Statistics
desc=df_fil.groupby(['label'])[score_name].describe()
desc['count']=desc['count'].astype('int32')
desc['median']=df_fil.groupby(['label'])[score_name].median().values
desc=desc.round(2)
desc['score name']=[sc_name, sc_name]
desc['filter']=[filter_name, filter_name]
desc
#positive score > 0.11

score_range=(0, 1)

df_fil=X_train[(X_train['positive score'] > 0.11)]
df_fil=make_dataset.downsample(df_fil, 1)

score_name='positive score'
sc_name='positive'
filter_name='> 0.11'

#BoxPlot
df_fil=df_fil.sort_values(by=['label'], ascending=False)
get_boxplot(df_fil, score_name, score_range)

#Statistics
desc=df_fil.groupby(['label'])[score_name].describe()
desc['count']=desc['count'].astype('int32')
desc['median']=df_fil.groupby(['label'])[score_name].median().values
desc=desc.round(2)
desc['score name']=[sc_name, sc_name]
desc['filter']=[filter_name, filter_name]
desc
#negative score > 0.06

score_range=(0, 1)

df_fil=X_train[(X_train['negative score'] > 0.06)]
df_fil=make_dataset.downsample(df_fil, 1)

score_name='negative score'
sc_name='negative'
filter_name='> 0.06'

#BoxPlot
df_fil=df_fil.sort_values(by=['label'], ascending=False)
get_boxplot(df_fil, score_name, score_range)

#Statistics
desc=df_fil.groupby(['label'])[score_name].describe()
desc['count']=desc['count'].astype('int32')
desc['median']=df_fil.groupby(['label'])[score_name].median().values
desc=desc.round(2)
desc['score name']=[sc_name, sc_name]
desc['filter']=[filter_name, filter_name]
desc
#neutral score < 0.76

score_range=(0, 1)

df_fil=X_train[(X_train['neutral score'] < 0.76)]
df_fil=make_dataset.downsample(df_fil, 1)

score_name='neutral score'
sc_name='neutral'
filter_name='< 0.76'

#BoxPlot
df_fil=df_fil.sort_values(by=['label'], ascending=False)
get_boxplot(df_fil, score_name, score_range)

#Statistics
desc=df_fil.groupby(['label'])[score_name].describe()
desc['count']=desc['count'].astype('int32')
desc['median']=df_fil.groupby(['label'])[score_name].median().values
desc=desc.round(2)
desc['score name']=[sc_name, sc_name]
desc['filter']=[filter_name, filter_name]
desc<jupyter_output><empty_output><jupyter_text>APPENDIX B : Classification performance of the Logit, CNN, and SVM.<jupyter_code>file_name1='../experiments/3_rq2_across_data_domains/results_rq2.pkl'

results_df1=[]
with open(file_name1, 'rb') as f:
    results_df1 = pickle.load(f)


# The code below is copied from this repository (https://github.com/gesiscss/sexist_code_icwsm20).
####################################################################
import pickle
import pandas as pd
import seaborn as sns

def format_domain_name(r):
    #{'bho', 'bho-M', 'bhocs', 'bhocs-M', 'c', 'c-M', 's'}
    r=r.lower()
    if r == 'bhom':
        return 'bho-M'
    elif r == 'bhocsm':
        return 'bhocs-M'
    elif r == 'cm':
        return 'c-M'
    else:
        return r

def format_model_name(name):
    if name == 'gender_word':
        return 'gender word'
    elif name == 'threshold_classifier':
        return 'toxicity'
    elif name == 'logistic_regression':
        return 'logit'
    else:
        return name

def format_columns(df):
    df['train_domain']=[format_domain_name(row['train_domain']) for index, row in df.iterrows()]
    df['test']=[format_domain_name(row['test_domain']) for index, row in df.iterrows()]
    df['model']=[format_model_name(row['model_name']) for index, row in df.iterrows()]
    df['variable']=['macro avg f1-score' for index, row in df.iterrows()]
    df['value']=df['macro avg f1-score']
    return df


df=results_df1

df=format_columns(df)
df=df[['model', 'test', 'train_domain', 'variable', 'value']]

gender_bline = df[df['model'] == 'gender word'].value.mean()
toxicity_bline = df[df['model'] == 'toxicity'].value.mean()
df=df[~df.model.isin(['toxicity', 'gender word',])]
df

%pylab inline

data_order = ['bho', 'bho-M', 'c', 'c-M', 'bhocs', 'bhocs-M']
model_order = ['logit', 'cnn', u'svm',]
marker_order = ['.','o', "d","D",  "<",">",]

custom_palette = sns.color_palette("Paired",8)
custom_palette[-1] = (.5, .5, .5)
custom_palette[-2] = (.6, .6, .6)

with plt.rc_context(dict(sns.axes_style("whitegrid"),
                         **sns.plotting_context("notebook", font_scale=1.35, 
                                                rc={"lines.linewidth": 1.,}
                                               ))):
    g = sns.catplot(x='test', y='value', col='model', hue='train_domain',  
                    data=df, kind='point',
                    sharex=True, sharey=True,
                    col_order = model_order,
                    hue_order = data_order,
                    order = data_order+['s'],
                    markers=marker_order,
                    legend=False,
                    legend_out=True,
                
                    palette=custom_palette,
                    dodge=.5,
                    join=False,
                    aspect=1.3
                   )
    g.set_xlabels("test set")
    for ax in g.axes[0]: 
        ax.set_xticklabels(ax.get_xticklabels(), rotation=30, ha='center')
        plt.setp(ax.collections, sizes=[40])

    g.axes[0, 0].set_ylabel(u'macro avg f1-score')

    g.fig.suptitle('performance by model type', x=0, ha='left', y=1.1)
    l=g.axes[0, 2].legend(loc='upper right', bbox_to_anchor=(0.3, 1.4), ncol=3,
              fancybox=False, shadow=False, frameon=False)
    l.set_title('training set:')
    l.get_title().set_position((-240, -22))
    plt.setp(l.get_title(),fontsize=l.prop.get_size())

    clrs = dict(zip(data_order,
                   custom_palette, ))
    mrkrs = dict(zip(data_order,marker_order ))    
    pltn = {j: i for i, j in enumerate(model_order)}
    mdln = {j:i for i, j in enumerate(data_order)}
    import matplotlib.patches as patches
    for a, d in df.groupby(["train_domain","model"]).mean().reset_index().groupby("model"):
        for mdl, v in d.set_index('train_domain').value.to_dict().items():
            g.axes[0, pltn[a]].scatter([6.8+(mdln[mdl]/8.)], [d.set_index('train_domain').value.to_dict()[mdl]],
                                          c=clrs[mdl], marker=mrkrs[mdl], clip_on=True)
    for i in range(3):
        l1 = g.axes[0, i].plot((6.7, 7.75), 
                                    (gender_bline, gender_bline),
                                    ls=':', lw=2, c='.3', clip_on = True,
                                      )  

        l2 = g.axes[0, i].plot((6.7, 7.75), 
                                    (toxicity_bline, toxicity_bline),
                                    ls='--', lw=2, c='.3', clip_on = True, 
                                      )  

    for i in range(3):
        g.axes[0, i].add_patch( patches.Rectangle((6.7,g.axes[0, pltn[a]].get_ylim()[0]),
                                                        1.05,.9-g.axes[0, pltn[a]].get_ylim()[0],
                                                        linewidth=2,
                                                        edgecolor='.7',
                                                        facecolor='none',
                                                        clip_on=False))
        g.axes[0, i].text(6.7+1.05/2, .92, 'avg', ha='center')
        
    from matplotlib.lines import Line2D

    lss = [':', '--']
    lines = [Line2D([0], [0], color='.3', linewidth=2, linestyle=ll) for ll in lss]
    labels = ['gender word', 'toxicity',]
    ll=g.axes[0, i].legend(lines, labels, loc='upper right', bbox_to_anchor=(1., 1.4), ncol=1,
              fancybox=False, shadow=False, frameon=False)
    ll.set_title('baseline:')
    ll.get_title().set_position((-140, -22))
    plt.setp(l.get_title(),fontsize=l.prop.get_size())
    g.axes[0, i].add_artist(l)<jupyter_output>Populating the interactive namespace from numpy and matplotlib
{'fraction_non_alphanumeric': 0.17097724668521852, 'fraction_numerical': 0.017760680962514323, 'mean_word_length': 3.7974087161366312, 'pattern_counts': {'":': 1, '<': 16, '<?xml version=': 0, '>': 19, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '325989', 'license': 'MIT', 'n_tokens_mistral': 4527, 'n_tokens_neox': 4304, 'n_words': 716, 'path': 'notebooks/3_appendix.ipynb', 'repo_name': 'gesiscss/sexism_custom_classifier', 'size': '12218'}