<jupyter_start><jupyter_text>Post processing global explanation quality<jupyter_code>def post_processing_local_explanation_quality(train_or_test, comparison_metric):
    """Returns an dataframe where each row is an explainer and each column is a 
    regression method. The value of the cells are the median observed for all
    data sets.
    
    comparison_metric should be a function that takes two explanation arrays
    and return a single value (can be vectorized, and the arrays should be 
    two dimensional, each line corresponding to a explanation and each row
    corresponding to a variable). The comparison_metric will be used to
    compare explanations for the original feynman equation and the regressor
    explanation using the same explainer.
    """
    
    # Feynman is used as ground truth here
    if train_or_test == 'train':
        df_feynman = pd.read_csv(f'{Auxiliary.local_path_train}Feynman_regressor_explanation.csv')
    else:
        df_feynman = pd.read_csv(f'{Auxiliary.local_path_test}Feynman_regressor_explanation.csv')
        
    for col_name in df_feynman.columns:
        if col_name.startswith('obs_'):
            df_feynman[col_name] = df_feynman[col_name].map(Auxiliary.convert_to_array_of_floats)
        df_feynman.dropna(inplace=True, axis=0)
    df_feynman.dropna(inplace=True, axis=1)
    
    data = []
    for regressor in regressors.__all__ + ['Operon_regressor']:
        df_regressor = None
        if train_or_test == 'train':
            df_regressor = pd.read_csv(f'{Auxiliary.local_path_train}{regressor}_explanation.csv')
        else:
            df_regressor = pd.read_csv(f'{Auxiliary.local_path_test}{regressor}_explanation.csv')

        for col_name in df_regressor.columns:
            if col_name.startswith('obs_'):
                df_regressor[col_name] = df_regressor[col_name].map(Auxiliary.convert_to_array_of_floats)
            df_regressor.dropna(inplace=True, axis=0)
        df_regressor.dropna(inplace=True, axis=1)

        # Merging ground truth and explanations data frames       
        df_merged = pd.merge(df_regressor, df_feynman,
            on=["dataset", 'explainer'], how='left', suffixes=(None, '_feynman'))

        def calculate_safe_metric(row):
            try:
                return np.mean(comparison_metric(
                    np.vstack((row[[f'obs_{i}' for i in range(30)]])),
                    np.vstack((row[[f'obs_{i}_feynman' for i in range(30)]])),
                ))
            except Exception as e:
                print(e, row)
                
                return np.nan

        # applying the metric row-wise
        df_merged[comparison_metric.__name__] = df_merged.apply(calculate_safe_metric, axis=1)
        
        # Improving the name of explainers
        df_merged['explainer'] = df_merged['explainer'].map(lambda x: x.replace('_explainer', ''))

        df_merged = df_merged.groupby(['dataset', 'explainer']).mean().reset_index(level=[0,1])
        
        df_pivoted = df_merged.pivot(
            index='dataset', columns='explainer')[comparison_f.__name__]
        
        df_merged = df_merged.groupby(['explainer']).median()[comparison_f.__name__]

        # Making extreme outliers become nan
        df_merged = df_merged[df_merged < 5000]
        df_merged.name = regressor.replace('_regressor', '')
        
        data.append(df_merged)
        
    return pd.concat(data, axis=1)
# We use reverse colormaps in cases where smaller values are better,
# so there is a convention in the color: lighter is better
comparisons_and_maps = [
    (Auxiliary.Cosine_similarity, sns.color_palette("rocket",   as_cmap=True)), 
    (Auxiliary.RMSE,              sns.color_palette("rocket_r", as_cmap=True)),
    (Auxiliary.NMSE,              sns.color_palette("rocket_r", as_cmap=True))
]

for comparison_f, cmap in comparisons_and_maps:
    print(comparison_f.__name__)
    
    all_regressors = post_processing_local_explanation_quality(
        comparison_metric=comparison_f, train_or_test='test')
    
    all_regressors = all_regressors[
        ['KNN', 'Linear', 'Lasso', 'DecisionTree', 'RF', 'MLP', 'SVM', 'XGB', 'Operon', 'ITEA']
    ].T
    
    all_regressors = (all_regressors).drop(['PartialEffectsadj', 'SHAPadj'], axis=1)
    
    all_regressors = all_regressors[
        ['PartialEffects', 'SHAP', 'IntegratedGradients', 'LIME', 'RandomImportance'] #'ELA', 
    ]
    
    all_regressors.columns = ['\n'.join(re.findall('[A-Z]+[a-z]*', col)) for col in all_regressors.columns]

    f, ax = plt.subplots(figsize=(10, 3.5))
    
    sns.heatmap(all_regressors.T, linewidths=.5, ax=ax,
        annot=True, fmt=".2f", #english format
        #annot=all_regressors.T.applymap(lambda x: f"{x:.2f}".replace('.',',')).values, fmt='', # pt-br format
        cmap = cmap,
    )

    plt.xticks(rotation=30, ha='right') 

    plt.tight_layout()
    plt.savefig(f'{analyzed_path}{comparison_f.__name__}_local_heatmap.pdf', bbox_inches='tight')
    plt.show()<jupyter_output>Cosine_similarity
{'fraction_non_alphanumeric': 0.11369509043927649, 'fraction_numerical': 0.00516795865633075, 'mean_word_length': 3.1010594947025263, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '176306', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 1718, 'n_tokens_neox': 1611, 'n_words': 326, 'path': 'post hoc analysis/scripts and notebooks/Local explanations qualities.ipynb', 'repo_name': 'gAldeia/iirsBenchmark', 'size': '5031'}