精确度与参数的完美融合:用可视化解读模型优化过程
背景
简洁明了地展示模型参数对性能的影响是一项挑战,为此,我们采用了可视化驱动的调优方法,通过直观的图表,帮助数据科学家和工程师更好地理解参数设置对模型精度的影响,在本项目中,我们主要探索随机森林模型的两个核心参数——n_estimators和max_depth,并通过热力图和等高线图直观地展示不同参数组合下的模型表现,读者可根据自己的项目进行更换模型、参数、评价指标等。
代码实现
数据导入分割
import pandas as pd
import numpy as np
df = pd.read_excel('模拟.xlsx')
from sklearn.model_selection import train_test_split
y = df['price']
X = df.drop(['price'], axis=1)
train_X, test_X, train_y, test_y = train_test_split(X, y, test_size=0.3, random_state=42)
df.head()
这里加载数据、准备特征和标签,并将数据集划分为训练集和测试集,这是一个回归任务,特征price为目标特征其余特征为自变量。
模型训练
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.model_selection import train_test_split
# 设置参数范围
n_estimators_range = np.arange(25, 201, 20)
max_depth_range = np.arange(3, 16, 1)
# 用于存储结果的列表
rmse_results = []
r2_results = []
# 进行嵌套循环,遍历参数组合
for n_estimators in n_estimators_range:
for max_depth in max_depth_range:
# 创建随机森林回归模型
model = RandomForestRegressor(
n_estimators=n_estimators,
max_depth=max_depth,
random_state=42
)
# 训练模型
model.fit(train_X, train_y)
# 进行预测
predictions = model.predict(test_X)
# 计算 RMSE 和 R^2
rmse = np.sqrt(mean_squared_error(test_y, predictions))
r2 = r2_score(test_y, predictions)
# 保存 RMSE 结果
rmse_results.append({
'n_estimators': n_estimators,
'max_depth': max_depth,
'RMSE': rmse
})
# 保存 R^2 结果
r2_results.append({
'n_estimators': n_estimators,
'max_depth': max_depth,
'R^2': r2
})
# 将结果转换为 DataFrame
rmse_df = pd.DataFrame(rmse_results)
r2_df = pd.DataFrame(r2_results)
通过遍历不同的 n_estimators 和 max_depth 参数组合,使用随机森林回归模型对数据进行训练和测试,计算每种参数组合下的模型预测误差(RMSE)和决定系数(R²),并将结果分别保存为各自的一个dataframe,方便接下来进行绘图展示模型参数和模型评价指标的相互影响变化。
模型可视化
模型参数对RMSE的影响
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
from matplotlib import rcParams
# 设置字体
rcParams['font.family'] = 'Times New Roman'
rcParams['font.size'] = 12 # 设置适合的字体大小
# 创建网格数据
pivot_table = rmse_df.pivot(index="max_depth", columns="n_estimators", values="RMSE")
# 定义自定义颜色映射(从蓝色到红色的渐变,并使其淡化)
cmap = LinearSegmentedColormap.from_list(
"custom_cmap",
[(180/255, 190/255, 240/255), (250/255, 150/255, 160/255)]
)
# 创建图表
plt.figure(figsize=(10, 8), dpi=1200)
# 使用 contourf 进行平滑填充等高线图
contour = plt.contourf(
pivot_table.columns.values, # n_estimators 值
pivot_table.index.values, # max_depth 值
pivot_table.values, # RMSE 值
levels=np.linspace(pivot_table.values.min(), pivot_table.values.max(), 10), # 等高线数量,越多越平滑
cmap=cmap # 自定义颜色映射
)
# 添加颜色条,并设置三位小数的格式
cbar = plt.colorbar(contour, format='%.3f')
cbar.set_label('RMSE')
# 设置 y 轴刻度从 4 开始,每 2 为一个间隔
plt.yticks(np.arange(4, pivot_table.index.max() + 1, 2))
# 设置图表标题和轴标签
plt.title("Hyperparameter Tuning - RMSE (Magnetite(Mt)%)")
plt.xlabel("n_estimators")
plt.ylabel("max_depth")
# 显示图表
plt.show()
通过创建等高线图(等高线的数量和模型的迭代次数都会影响可视化效果,选择合理的等高线数量可以使可视化图表更加精美和易于解读),我们可视化了不同 n_estimators 和 max_depth 参数组合下随机森林模型的 RMSE 值,以直观分析超参数对模型误差的影响。此处仅选取了随机森林中最重要的两个参数作为 X 轴和 Y 轴进行可视化。如果读者希望对更多参数进行可视化,建议可以引入降维方法,将多维参数降至 2D 或 3D 进行展示,尽管这样会失去对实际参数值的直接呈现。
当前的可视化展示了不同 n_estimators 和 max_depth 参数组合下的 RMSE 值,但并未明确标出在最优平均指标下的模型参数,接下来,我们将通过改进可视化,在图表中添加文本标注,明确指出 RMSE 最小值所对应的最优参数组合。
# 创建网格数据
pivot_table = rmse_df.pivot(index="max_depth", columns="n_estimators", values="RMSE")
# 定义自定义颜色映射(从蓝色到红色的渐变,并使其淡化)
cmap = LinearSegmentedColormap.from_list(
"custom_cmap",
[(180/255, 190/255, 240/255), (250/255, 150/255, 160/255)]
)
# 创建图表
plt.figure(figsize=(10, 8),dpi=1200)
# 使用 contourf 进行平滑填充等高线图
contour = plt.contourf(
pivot_table.columns.values, # n_estimators 值
pivot_table.index.values, # max_depth 值
pivot_table.values, # RMSE 值
levels=np.linspace(pivot_table.values.min(), pivot_table.values.max(), 10), # 等高线数量,越多越平滑
cmap=cmap # 自定义颜色映射
)
# 找到 RMSE 最小值的位置
min_rmse = pivot_table.values.min()
min_position = np.where(pivot_table.values == min_rmse)
min_x = pivot_table.columns[min_position[1][0]]
min_y = pivot_table.index[min_position[0][0]]
# 在最小值位置添加标注和箭头,向左移动标注
plt.annotate(
f'RMSE Min: {min_rmse:.3f}\n(n_estimators: {min_x}, max_depth: {min_y})',
xy=(min_x, min_y), xycoords='data',
xytext=(min_x - 30, min_y + 1), textcoords='data', # 向左移动
arrowprops=dict(facecolor='black', shrink=0.05, width=1, headwidth=6),
fontsize=12, ha='right' # 文本对齐方式改为靠右
)
# 添加颜色条,并设置三位小数的格式
cbar = plt.colorbar(contour, format='%.3f')
cbar.set_label('RMSE')
# 设置 y 轴刻度从 4 开始,每 2 为一个间隔
plt.yticks(np.arange(4, pivot_table.index.max() + 1, 2))
# 设置图表标题和轴标签
plt.title("Hyperparameter Tuning - RMSE (Magnetite(Mt)%)")
plt.xlabel("n_estimators")
plt.ylabel("max_depth")
# 显示图表
plt.show()
模型参数对 R²的影响
# 创建网格数据
pivot_table = r2_df.pivot(index="max_depth", columns="n_estimators", values="R^2")
# 定义自定义颜色映射(从蓝色到红色的渐变,并使其淡化)
cmap = LinearSegmentedColormap.from_list(
"custom_cmap",
[(180/255, 190/255, 240/255), (250/255, 150/255, 160/255)]
)
# 创建图表
plt.figure(figsize=(10, 8),dpi=1200)
# 使用 contourf 进行平滑填充等高线图
contour = plt.contourf(
pivot_table.columns.values, # n_estimators 值
pivot_table.index.values, # max_depth 值
pivot_table.values, # RMSE 值
levels=np.linspace(pivot_table.values.min(), pivot_table.values.max(), 10), # 等高线数量,越多越平滑
cmap=cmap # 自定义颜色映射
)
# 添加颜色条,并设置三位小数的格式
cbar = plt.colorbar(contour, format='%.3f')
cbar.set_label('R^2')
# 设置 y 轴刻度从 4 开始,每 2 为一个间隔
plt.yticks(np.arange(4, pivot_table.index.max() + 1, 2))
# 设置图表标题和轴标签
plt.title(r"Hyperparameter Tuning - $R^2$ (Magnetite(Mt)%)")
plt.xlabel("n_estimators")
plt.ylabel("max_depth")
# 显示图表
plt.show()
同理与RMSE的代码相似,但这里目的是可视化不同参数组合下的 值,而不是 RMSE。
# 创建网格数据
pivot_table = r2_df.pivot(index="max_depth", columns="n_estimators", values="R^2")
# 定义自定义颜色映射(从蓝色到红色的渐变,并使其淡化)
cmap = LinearSegmentedColormap.from_list(
"custom_cmap",
[(180/255, 190/255, 240/255), (250/255, 150/255, 160/255)]
)
# 创建图表
plt.figure(figsize=(10, 8), dpi=1200)
# 使用 contourf 进行平滑填充等高线图
contour = plt.contourf(
pivot_table.columns.values, # n_estimators 值
pivot_table.index.values, # max_depth 值
pivot_table.values, # R^2 值
levels=np.linspace(pivot_table.values.min(), pivot_table.values.max(), 10), # 等高线数量,越多越平滑
cmap=cmap # 自定义颜色映射
)
# 添加颜色条,并设置三位小数的格式
cbar = plt.colorbar(contour, format='%.3f')
cbar.set_label(r"$R^2$")
# 找到 R^2 最大值及对应的 max_depth 和 n_estimators
max_r2 = pivot_table.values.max()
max_r2_location = np.where(pivot_table.values == max_r2)
max_depth = pivot_table.index[max_r2_location[0][0]]
n_estimators = pivot_table.columns[max_r2_location[1][0]]
# 在图表上添加文本标注
plt.text(
x=n_estimators,
y=max_depth,
s=f"$R^2$: {max_r2:.3f}\nmax_depth: {max_depth}\nn_estimators: {n_estimators}",
color="black",
fontsize=10,
ha="right", # 水平对齐方式为右对齐
va="top", # 垂直对齐方式为顶对齐
bbox=dict(facecolor='white', alpha=0.6, edgecolor='none') # 添加背景框以提高可读性
)
# 设置 y 轴刻度从 4 开始,每 2 为一个间隔
plt.yticks(np.arange(4, pivot_table.index.max() + 1, 2))
# 设置图表标题和轴标签
plt.title(r"Hyperparameter Tuning - $R^2$ (Magnetite(Mt)%)")
plt.xlabel("n_estimators")
plt.ylabel("max_depth")
# 显示图表
plt.show()
结束语
通过本次分析,我们对随机森林模型中的两个关键参数 n_estimators 和 max_depth 在不同组合下对模型性能的影响进行了可视化探讨,主要聚焦于 和RMSE这两个评价指标,通过直观的可视化,我们不仅揭示了如何通过调整超参数来优化模型,还提供了一种有效的方法来识别最优的参数组合。
然而,模型性能的评估并不仅限于 和RMSE,读者们可以进一步扩展此方法,针对其它回归评价指标,如 MAE(平均绝对误差)或 MAPE(平均绝对百分比误差)等,进行类似的分析,同样,对于分类模型而言,此方法同样适用,可以针对 F1-score、召回率等指标进行参数调优的可视化展示,从而全面提升模型的准确性与可靠性。