|
import ipdb |
|
import pandas as pd |
|
import os |
|
import re |
|
from scipy import stats |
|
|
|
|
|
def format_number(num): |
|
|
|
if isinstance(num, (int, float)): |
|
if abs(num) >= 10**2: |
|
return f"{num:.1e}" |
|
else: |
|
return f"{num:.3f}" |
|
|
|
return num |
|
|
|
def norm_sNavie(df): |
|
df_normalized = df.copy() |
|
seasonal_naive_row = df[df['model'] == 'seasonal_naive'].iloc[0] |
|
print('df: ',df) |
|
for column in df.columns: |
|
if column != 'model': |
|
df_normalized[column] = df[column] / seasonal_naive_row[column] |
|
return df_normalized |
|
|
|
def pivot_df(file_name, tab_name): |
|
df = pd.read_csv(file_name) |
|
if tab_name == 'univariate': |
|
df['univariate'] = df['univariate'].replace({True: 'univariate', False: 'multivariate'}) |
|
df.rename(columns={'univariate': 'variate_type'}, inplace=True) |
|
tab_name = 'variate_type' |
|
df_melted = pd.melt(df, id_vars=[tab_name, 'model'], var_name='metric', value_name='value') |
|
df_melted['metric'] = df_melted['metric'].replace({ |
|
'eval_metrics/MAPE[0.5]': 'MAPE', |
|
'eval_metrics/mean_weighted_sum_quantile_loss': 'CRPS' |
|
}) |
|
df_pivot = df_melted.pivot_table(index='model', columns=[tab_name, 'metric'], values='value') |
|
df_pivot.columns = [f'{tab_name} ({metric})' for tab_name, metric in df_pivot.columns] |
|
|
|
|
|
df_pivot = df_pivot.reset_index() |
|
df_pivot = df_pivot.round(3) |
|
return df_pivot |
|
|
|
|
|
def rename_metrics(df): |
|
df = df.rename(columns={ |
|
'eval_metrics/MASE[0.5]': 'MASE', |
|
'eval_metrics/mean_weighted_sum_quantile_loss': 'CRPS', |
|
'rank': 'Rank' |
|
}) |
|
return df |
|
|
|
def format_df(df): |
|
df = df.applymap(format_number) |
|
|
|
df.iloc[:, 1:] = df.iloc[:, 1:].astype(float) |
|
return df |
|
|
|
def unify_freq(df): |
|
|
|
df['frequency'] = df['frequency'].str.replace(r'\d+', '', regex=True) |
|
|
|
df['frequency'] = df['frequency'].str.split('-').str[0] |
|
|
|
|
|
freq_conversion = { |
|
'T': 'Minutely', |
|
'H': 'Hourly', |
|
'D': 'Daily', |
|
'W': 'Weekly', |
|
'M': 'Monthly', |
|
'Q': 'Quarterly', |
|
'Y': 'Yearly', |
|
'A': 'Yearly', |
|
'S': 'Secondly' |
|
} |
|
|
|
|
|
df['frequency'] = df['frequency'].replace(freq_conversion) |
|
return df |
|
def pivot_existed_df(df, tab_name): |
|
df = df.reset_index() |
|
if tab_name == 'univariate': |
|
df['univariate'] = df['univariate'].replace({True: 'univariate', False: 'multivariate'}) |
|
df.rename(columns={'univariate': 'variate_type'}, inplace=True) |
|
tab_name = 'variate_type' |
|
print('tab_name:', tab_name, 'df: ',df) |
|
print('columns', df.columns) |
|
df_melted = pd.melt(df, id_vars=[tab_name, 'model'], var_name='metric', value_name='value') |
|
df_melted['metric'] = df_melted['metric'].replace({ |
|
'eval_metrics/MASE[0.5]': 'MASE', |
|
'eval_metrics/mean_weighted_sum_quantile_loss': 'CRPS', |
|
'rank': 'Rank', |
|
}) |
|
df_pivot = df_melted.pivot_table(index='model', columns=[tab_name, 'metric'], values='value') |
|
df_pivot.columns = [f'{tab_name} ({metric})' for tab_name, metric in df_pivot.columns] |
|
df_pivot = df_pivot.reset_index() |
|
|
|
df_pivot = format_df(df_pivot) |
|
|
|
|
|
|
|
return df_pivot |
|
|
|
|
|
def get_grouped_dfs(root_dir='results', ds_properties='results/dataset_properties.csv'): |
|
df_list = [] |
|
|
|
|
|
for subdir, _, files in os.walk(root_dir): |
|
for file in files: |
|
if file == 'all_results.csv': |
|
file_path = os.path.join(subdir, file) |
|
df = pd.read_csv(file_path) |
|
df_list.append(df) |
|
|
|
all_results_df = pd.concat(df_list, ignore_index=True) |
|
all_results_df = all_results_df.sort_values(by=['model', 'dataset']).reset_index(drop=True) |
|
all_results_df[['dataset', 'frequency', 'term_length']] = all_results_df['dataset'].str.split('/', expand=True) |
|
|
|
dataset_properties = pd.read_csv(ds_properties) |
|
|
|
|
|
dataset_properties['dataset'] = dataset_properties['dataset'].apply(lambda x: x.lower()) |
|
|
|
dataset_properties['dataset'] = dataset_properties['dataset'].apply(lambda x: x.replace(' ', '_')) |
|
|
|
dataset_properties['dataset'] = dataset_properties['dataset'].apply(lambda x: x.replace('-', '_')) |
|
|
|
dataset_properties['dataset'] = dataset_properties['dataset'].apply(lambda x: re.sub('_+', '_', x)) |
|
|
|
dataset_properties['dataset'] = dataset_properties['dataset'].apply(lambda x: x.strip('_')) |
|
|
|
df = all_results_df |
|
|
|
|
|
dataset_properties_dict = dataset_properties.set_index('dataset').T.to_dict('dict') |
|
dataset_properties_dict.keys() |
|
|
|
|
|
for dataset in dataset_properties_dict.keys(): |
|
for key in dataset_properties_dict[dataset].keys(): |
|
|
|
|
|
|
|
if key == 'frequency': |
|
|
|
if all(df[df['dataset'] == dataset]['frequency'].isna()): |
|
df.loc[df['dataset'] == dataset, key] = dataset_properties_dict[dataset][key] |
|
else: |
|
df.loc[df['dataset'] == dataset, key] = dataset_properties_dict[dataset][key] |
|
|
|
|
|
df = unify_freq(df) |
|
|
|
df = standardize_df(df) |
|
metric_columns = ['eval_metrics/MSE[mean]', 'eval_metrics/MSE[0.5]', 'eval_metrics/MAE[0.5]', |
|
'eval_metrics/MASE[0.5]', 'eval_metrics/MAPE[0.5]', 'eval_metrics/sMAPE[0.5]', |
|
'eval_metrics/MSIS', 'eval_metrics/RMSE[mean]', 'eval_metrics/NRMSE[mean]', |
|
'eval_metrics/ND[0.5]', 'eval_metrics/mean_weighted_sum_quantile_loss'] |
|
RANKING_METRIC = "eval_metrics/mean_weighted_sum_quantile_loss" |
|
df['rank'] = df.groupby(['dataset', 'term_length', 'frequency'])[f'{RANKING_METRIC}'].rank(method='first', |
|
ascending=True) |
|
|
|
metric_columns.append('rank') |
|
|
|
df['univariate'] = df['num_variates'] == 1 |
|
|
|
|
|
METRIC_CHOICES = ["eval_metrics/MASE[0.5]", "eval_metrics/mean_weighted_sum_quantile_loss"] |
|
|
|
grouped_results_overall = df.groupby(['model'])[METRIC_CHOICES].agg(stats.gmean) |
|
grouped_results_overall_rank = df.groupby(['model'])[['rank']].mean() |
|
grouped_results_overall = pd.concat([grouped_results_overall, grouped_results_overall_rank], axis=1) |
|
|
|
|
|
|
|
grouped_dfs = {} |
|
for col_name in ["domain", 'term_length', 'frequency', 'univariate']: |
|
grouped_dfs[col_name] = group_by(df, col_name) |
|
|
|
|
|
grouped_dfs['overall'] = grouped_results_overall |
|
return grouped_dfs |
|
|
|
def standardize_df(df): |
|
|
|
metric_columns = ['eval_metrics/MSE[mean]', 'eval_metrics/MSE[0.5]', 'eval_metrics/MAE[0.5]', |
|
'eval_metrics/MASE[0.5]', 'eval_metrics/MAPE[0.5]', 'eval_metrics/sMAPE[0.5]', |
|
'eval_metrics/MSIS', 'eval_metrics/RMSE[mean]', 'eval_metrics/NRMSE[mean]', |
|
'eval_metrics/ND[0.5]', 'eval_metrics/mean_weighted_sum_quantile_loss'] |
|
|
|
|
|
for metric in metric_columns: |
|
df[metric] = df[metric].astype(float) |
|
df[metric] = df[metric].fillna(df[metric].mean()) |
|
|
|
df[metric_columns] = df[metric_columns].astype(float) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
original_df = df.copy() |
|
|
|
dataset_corrections = { |
|
"saugeenday": "saugeen", |
|
"temperature_rain_with_missing": "temperature_rain", |
|
"kdd_cup_2018_with_missing": "kdd_cup_2018", |
|
"car_parts_with_missing": "car_parts", |
|
} |
|
df['dataset'] = df['dataset'].replace(dataset_corrections) |
|
dataset_names = df['dataset'].unique() |
|
|
|
for dataset in dataset_names: |
|
term_lengths = df[df['dataset'] == dataset]['term_length'].unique() |
|
for term_length in term_lengths: |
|
frequencies = df[(df['dataset'] == dataset) & (df['term_length'] == term_length)]['frequency'].unique() |
|
for frequency in frequencies: |
|
|
|
seasonal_naive_results = df[ |
|
(df['dataset'] == dataset) & (df['frequency'] == frequency) & (df['term_length'] == term_length) & ( |
|
df['model'] == 'Seasonal_Naive')] |
|
for metric in metric_columns: |
|
try: |
|
|
|
df.loc[(df['dataset'] == dataset) & (df['frequency'] == frequency) & ( |
|
df['term_length'] == term_length), metric] = df[(df['dataset'] == dataset) & ( |
|
df['frequency'] == frequency) & (df['term_length'] == term_length)][metric] / \ |
|
seasonal_naive_results[metric].values[0] |
|
except Exception: |
|
print(f"Error: {dataset} {term_length} {frequency} {metric}") |
|
ipdb.set_trace() |
|
|
|
return df |
|
|
|
def group_by(df, col_name): |
|
METRIC_CHOICES = ["eval_metrics/MASE[0.5]", "eval_metrics/mean_weighted_sum_quantile_loss"] |
|
grouped_results = df.groupby([col_name, 'model'])[METRIC_CHOICES].agg(stats.gmean) |
|
grouped_results_rank = df.groupby([col_name, 'model'])[['rank']].mean() |
|
grouped_results = pd.concat([grouped_results, grouped_results_rank], axis=1) |
|
|
|
|
|
|
|
return grouped_results |