You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何复刻结合运行时间与MAE的排序模型可视化图表

如何复刻结合运行时间与MAE的排序模型可视化图表

首先得先帮你理清核心问题:你需要同时保留**MAE性能(越小越好)运行时间(越短越好)**的信息,还要生成能体现模型综合排名的可视化。先给你修正下原始数据的小问题——Python字典里不能直接写0:00:43.387145这种时间格式,得转成字符串后续再处理,不然DataFrame会直接报错。

接下来咱们一步步实现接近目标的方案:

一、数据预处理:统一格式+计算综合排名

首先把运行时间转成可计算的秒数,然后分别对MAE和运行时间做排名,最后取平均得到综合排名(两个指标都是越小越优,所以排名用升序):

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 修正数据格式:运行时间用字符串存储
data1 = {
    'Models': ['LinearRegression', 'Random Forest', 'XGBoost', 'MLPRegressor', 'SVR', 'CatBoostRegressor', 'LGBMRegressor'],
    'MAE': [4.906, 2.739, 2.826, 5.234, 5.061, 2.454, 2.76],
    'Runtime': ['0:00:43.387145', '0:28:11.761681', '0:03:58.883474', '0:01:44.252276' , '0:04:52.754769', '0:19:36.925169', '0:04:51.223103']
}
data2 = {
    'Models': ['LinearRegression', 'Random Forest', 'XGBoost', 'MLPRegressor', 'SVR', 'CatBoostRegressor', 'LGBMRegressor'],
    'MAE': [4.575, 2.345, 2.129, 4.414, 4.353, 2.281, 2.511],
    'Runtime': ['0:00:45.055854', '0:10:55.468473', '0:01:01.575033' , '0:00:31.231719' , '0:02:12.258870', '0:08:16.526615' , '0:15:25.084937']
}
data3 = {
    'Models': ['LinearRegression', 'Random Forest', 'XGBoost', 'MLPRegressor', 'SVR', 'CatBoostRegressor', 'LGBMRegressor'],
    'MAE': [4.575, 2.345, 2.129, 4.414, 4.353, 2.281, 2.511],
    'Runtime': ['0:00:40.055854', '0:11:55.468473', '0:01:03.575033' , '0:00:29.231719' , '0:02:02.258870', '0:07:16.526615' , '0:13:25.084937']
}

# 转成DataFrame并处理时间指标
dfs = [pd.DataFrame(data) for data in [data1, data2, data3]]
for df in dfs:
    # 把时间转成总秒数,方便计算排名
    df['Runtime_seconds'] = pd.to_timedelta(df['Runtime']).dt.total_seconds()
    # 计算单指标排名:MAE越小排名越前,运行时间越短排名越前
    df['MAE_Rank'] = df['MAE'].rank(ascending=True)
    df['Runtime_Rank'] = df['Runtime_seconds'].rank(ascending=True)
    # 综合排名:取两个指标排名的平均值,数值越小综合性能越好
    df['Overall_Rank'] = (df['MAE_Rank'] + df['Runtime_Rank']) / 2

# 合并三个数据集,添加数据集标识
for idx, df in enumerate(dfs, 1):
    df['Dataset'] = f'Dataset {idx}'
combined_df = pd.concat(dfs, ignore_index=True)

二、复刻可视化图表的三种方案

根据你参考图的需求,这里给你提供三种不同风格的实现,都能同时体现MAE、运行时间和综合排名:

方案1:双轴散点图(直观展示指标关系)

这个方案可以清晰看到每个模型在不同数据集下的MAE和运行时间分布,同时按综合排名排序模型:

plt.figure(figsize=(12, 8))
sns.set_style("whitegrid")

# 按综合排名的中位数排序模型,保证x轴是从优到劣的顺序
model_order = combined_df.groupby('Models')['Overall_Rank'].median().sort_values().index

# 绘制MAE散点
sns.scatterplot(data=combined_df, x='Models', y='MAE', hue='Dataset', s=150, marker='o', ax=plt.gca())
# 双轴绘制运行时间散点
ax2 = plt.gca().twinx()
sns.scatterplot(data=combined_df, x='Models', y='Runtime_seconds', hue='Dataset', s=150, marker='s', ax=ax2, legend=False)

# 优化图表样式
plt.gca().set_xticklabels(model_order, rotation=45, ha='right')
plt.gca().set_ylabel('MAE (数值越小性能越好)')
ax2.set_ylabel('运行时间(秒,数值越小效率越高)')
plt.title('不同数据集下模型性能与运行时间对比')
plt.tight_layout()
plt.show()

