☰
模型还能怎么优化?用华为云码道诊断并改进机器学习回归项目
2026/10/1 10:29:46 网站建设 项目流程

ml-regression-demo:基于 Python 和 scikit-learn 的机器学习回归预测实验,完成数据读取、数据处理、训练集划分、线性回归模型训练、MAE/MSE/RMSE/R² 模型评估以及预测结果可视化,用于体验华为云码道辅助完成完整机器学习实验流程。 - AtomGit

深圳技术大学 - 开源代码托管,代码协作 - AtomGit

模型还能怎么优化?用华为云码道诊断并改进机器学习回归项目

前言

在上一篇实践中,我使用华为云码道辅助完成了一个完整的 Python 机器学习回归预测实验。

项目使用 scikit-learn 自带的 Diabetes 数据集,以 LinearRegression 作为回归模型,完成了数据读取、数据检查、训练集与测试集划分、模型训练、模型预测以及结果评价。

整个数据集共有442 条样本、10 个特征。按照 8:2 的比例进行数据划分后,训练集包含 353 条样本,测试集包含 89 条样本。

程序运行得到的模型评价结果如下:

MAE(平均绝对误差):42.7941 MSE(均方误差):2900.1936 RMSE(均方根误差):53.8534 R²(决定系数):0.4526

这说明项目已经能够完成一个完整的机器学习回归预测流程,但模型仍然有进一步分析的空间。

相比从零重新建立一个机器学习项目,这一次我更想解决另一个实际开发中非常常见的问题:

当代码已经能够正常运行,但模型效果还有提升空间时,应该从哪里开始排查?

因此,我继续使用原来的ml-regression-demo项目,通过华为云码道读取已有代码,在现有程序基础上完成模型诊断、残差分析、模型对比和交叉验证。

整个过程由“生成一个机器学习程序”进一步进入到:

已有项目 ↓ 读取现有代码 ↓ 复现模型结果 ↓ 分析预测误差 ↓ 比较不同模型 ↓ 增加交叉验证 ↓ 综合评价模型效果

华为云码道支持结合文件、文件夹、终端输出等上下文理解当前项目,并围绕已有代码继续完成代码分析、生成和问题排查,因此除了从零开发项目,也适合继续维护和迭代已有工程。


一、从原始模型结果开始

本次实验并没有立即删除之前的 LinearRegression,而是首先将它作为后续模型对比的基线。

原来的模型训练代码很简单:

from sklearn.linear_model import LinearRegressionmodel = LinearRegression()model.fit(X_train, y_train)y_pred = model.predict(X_test)

数据仍然采用固定的数据划分方式:

X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42)

使用固定的random_state=42,可以保证后续增加其他模型时仍然使用相同的训练集和测试集。

原项目实际运行得到:

训练集样本数量:353 测试集样本数量:89 MAE:42.7941 MSE:2900.1936 RMSE:53.8534 R²:0.4526

其中:

MAE表示预测值与真实值之间平均相差多少。

MSE会对较大的预测误差给予更高的惩罚。

RMSE与目标变量保持相同量纲,因此更加直观。

R²用于反映模型能够解释目标变量变化的程度。

当前得到的R²=0.4526,说明线性回归已经能够学习数据中的一部分规律,但仍然存在一部分变化没有被当前模型充分解释。

这也为后续的模型诊断提供了一个明确的基线。

图1 LinearRegression 基线模型运行结果


二、先检查流程,而不是立即更换模型

模型效果没有达到预期,并不一定意味着模型本身存在问题。

很多机器学习项目的异常结果,实际上可能来自数据处理、数据划分或者评价方式。

因此,这一次我首先让华为云码道直接读取现有的ml_regression.py,检查整个机器学习流程。

主要包括:

特征和目标变量是否正确划分 训练集与测试集是否正确划分 数据是否存在缺失值 是否存在数据泄漏 评价指标是否正确 模型训练和预测逻辑是否完整

原项目的数据检查结果显示:

是否存在缺失值:否

并且 10 个输入特征以及目标变量的缺失值数量均为 0。

训练集与测试集的维度也符合预期:

训练集特征维度:(353, 10) 测试集特征维度:(89, 10)

因此,本次实验中的基础数据处理流程没有出现明显问题。

