目录
[2.1 缺失值填充的必要性](#2.1 缺失值填充的必要性)
[2.2 平均值填充的适用场景](#2.2 平均值填充的适用场景)
[2.3 平均值填充的落地](#2.3 平均值填充的落地)
[三、模型训练:XGBoost 与 AdaBoost 的实现细节](#三、模型训练:XGBoost 与 AdaBoost 的实现细节)
[3.1 通用训练框架](#3.1 通用训练框架)
[3.2 XGBoost 的训练实现](#3.2 XGBoost 的训练实现)
[3.3 AdaBoost 的训练实现](#3.3 AdaBoost 的训练实现)
[四、结果分析:XGBoost 与 AdaBoost 在平均值填充数据集上的表现](#四、结果分析:XGBoost 与 AdaBoost 在平均值填充数据集上的表现)
[4.1 核心评估指标](#4.1 核心评估指标)
[4.2 数值结果对比](#4.2 数值结果对比)
[4.3 结果解读](#4.3 结果解读)
[五、延伸思考:从 "单填充 + 单模型" 到 "全局最优"](#五、延伸思考:从 “单填充 + 单模型” 到 “全局最优”)
前言
在机器学习项目中,数据清洗 是模型效果的基石,而模型选型与调优 则是提升任务性能的核心环节。本文以矿物分类为背景,围绕 "缺失值填充(平均值填充)→模型训练(XGBoost/AdaBoost)→结果分析" 的完整流程展开,结合实际代码与训练结果,拆解多分类任务中模型训练的关键步骤,同时对比 XGBoost 与 AdaBoost 在平均值填充数据集上的表现,我们以及在上文矿物成分数据智能分类实战(一)中对数据进行了清洗。
一、项目整体流程概述
本项目针对含缺失值的多分类数据集,搭建了完整的建模流程:
- 数据清洗:针对原始数据集的缺失值问题,设计 6种不同的缺失值填充策略(如删除空缺值、平均值、中位数、众数、线性回归填充、随机森林填充),对训练集和测试集分别处理,最终生成 12 个填充后的数据文件(6 种填充方式 × 训练 / 测试集);
- 模型训练:基于每种填充后的数据集,训练 6 种经典机器学习模型(LR、RF、SVM、XGBoost、GNB、AdaBoost),通过网格搜索优化超参数,保存最优模型并记录评估指标;和两种卷积神经网络模型(pytorch框架和CNN卷积神经网络)。
- 结果对比:横向对比同一种填充方式下不同模型的表现,纵向对比同一模型在不同填充方式下的效果,最终筛选出 "最优填充方式 + 最优模型"。
本文聚焦平均值填充后的数据集,以 XGBoost 和 AdaBoost 为例,详解模型训练过程与结果分析。
二、数据清洗:平均值填充的核心逻辑
2.1 缺失值填充的必要性
原始数据集存在特征缺失值,若直接用于模型训练,会导致算法报错(如 XGBoost 默认不支持缺失值,虽部分算法可兼容,但缺失值会破坏数据分布),同时降低模型的泛化能力。因此,缺失值填充是数据清洗的核心步骤。
2.2 平均值填充的适用场景
平均值填充是最基础的数值型缺失值填充方法,适用于:
- 特征分布近似正态分布,无极端异常值(避免平均值被异常值拉偏);
- 缺失值占比低(一般<20%),填充后不会显著改变特征的原始分布。
2.3 平均值填充的落地
本项目中,我们对训练集和测试集的数值型特征分别计算平均值,填充对应特征的缺失值,最终生成:
训练数据集[平均值填充].xlsx:训练集特征缺失值以该特征的平均值填充;测试数据集[平均值填充].xlsx:测试集特征缺失值以训练集对应特征的平均值填充(避免数据泄露)。
填充后的数据集作为后续模型训练的输入(对应代码中x_train/x_test、y_train/y_test的读取来源)。
三、模型训练:XGBoost 与 AdaBoost 的实现细节
基于平均值填充后的数据集,我们采用 "网格搜索 + 交叉验证" 的方式优化 XGBoost 和 AdaBoost 的超参数,确保模型性能最优。以下是核心实现逻辑(基于项目代码):
3.1 通用训练框架
无论 XGBoost 还是 AdaBoost,均遵循统一的训练流程:
- 读取填充后的训练集 / 测试集,拆分特征(x)和标签(y);
- 定义超参数网格,通过
GridSearchCV进行 5 折交叉验证,筛选最优参数; - 保存最优模型(
joblib),避免重复训练; - 用最优模型预测测试集,计算召回率(Recall,多分类任务重点关注)和准确率(Accuracy);
- 将评估指标保存为 JSON 文件(带时间戳),便于后续对比分析。
读取文件
python
import pandas as pd
from sklearn import metrics
from sklearn.model_selection import GridSearchCV
import joblib # 保存模型专用
import json
import os
from datetime import datetime
train_data = pd.read_excel(r'.//temp_data//训练数据集[平均值填充].xlsx')
x_train = train_data.iloc[:,1:]
y_train = train_data.iloc[:,0]
test_data = pd.read_excel(r'.//temp_data//测试数据集[平均值填充].xlsx')
x_test = test_data.iloc[:,1:]
y_test = test_data.iloc[:,0]
result_data = {} #用来保存后面算法的结果
保存JSON文件代码
python
# 创建保存JSON结果的目录(如果不存在)
json_save_dir = "./model_results"
if not os.path.exists(json_save_dir):
os.makedirs(json_save_dir)
# 定义保存结果为JSON的函数
def save_result_to_json(result_data, filename=None):
"""
将模型训练结果保存为JSON文件(带时间戳)
:param result_data: 要保存的结果字典
:param filename: 保存的文件名(可选)
"""
if filename is None:
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"model_results_{timestamp}.json"
save_path = os.path.join(json_save_dir, filename)
with open(save_path, 'w', encoding='utf-8') as f:
json.dump(result_data, f, ensure_ascii=False, indent=4)
print(f"结果已保存至: {save_path}")
3.2 XGBoost 的训练实现
XGBoost 是基于梯度提升树的集成算法,在分类任务中表现优异,核心超参数需重点调优:
python
from xgboost import XGBClassifier
# 1. 定义超参数网格
param_grid = {
'max_depth': [3, 5, 7], # 树的最大深度(控制过拟合)
'learning_rate': [0.05, 0.1], # 学习率(步长,越小越稳定)
'n_estimators': [100, 200], # 弱学习器数量
'subsample': [0.6, 0.8], # 训练样本采样率(防止过拟合)
'colsample_bytree': [0.8, 1.0],# 特征采样率
'gamma': [0, 0.1], # 节点分裂的最小损失减少值
'reg_alpha': [0, 0.1], # L1正则化
'reg_lambda': [1, 10], # L2正则化
'objective':['multi:softmax'], # 多分类任务目标函数
}
# 2. 网格搜索+交叉验证
xgb = XGBClassifier()
grid_search = GridSearchCV(xgb,param_grid=param_grid,cv=5,n_jobs=-1)
grid_search.fit(x_train,y_train)
# 3. 保存最优模型
joblib.dump(grid_search.best_estimator_, "model/xgboost_best_model.pkl")
# 4. 模型评估与结果保存(核心逻辑)
xgb = joblib.load('model/xgboost_best_model.pkl')
test_pred = xgb.predict(x_test)
# 提取多分类召回率和准确率
report = metrics.classification_report(y_test,test_pred,digits=6)
report_list = report.split()
XGB_result = {
"recall_0": float(report_list[6]), # 类别0召回率
"recall_1": float(report_list[11]), # 类别1召回率
"recall_2": float(report_list[16]), # 类别2召回率
"recall_3": float(report_list[21]), # 类别3召回率
"acc": float(report_list[25]) # 整体准确率
}
# 保存结果到JSON(带时间戳)
save_result_to_json({"xgboost": XGB_result})
3.3 AdaBoost 的训练实现
AdaBoost 是基于提升法的集成算法,以决策树为基分类器,核心优化学习率和弱学习器数量:
python
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
# 1. 定义基分类器(决策树)
base_tree = DecisionTreeClassifier(max_depth=1, random_state=42)
ada_model = AdaBoostClassifier(estimator=base_tree, random_state=42)
# 2. 定义超参数网格(含基分类器参数)
param_grid = {
'n_estimators': [50, 100, 200], # 弱学习器数量
'learning_rate': [0.01, 0.1, 1.0], # 学习率
'estimator__max_depth': [1, 2, 3], # 基分类器树深度
'estimator__min_samples_split': [2, 5] # 基分类器节点分裂最小样本数
}
# 3. 网格搜索+交叉验证
grid_search = GridSearchCV(ada_model,param_grid=param_grid,cv=5,scoring='accuracy', n_jobs=-1)
grid_search.fit(x_train,y_train)
# 4. 保存最优模型
joblib.dump(grid_search.best_estimator_, "model/adaboost_best_model.pkl")
# 5. 模型评估与结果保存
ada = joblib.load('model/adaboost_best_model.pkl')
test_pred = ada.predict(x_test)
report = metrics.classification_report(y_test,test_pred,digits=6)
report_list = report.split()
ADA_result = {
"recall_0": float(report_list[6]),
"recall_1": float(report_list[11]),
"recall_2": float(report_list[16]),
"recall_3": float(report_list[21]),
"acc": float(report_list[25])
}
save_result_to_json({"adaboost": ADA_result})
四、结果分析:XGBoost 与 AdaBoost 在平均值填充数据集上的表现
4.1 核心评估指标
对于多分类任务,我们重点关注:
- 召回率(Recall):每个类别被正确预测的比例(避免漏检,尤其适用于类别不平衡场景);
- 准确率(Accuracy):整体预测正确的样本比例(全局性能指标)。
4.2 数值结果对比
基于平均值填充的数据集,XGBoost 和 AdaBoost 的训练结果如下(JSON 文件提取):
| 模型 | recall_0 | recall_1 | recall_2 | recall_3 | acc(准确率) |
|---|---|---|---|---|---|
| XGBoost | 0.95082 | 0.959184 | 1.0 | 0.888889 | 0.954023 |
| AdaBoost | 0.95082 | 0.959184 | 1.0 | 0.944444 | 0.957854 |
4.3 结果解读
- 类别召回率 :
- 两类模型在类别 0、1、2 上的召回率完全一致(0.95082、0.959184、1.0),说明对这三类样本的识别能力相当;
- AdaBoost 在类别 3 上的召回率(0.944444)显著高于 XGBoost(0.888889),对类别 3 样本的漏检率更低。
- 整体准确率 :
- AdaBoost 的准确率(0.957854)略高于 XGBoost(0.954023),整体性能更优;
- 对比其他模型:结合平均值填充下的其他模型结果(如 GNB 准确率仅 0.429119、LR 准确率 0.716475),XGBoost 和 AdaBoost 的优势极为明显,验证了集成算法在多分类任务中的有效性。
五、延伸思考:从 "单填充 + 单模型" 到 "全局最优"
本文仅分析了 "平均值填充" 下 XGBoost 和 AdaBoost 的表现,而项目的核心目标是找到 "最优填充方式 + 最优模型":
- 横向扩展:需对比同一模型在 6 种填充方式下的表现(如 XGBoost 在中位数填充、随机森林填充数据集上的召回率 / 准确率);
- 纵向扩展:需对比同一种填充方式下 8种模型的表现(如平均值填充下 SVM 准确率 0.881226,低于 AdaBoost);
- 业务适配:除了准确率 / 召回率,还需结合业务场景选择模型(如对推理速度要求高时,AdaBoost 可能优于 XGBoost,因基分类器更简单)
六、总结
本文以多分类任务为背景,完整拆解了 "平均值填充→XGBoost/AdaBoost 训练→结果分析" 的核心流程,得出以下结论:
- 数据清洗是基础:平均值填充能有效处理数值型缺失值,为模型训练提供高质量数据;
- 集成算法表现优异:XGBoost 和 AdaBoost 在平均值填充数据集上的准确率均超过 95%,远优于传统模型(如 LR、GNB);
- AdaBoost 更胜一筹:在类别 3 召回率和整体准确率上,AdaBoost 略优于 XGBoost,是平均值填充下的更优选择。
后续可进一步验证其他填充方式下的模型表现,最终筛选出适配业务场景的 "最优填充 + 最优模型" 组合,为多分类任务提供可落地的解决方案。
附:本文所有代码均基于项目中8种模型训练.py实现,未做修改,确保了结果的可复现性;模型评估结果均来自自动生成的 JSON 文件(如model_results_20260319_210628.json、model_results_20260319_211050.json),保证了数据的客观性。