方案2:综合排名热力图(汇总跨数据集表现)

如果参考图是偏向“排名汇总”的风格,这个热力图可以直观展示每个模型在不同数据集的综合排名,旁边再附上指标统计:

# 构建排名矩阵:行是模型,列是数据集
rank_matrix = combined_df.pivot(index='Models', columns='Dataset', values='Overall_Rank').reindex(model_order)

plt.figure(figsize=(10, 6))
sns.heatmap(rank_matrix, annot=True, cmap='coolwarm_r', fmt='.1f', cbar_kws={'label': '综合排名(数值越小越好)'})
plt.title('各模型在不同数据集的综合排名')
plt.tight_layout()
plt.show()

# 输出指标汇总表,同时保留MAE和运行时间
summary_table = combined_df.groupby('Models').agg(
    平均MAE=('MAE', 'mean'),
    MAE标准差=('MAE', 'std'),
    平均运行时间=('Runtime_seconds', lambda x: str(pd.to_timedelta(x.mean(), unit='s'))),
    运行时间标准差=('Runtime_seconds', lambda x: str(pd.to_timedelta(x.std(), unit='s')))
).reindex(model_order)
print("模型性能与运行时间汇总表:")
print(summary_table.round(2))

方案3:归一化双指标条形图(类似参考图的组合展示)

如果参考图是把模型按综合排名排序,同时展示两个指标的相对表现,用归一化后的条形图可以实现:

# 对MAE和运行时间做0-1归一化,0代表最优,1代表最差
normalized_df = combined_df.copy()
normalized_df['MAE_归一化'] = (normalized_df['MAE'] - normalized_df['MAE'].min()) / (normalized_df['MAE'].max() - normalized_df['MAE'].min())
normalized_df['Runtime_归一化'] = (normalized_df['Runtime_seconds'] - normalized_df['Runtime_seconds'].min()) / (normalized_df['Runtime_seconds'].max() - normalized_df['Runtime_seconds'].min())

plt.figure(figsize=(12, 8))
sns.set_style("whitegrid")

bar_width = 0.35
x = range(len(model_order))

# 分数据集绘制堆叠条形图
for idx, dataset in enumerate(normalized_df['Dataset'].unique()):
    subset = normalized_df[normalized_df['Dataset'] == dataset].set_index('Models').reindex(model_order)
    # 绘制MAE归一化值
    plt.bar([xi + idx*bar_width for xi in x], subset['MAE_归一化'], width=bar_width, label=f'{dataset} - MAE(归一化)')
    # 绘制运行时间归一化值(堆叠在MAE上方)
    plt.bar([xi + idx*bar_width for xi in x], subset['Runtime_归一化'], width=bar_width, bottom=subset['MAE_归一化'], label=f'{dataset} - 运行时间(归一化)')

# 优化图表样式
plt.xticks([xi + bar_width for xi in x], model_order, rotation=45, ha='right')
plt.ylabel('归一化值(0=最优,1=最差)')
plt.title('按综合排名排序的模型双指标对比')
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
plt.tight_layout()
plt.show()

三、保留运行时间的排名与频率统计

你之前的排名表丢失了运行时间信息,现在可以生成同时包含所有关键指标的排名汇总,还能计算Top模型的出现频率:

# 生成按综合排名排序的汇总表
ranked_summary = combined_df.groupby('Models').agg(
    平均MAE=('MAE', 'mean'),
    平均运行时间=('Runtime', lambda x: str(pd.to_timedelta(pd.to_timedelta(x).mean()))),
    平均综合排名=('Overall_Rank', 'mean')
).sort_values('平均综合排名').reset_index()

# 计算Top3模型的出现频率
top3_models = ranked_summary.head(3)['Models'].tolist()
top3_count = combined_df[combined_df['Models'].isin(top3_models)].groupby('Dataset').size().count()
top3_freq = (top3_count / len(dfs)) * 100

print("带运行时间的模型综合排名汇总:")
print(ranked_summary.round(2))
print(f"\nTop3模型({', '.join(top3_models)}) 在 {top3_count} 个数据集里表现最优,出现频率:{top3_freq:.2f}%")

这样就能完美复刻同时体现性能、效率和排名的可视化,还不会丢失任何关键数据啦~

备注:内容来源于stack exchange,提问作者Mario

火山引擎 最新活动