这意味着当前模型效果并不是由一个简单的代码错误造成的,而需要进一步从模型本身和预测误差入手分析。

这也是使用 AI 编程工具处理已有项目时很重要的一点:

并不是每次都需要重新生成代码。

华为云码道能够通过文件、文件夹、终端、Problems 等上下文了解已有项目,使智能体能够围绕当前代码进行更有针对性的分析和处理。

图2 使用华为云码道读取并分析已有机器学习项目


三、通过残差进一步观察模型

确认代码流程没有明显问题以后,下一步就是观察模型到底在哪些样本上预测得不够准确。

这里可以引入一个很常见的概念:

残差。

残差的计算方式非常简单:

residuals = y_test - y_pred

也就是:

残差 = 真实值 - 预测值

如果某一个样本:

真实值 = 200 预测值 = 180

那么残差就是:

20

如果预测结果与真实值完全相同,那么残差就是 0。

因此,将预测值与残差画成散点图,可以比较直观地观察模型的预测误差。

代码如下:

residuals = y_test - y_predplt.figure(figsize=(8, 6))plt.scatter( y_pred, residuals, alpha=0.7)plt.axhline( y=0, linestyle="--")plt.xlabel("Predicted Value")plt.ylabel("Residual")plt.title("Residual Plot")plt.grid(True)plt.tight_layout()plt.savefig( "residual_plot.png", dpi=300)plt.show()

在理想情况下,大部分点应该比较均匀地分布在:

y = 0

附近。

如果残差出现明显的规律、趋势或者大量偏离 0 的点,就说明当前模型仍然没有充分描述数据中的某些关系。

相比只看R²=0.4526这一个数字,残差图能够更加直观地告诉我们:

模型究竟是怎样产生误差的。

图3 LinearRegression 模型残差分布


四、保留线性回归作为基线

完成残差分析以后,我没有直接删除原来的模型。

LinearRegression 仍然作为整个实验中的基线模型。

这是因为模型优化需要一个可以进行比较的参照。

如果直接不断替换模型,很容易出现一个问题:

模型A ↓ 换成模型B ↓ 换成模型C

最后虽然得到了新的结果,却很难清楚判断每一次修改到底带来了多少变化。

所以本次实验保留三个模型:

LinearRegression Ridge GradientBoostingRegressor

并让它们使用完全相同的数据进行训练和测试。


五、加入 Ridge 回归

第二个模型使用 Ridge:

from sklearn.linear_model import Ridgeridge_model = Ridge( alpha=0.1)

Ridge 与普通线性回归非常接近。

不同的是,Ridge 在训练过程中增加了 L2 正则化,用于对模型参数进行一定程度的约束。

因此,这一步主要是观察:

在保持线性模型结构的情况下,加入正则化能否改善模型效果?

在相同测试集上,Ridge 得到:

MAE:42.9969 MSE:2856.4869 RMSE:53.4461 R²:0.4609

与原来的 LinearRegression 相比:

LinearRegression R²:0.4526 Ridge R²:0.4609

Ridge 的 R² 出现了小幅提高,同时 RMSE 从:

53.8534

下降到:

53.4461

说明正则化对当前模型带来了一定变化,但整体提升幅度并不大。

这也说明:

单纯在线性模型上增加正则化,并不能完全解决当前数据中的建模问题。


六、加入 Gradient Boosting 回归模型

接下来增加第三个模型:

from sklearn.ensemble import GradientBoostingRegressorgbr_model = GradientBoostingRegressor( random_state=42, n_estimators=100, learning_rate=0.03, max_depth=2, min_samples_leaf=5, loss="huber")

与 LinearRegression 和 Ridge 不同,Gradient Boosting 可以学习更加复杂的非线性关系。

这使得它能够作为一个很好的对照,用来验证:

当前数据中是否存在单纯线性模型难以充分表达的关系?

在相同训练集与测试集条件下,本次运行得到:

MAE:42.3410 MSE:2721.6434 RMSE:52.1694 R²:0.4863

三个模型的测试结果可以整理为:

模型MAERMSER²
LinearRegression42.794153.85340.4526
Ridge42.996953.44610.4609
GradientBoostingRegressor42.341052.16940.4863

从测试集结果来看,GradientBoostingRegressor 的:

  • MAE 最低;
  • RMSE 最低;
  • R² 最高。

