所有文章 > AI驱动 > 用图表说话:如何有效呈现回归预测模型结果

用图表说话:如何有效呈现回归预测模型结果

背景

在现代数据科学领域中,构建高效的机器学习模型固然重要,但对模型结果的可视化也是至关重要的一环,通过直观的图形和图表,我们不仅能更清晰地理解模型的表现,还能更好地传达数据背后的故事,在本文中,我们将借鉴一篇学术研究中的可视化方法,重点介绍如何使用XGBoost回归模型对数据进行预测,并通过精美的图表展现模型的训练和测试结果(针对于回归预测模型),这些可视化不仅有助于评估模型的准确性,还能为进一步的模型优化提供洞察力。

在接下来的代码实现中,我们将复现并细化类似的可视化效果,希望能为大家在实践中提供参考,通过这种方式,我们能够更好地理解模型的表现,并为数据分析与模型调优提供有力支持

代码实现

模型构建

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split

df = pd.read_excel('数据.xlsx')

# 划分特征和目标变量
X = df.drop(['price'], axis=1)
y = df['price']

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)


import xgboost as xgb
from sklearn.model_selection import GridSearchCV

# XGBoost模型参数
params_xgb = {
'learning_rate': 0.02, # 学习率,控制每一步的步长,用于防止过拟合。典型值范围:0.01 - 0.1
'booster': 'gbtree', # 提升方法,这里使用梯度提升树(Gradient Boosting Tree)
'objective': 'reg:squarederror', # 损失函数,这里使用平方误差
'max_leaves': 127, # 每棵树的叶子节点数量,控制模型复杂度。较大值可以提高模型复杂度但可能导致过拟合
'verbosity': 1, # 控制 XGBoost 输出信息的详细程度,0表示无输出,1表示输出进度信息
'seed': 42, # 随机种子,用于重现模型的结果
'nthread': -1, # 并行运算的线程数量,-1表示使用所有可用的CPU核心
'colsample_bytree': 0.6, # 每棵树随机选择的特征比例,用于增加模型的泛化能力
'subsample': 0.7 # 每次迭代时随机选择的样本比例,用于增加模型的泛化能力
}

model_xgb = xgb.XGBRegressor(**params_xgb)

# 定义参数网格,用于网格搜索
param_grid = {
'n_estimators': [100, 200, 300, 400, 500], # 树的数量,控制模型的复杂度
'max_depth': [3, 4, 5, 6, 7], # 树的最大深度,控制模型的复杂度,防止过拟合
'min_child_weight': [1, 2, 3, 4, 5], # 节点最小权重,值越大,算法越保守,用于控制过拟合
}

grid_search = GridSearchCV(
estimator=model_xgb,
param_grid=param_grid,
scoring='neg_root_mean_squared_error',
cv=5,
n_jobs=-1,
verbose=1
)


# 训练模型
grid_search.fit(X_train, y_train)
best_model = grid_search.best_estimator_

使用网格搜索优化了XGBoost回归模型的参数,并在训练集上训练了最佳模型,用于预测目标变量。

模型评价指标

from sklearn import metrics

# 预测
y_pred_train = best_model.predict(X_train)
y_pred_test = best_model.predict(X_test)

y_pred_train_list = y_pred_train.tolist()
y_pred_test_list = y_pred_test.tolist()

# 计算训练集的指标
mse_train = metrics.mean_squared_error(y_train, y_pred_train_list)
rmse_train = np.sqrt(mse_train)
mae_train = metrics.mean_absolute_error(y_train, y_pred_train_list)
r2_train = metrics.r2_score(y_train, y_pred_train_list)

# 计算测试集的指标
mse_test = metrics.mean_squared_error(y_test, y_pred_test_list)
rmse_test = np.sqrt(mse_test)
mae_test = metrics.mean_absolute_error(y_test, y_pred_test_list)
r2_test = metrics.r2_score(y_test, y_pred_test_list)

print("训练集评价指标:")
print("均方误差 (MSE):", mse_train)
print("均方根误差 (RMSE):", rmse_train)
print("平均绝对误差 (MAE):", mae_train)
print("拟合优度 (R-squared):", r2_train)

print("\n测试集评价指标:")
print("均方误差 (MSE):", mse_test)
print("均方根误差 (RMSE):", rmse_test)
print("平均绝对误差 (MAE):", mae_test)
print("拟合优度 (R-squared):", r2_test)

量化和比较模型在训练数据和测试数据上的预测效果,通过一系列常用的回归指标来衡量模型的性能。

回归结果可视化

import seaborn as sns
from sklearn import metrics

# 创建一个包含训练集和测试集真实值与预测值的数据框
data_train = pd.DataFrame({
'True': y_train,
'Predicted': y_pred_train,
'Data Set': 'Train'
})

data_test = pd.DataFrame({
'True': y_test,
'Predicted': y_pred_test,
'Data Set': 'Test'
})

data = pd.concat([data_train, data_test])

# 自定义调色板
palette = {'Train': '#b4d4e1', 'Test': '#f4ba8a'}

# 创建 JointGrid 对象
plt.figure(figsize=(8, 6), dpi=1200)
g = sns.JointGrid(data=data, x="True", y="Predicted", hue="Data Set", height=10, palette=palette)

# 绘制中心的散点图
g.plot_joint(sns.scatterplot, alpha=0.5)
# 添加训练集的回归线
sns.regplot(data=data_train, x="True", y="Predicted", scatter=False, ax=g.ax_joint, color='#b4d4e1', label='Train Regression Line')
# 添加测试集的回归线
sns.regplot(data=data_test, x="True", y="Predicted", scatter=False, ax=g.ax_joint, color='#f4ba8a', label='Test Regression Line')
# 添加边缘的柱状图
g.plot_marginals(sns.histplot, kde=False, element='bars', multiple='stack', alpha=0.5)

# 添加拟合优度文本在右下角
ax = g.ax_joint
ax.text(0.95, 0.1, f'Train $R^2$ = {r2_train:.3f}', transform=ax.transAxes, fontsize=12,
verticalalignment='bottom', horizontalalignment='right', bbox=dict(boxstyle="round,pad=0.3", edgecolor="black", facecolor="white"))
ax.text(0.95, 0.05, f'Test $R^2$ = {r2_test:.3f}', transform=ax.transAxes, fontsize=12,
verticalalignment='bottom', horizontalalignment='right', bbox=dict(boxstyle="round,pad=0.3", edgecolor="black", facecolor="white"))
# 在左上角添加模型名称文本
ax.text(0.75, 0.99, 'Model = xgboost', transform=ax.transAxes, fontsize=12,
verticalalignment='top', horizontalalignment='left', bbox=dict(boxstyle="round,pad=0.3", edgecolor="black", facecolor="white"))

# 添加中心线
ax.plot([data['True'].min(), data['True'].max()], [data['True'].min(), data['True'].max()], c="black", alpha=0.5, linestyle='--', label='x=y')
ax.legend()
plt.savefig("TrueFalse.pdf", format='pdf', bbox_inches='tight')

创建一个联合网格图(JointGrid),其中包含散点图、回归线以及直方图,用于直观比较真实值和预测值的关系,读者能直观地看到模型在训练集和测试集上的表现,并通过 值和对角线判断模型的拟合效果,如果要关闭y轴柱状图只需要在添加边缘的柱状图 下面添加以下代码。

# 关闭 y 轴的边缘柱状图
g.ax_marg_y.set_visible(False)

文章转自微信公众号@Python机器学习AI