本节介绍:一种机器学习回归预测结果的论文复刻图。原图围绕混凝剂投加量(Coagulant dosage, mg/L)展开,上排分别展示训练集和测试集中的实际值与预测值序列对比,下排分别展示训练集和测试集的 Actual value 与 Predicted Value 二维密度分布。
本文根据论文原图、已有复刻代码和完整 Notebook 流程进行整理。代码中采用模拟水质特征数据进行演示,目标变量为混凝剂投加量,候选模型包含 RandomForest、ExtraTrees 和 GradientBoosting。需要说明的是,模拟数据无任何现实实验意义,主要用于还原图形结构、建模流程和绘图逻辑,正式用于论文时应替换为真实水处理实验数据。
这张图属于典型的模型驱动型评估图,前置流程不是简单统计汇总,而是需要经历数据构造、特征整理、模型训练、预测结果输出和可视化复刻。
上排两个子图分别对应 Train 和 Test。横轴为样本编号,纵轴为混凝剂投加量,绿色实线表示 Actual,粉色虚线表示 Predicted。通过这两个面板,可以观察模型在样本序列上的跟随能力,尤其适合展示预测值是否能贴近阶梯状或离散档位变化。
下排两个子图分别对应训练集和测试集的实际值-预测值二维密度分布。横轴为 Actual value,纵轴为 Predicted Value,颜色表示局部样本密度。密度越高,说明该区域聚集的样本越多。若模型预测效果较好,样本密度通常会集中在 y=x 附近。
这类图适合放在论文的模型性能评估、预测结果验证或机器学习模型应用结果部分。相比只给 R2、RMSE、MAE 表格,它能同时展示序列拟合情况和整体预测分布结构。
完整 Notebook 代码被整理为 5 个 Cell。第 1 个 Cell 固定全局绘图设置,包括字体、线宽、刻度方向、保存分辨率等,保证后续图形风格统一。
import matplotlib.pyplot as pltimport pandas as pdimport numpy as npimport seaborn as snsfrom sklearn.ensemble import RandomForestRegressor, ExtraTreesRegressor, GradientBoostingRegressorfrom sklearn.model_selection import GridSearchCVfrom sklearn.metrics import r2_score, mean_absolute_error, mean_squared_error
第 2 个 Cell 负责识别任务类型和全局参数。该图被判断为模型驱动型回归评估图,因此需要补全模型训练流程。代码中设置训练集样本约 1080,测试集样本约 270,并定义原水和处理后水质特征,例如 NTU-RW、pH-RW、EC-RW、CODMn-RW、EC-TW、CODMn-TW 和 WTR 等。
DOSAGE_LEVELS = np.array([8, 10, 12, 15, 20, 25, 30, 35], dtype=float)dosage = np.empty(N_TOTAL)dosage[0] = rng.choice(DOSAGE_LEVELS, p=state_prob)for i in range(1, N_TOTAL): if rng.random() < 0.64: dosage[i] = dosage[i - 1] else: dosage[i] = rng.choice(DOSAGE_LEVELS, p=state_prob)
这里不是完全随机生成目标值,而是让相邻样本有一定概率保持同一投加档位,从而形成类似原图中的连续阶梯片段。随后再加入少量高投加量样本,使 30-35 mg/L 区间出现稀疏峰值。
然后根据投加量构造水质特征。
latent_load = (dosage - dosage.min()) / (dosage.max() - dosage.min())data = pd.DataFrame({ "NTU_RW": 18 + 65 * latent_load + noise(5.5), "pH_RW": 7.6 - 0.55 * latent_load + noise(0.12), "EC_RW": 260 + 430 * latent_load + noise(35), "CODMn_RW": 2.5 + 10.5 * latent_load + noise(0.75), "WTR": 0.20 + 1.8 * latent_load + noise(0.16), "Coagulant_dosage_mg_L": dosage})
这一步的核心是让特征和目标变量之间存在合理关联,而不是简单拼接随机数。生成完成后,代码默认保存 `模拟数据-YYYYMMDD.xlsx`,并绘制 1 张模拟数据辅助图,用于检查投加量分布和关键水质特征关系。
第 4 个 Cell 进入建模阶段。代码按照原图口径,将前 1080 个样本作为训练集,后 270 个样本作为测试集。
train_df = data.iloc[:N_TRAIN].copy()test_df = data.iloc[N_TRAIN:].copy()X_train = train_df[FEATURE_NAMES]y_train = train_df[TARGET_NAME]X_test = test_df[FEATURE_NAMES]y_test = test_df[TARGET_NAME]
candidate_models["RandomForest"] = ( RandomForestRegressor(random_state=RANDOM_SEED, n_jobs=-1), {"n_estimators": [120, 200], "max_depth": [6, 10, None], "min_samples_leaf": [1, 3]})
代码会比较多个候选模型的交叉验证 R2,选择最优模型进行最终预测。预测结果进一步整理为训练集和测试集的 Actual、Predicted、Residual,用于后续主图绘制。
训练完成后,Notebook 会额外输出两张模型训练辅助图:一张真实值 vs 预测值散点图,一张特征重要性条形图。前者用于观察整体预测贴合程度,后者用于了解模型主要依赖哪些水质变量。
fig, axes = plt.subplots(2, 2, figsize=(13, 9.8))ax1, ax2, ax3, ax4 = axes.flatten()
ax1.plot(train_results["Sample"], train_results["Actual"], color=COLOR_ACTUAL, linewidth=CUSTOM_LINE_WIDTH, label="Actual")ax1.plot(train_results["Sample"], train_results["Predicted"], color=COLOR_PREDICTED, linewidth=CUSTOM_LINE_WIDTH, linestyle="--", alpha=CUSTOM_LINE_ALPHA, label="Predicted")
下排使用 hist2d 绘制实际值与预测值的二维密度图。
h1 = ax3.hist2d( train_results["Actual"], train_results["Predicted"], bins=CUSTOM_DENSITY_BINS, range=[[2, 42], [2, 42]], cmap=CMAP_DENSITY, density=True, cmin=0)
这类密度图适合样本点较多或存在离散档位的预测任务。与普通散点图相比,它能更清楚地显示样本聚集区域,避免大量点重叠后难以辨认。
第一,混凝剂投加量具有明显工程背景,真实建模时应检查单位、药剂类型、采样频率和实验条件是否一致。
第二,投加量预测往往呈现离散档位或阶梯状变化,评价模型时不应只看平均误差,还应观察高投加量峰值是否被低估。
第三,二维密度图适合展示大量预测点的聚集情况,但色条范围会受样本量、分箱数量和密度归一化方式影响,跨图比较时需要保持参数一致。
第四,特征重要性只能说明模型在当前模拟或真实数据中的使用偏好,不能直接解释为严格因果关系。
👇关注公众号【嗡嗡的Python日常】
✅ 支持代码定制|承接各类定制化科研绘图|质量放心
📌 关于源码:本文核心代码为原创定制,默认不免费公开。
✅ 获取源码方式:
1、直接添加号主微信,付费购买完整源码 + 数据
2、全部完整合集158元,后续将会持续更新,决定购买请联系作者,仅分享代码文件及模拟数据,不提供答疑服务,购买后不退不换!!!
👉请直接添加号主微信联系☕️:Wjtaiztt0406