也就是说,在当前这一次固定数据划分下,Gradient Boosting 对数据的拟合表现优于两个线性模型。

但机器学习模型评价到这里还没有结束。


七、为什么还要加入5折交叉验证?

如果只看上面的结果,很容易直接得出:

GradientBoostingRegressor 最好

但这样的判断其实还不够完整。

因为目前的所有结果都来自同一次训练集和测试集划分。

如果重新随机划分数据,评价结果就可能发生变化。

因此,还需要使用交叉验证观察模型在不同数据划分下的稳定表现。

本次采用:

from sklearn.model_selection import KFoldkf = KFold( n_splits=5, shuffle=True, random_state=42)

5折交叉验证会将数据划分为5个部分。

每一次使用其中4份训练,另外1份验证。

可以简单理解为:

第1轮: 1 2 3 4 训练 5 验证 第2轮: 1 2 3 5 训练 4 验证 第3轮: 1 2 4 5 训练 3 验证 …… 共进行5轮

最后再取5次评价结果的平均值。

代码可以使用:

from sklearn.model_selection import cross_val_scorecv_scores = cross_val_score( model, X, y, cv=kf, scoring="r2")cv_mean = cv_scores.mean()

这样可以减少一次随机划分所带来的偶然性。


八、三个模型的交叉验证结果

在相同的 5 折交叉验证设置下,本次实验得到:

模型测试集 R²5折交叉验证平均 R²
LinearRegression0.45260.4785
Ridge0.46090.4791
GradientBoostingRegressor0.48630.4470

这里出现了一个很有意思的结果。

如果只观察当前测试集:

GradientBoostingRegressor:0.4863

明显高于:

LinearRegression:0.4526 Ridge:0.4609

但是在5折交叉验证中:

LinearRegression:0.4785 Ridge:0.4791 GradientBoostingRegressor:0.4470

Gradient Boosting 的平均 R² 反而低于两个线性模型。

这正好体现了为什么不能只根据一次测试结果判断模型。


九、测试集更高,不代表模型一定更稳定

这一组结果非常适合作为机器学习模型评价的一个例子。

GradientBoostingRegressor 在固定测试集上取得了最高的:

R² = 0.4863

同时 MAE 和 RMSE 也更低。

说明它在当前这组测试数据上确实取得了更好的预测表现。

但5折交叉验证平均 R² 为:

0.4470

没有超过两个线性模型。

这意味着它的优势并没有在不同数据划分中始终保持。

因此,对于一个模型,不能只问:

它这一次的 R² 是多少?

还应该继续问:

换一批训练数据和验证数据以后,它的效果是否依然稳定?

这也是交叉验证的重要价值。


十、三个模型应该怎样理解?

经过这次对比,可以更加清楚地看到三个模型各自的特点。

LinearRegression

测试集:

MAE:42.7941 RMSE:53.8534 R²:0.4526

5折交叉验证:

平均 R²:0.4785

它的结构最简单,也可以作为整个实验很好的基线。


Ridge

测试集:

MAE:42.9969 RMSE:53.4461 R²:0.4609

5折交叉验证:

平均 R²:0.4791

相比普通线性回归,Ridge 的测试集 R² 和 RMSE有所改善。

交叉验证平均 R² 也略高。

整体变化并不大,说明正则化虽然带来了一定效果,但当前问题并不只是简单的参数约束问题。


GradientBoostingRegressor

测试集:

MAE:42.3410 RMSE:52.1694 R²:0.4863

5折交叉验证:

平均 R²:0.4470

它在当前测试集上的表现最好。

但交叉验证平均结果低于两个线性模型。

因此,它证明了更加复杂的模型能够在部分数据划分中捕捉更多关系,同时也说明:

更加复杂并不等于在所有数据划分下都更稳定。


十一、将模型结果可视化

只观察终端中的数字仍然不够直观。

因此,我让华为云码道继续生成三个模型的测试集 R² 对比图。

核心代码如下:

plt.figure(figsize=(8, 6))bars = plt.bar( result_df["模型"], result_df["R²"])plt.xlabel("Model")plt.ylabel("R²")plt.title( "Model R2 Comparison")plt.grid( axis="y", alpha=0.3)for bar, value in zip( bars, result_df["R²"]): plt.text( bar.get_x() + bar.get_width() / 2, bar.get_height(), f"{value:.4f}", ha="center", va="bottom" )plt.tight_layout()plt.savefig( "model_comparison.png", dpi=300

通过柱状图,可以直接看到当前测试集上的模型差异:

LinearRegression 0.4526 Ridge 0.4609 GradientBoosting 0.4863

相比单纯阅读表格,可视化可以更加直观地呈现模型之间的变化。

图4 三种回归模型测试集 R² 对比


十二、从“优化参数”转向“诊断模型”

完成这次实验后,我发现“优化机器学习模型”并不应该理解为:

换模型 ↓ 调参数 ↓ 看R²有没有提高

更完整的流程应该是:

得到基线模型 ↓ 检查数据处理 ↓ 检查模型训练流程 ↓ 观察预测误差 ↓ 增加候选模型 ↓ 使用相同数据比较 ↓ 加入交叉验证 ↓ 综合分析结果

例如这次实验,如果只看一次测试集:

GradientBoostingRegressor

表现最好。

但加入5折交叉验证以后,就可以看到:

Ridge LinearRegression

在不同数据划分下反而表现得更加稳定。

这说明模型评价不能只追求一个更高的数字。


十三、华为云码道在已有项目中能做什么?

三号实验主要体验的是:

从自然语言需求开始,生成一个可以运行的机器学习实验。

而这一次重点已经发生变化。

项目本身已经存在,代码也已经可以正常运行。

华为云码道需要完成的是:

读取已有项目 ↓ 理解现有代码 ↓ 结合终端结果分析问题 ↓ 继续修改原有文件 ↓ 增加残差分析 ↓ 增加新的机器学习模型 ↓ 加入交叉验证 ↓ 再次运行并分析结果

这更接近日常开发中维护已有代码的过程。

华为云官方目前将码道定位为能够理解项目上下文和开发意图,并完成需求分析、代码编写、调试优化和测试验证等研发任务的代码智能体;码道IDE还支持项目代码索引以及文件、文件夹、Git、Terminal、Problems 等上下文信息。

对于机器学习实验来说,这意味着开发者不需要每次出现问题都重新解释整个项目。

可以把现有 Python 文件和运行结果作为上下文,让智能体围绕当前工程继续分析。


十四、AI生成代码之后,仍然需要理解结果

AI可以快速帮助我们补充:

模型代码 评价代码 交叉验证代码 可视化代码

但机器学习实验真正重要的部分并不只是“程序能够运行”。

例如本次结果中:

GradientBoosting测试集R²最高

如果只看到这里,很容易认为模型优化已经成功。

但继续加入交叉验证后,会发现:

GradientBoosting平均R²反而更低

这时候就需要自己理解:

  • 测试集结果代表什么;
  • 交叉验证代表什么;
  • 模型复杂度意味着什么;
  • 一次较好的结果是否具有稳定性。

因此,AI编程工具更适合承担:

代码实现和开发辅助。

而开发者仍然需要负责:

理解实验逻辑和解释模型结果。


十五、总结

这次实验继续使用上一篇已经完成的ml-regression-demo项目,没有重新创建新的机器学习工程。

实验从原始 LinearRegression 的:

MAE:42.7941 MSE:2900.1936 RMSE:53.8534 R²:0.4526

开始。

在确认数据处理和模型训练流程正常以后,进一步增加了:

残差分析 Ridge回归 GradientBoostingRegressor 5折交叉验证 模型结果可视化

最终三个模型得到:

模型MAERMSE测试集 R²5折CV平均 R²
LinearRegression42.794153.85340.45260.4785
Ridge42.996953.44610.46090.4791
GradientBoostingRegressor42.341052.16940.48630.4470

这组结果也让我对机器学习模型优化有了更直观的认识:

模型优化不是不断寻找更复杂的算法,而是通过数据检查、误差分析、模型对比和交叉验证,确认模型是否真的取得了稳定改善。

这次华为云码道的作用也不再只是生成一段新的 Python 代码,而是围绕一个已经存在的机器学习项目继续完成代码理解、功能增加、模型诊断和结果分析。

对于学习机器学习或者日常开发中的小型数据分析项目来说,这种基于现有代码继续协作的方式,能够明显减少重复查找 API、编写实验框架和整理评价代码的时间,让开发者把更多精力放在真正重要的模型分析上。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询