前言
欢迎回到《速通机器学习》系列!
前面我们训练模型时,仅仅单次划分训练集、测试集存在明显缺陷:数据集划分具有随机性。运气好划分效果好,模型指标很高;运气差划分糟糕,评估结果失真,无法客观反映模型真实性能。
同时我们在逻辑回归中接触到超参数C,人工盲目挑选参数效率很低。
本章学习K 折交叉验证,解决两个核心问题:
- 稳定、客观评估模型效果,降低数据集随机划分带来的误差
- 结合交叉验证完成超参数挑选,选出最优正则系数 C
重要规范:绝对不能使用测试集参与调参! |
5.1 什么是 K 折交叉验证
在进行交叉验证前,首先将完整数据集划分为训练集和独立测试集,测试集全程隔离,不参与任何训练与调参过程。
- 数据集拆分:仅将训练集均匀划分为 K 个子集(K折),严格保留测试集完整数据,不作任何拆分,用于最终模型效果验证。
- 循环交叉训练:轮流选取其中1个子集作为验证集,剩余 K-1 个子集合并作为训练数据,迭代训练模型。
- 指标综合评估:完整循环 K 次后,会得到 K 组模型评估指标,对所有指标求取平均值,以此作为模型的综合性能分数,规避单次数据划分带来的偶然性误差。
- 超参数择优:遍历多组候选超参数,通过K折交叉验证对比各组参数的平均性能指标,筛选出适配当前数据集的最优超参数。
- 模型最终训练与验证:确定最优超参数后,使用完整训练集重新训练最终模型,再用全程隔离的独立测试集,模拟真实业务场景完成最终性能测试。
业务提醒
交叉验证只是在训练集内部进行评估调参,测试集全程隔离,仅作为最终模拟真实线上数据。
k折代码实现
核心API代码实现
首先导入交叉验证核心工具库:
from sklearn.model_selection import cross_val_score标准调用语法:
score = cross_val_score(model, X, y, cv, scoring)参数详细说明:
- model:待训练的机器学习模型,本文为逻辑回归模型
- X:训练集全部特征数据
- y:训练集对应标签数据
- cv:交叉验证折数,代表将训练集均匀拆分的份数
- scoring:模型评估指标,常用参数包含recall召回率、precision精确率、f1综合分数、roc_auc曲线面积等,可根据业务场景灵活选择
函数返回值:返回包含 K 次交叉验证评估结果的数组,数组长度与设置的折数 cv 一致,后续可通过均值计算得到模型综合性能分数。
5.2 实战分步讲解(三段式:调参前→K折调参→择优训练)
本节结合信用卡欺诈数据集,将K折交叉验证超参数优选流程,拆分为调参前数据准备、K折交叉验证选参、最优参数模型训练验证三个核心阶段,逻辑清晰、贴合工业建模规范。改代码是根据前一章节,银行辨别欺诈系统改进的,所以省略部分代码讲解,可查看前一章节详细解答:
https://blog.csdn.net/2302_80153357/article/details/163374899?spm=1011.2415.3001.5331
5.2.1 第一阶段:K折调参前准备(数据预处理+数据集隔离)
核心原则:测试集全程隔离,仅用纯训练集做交叉验证调参,杜绝数据泄露,保证模型泛化能力真实可靠。
主要工作:完成数据清洗、特征标准化、分层数据集划分,为后续调参提供干净、均衡的数据集。
完整代码实现如下:
import pandas as pd import numpy as np import matplotlib.pyplot as plt from sklearn.preprocessing import StandardScaler from sklearn.model_selection import train_test_split, cross_val_score from sklearn.linear_model import LogisticRegression from sklearn.metrics import classification_report, confusion_matrix # 解决matplotlib中文乱码 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False # 混淆矩阵绘制函数 def cm_plot(y_true, y_pred): """绘制混淆矩阵热力图""" cm = confusion_matrix(y_true, y_pred) fig, ax = plt.subplots() im = ax.matshow(cm, cmap=plt.cm.Blues) plt.colorbar(im) # 填充单元格数字 for x in range(cm.shape[0]): for y in range(cm.shape[1]): ax.annotate(cm[x, y], xy=(y, x), ha="center", va="center") plt.ylabel('真实标签') plt.xlabel('预测标签') return plt # 1.数据读取与预处理 data = pd.read_csv(r"D:\pythoncode2\bigdata_ai40\机械学习\data\creditcard.csv") # 删除无用时间特征 data = data.drop('Time', axis=1) # 对量纲差异大的金额字段标准化 scaler = StandardScaler() data['Amount'] = scaler.fit_transform(data[['Amount']]) # 2.划分特征与标签 X = data.drop('Class', axis=1) y = data['Class'] # 3.分层划分训练集、独立测试集 # stratify=y 保证不平衡数据正负样本比例一致,测试集全程不参与调参 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=42, stratify=y )阶段核心要点:
- 仅X_train、y_train用于后续K折交叉验证调参
- X_test、y_test 彻底封存,只用于最后一次模型最终评估
- 分层抽样stratify=y是不平衡数据集建模的必备操作
5.2.2 第二阶段:K折交叉验证核心(遍历超参数+参数详解)
本阶段核心目的:遍历多组正则化超参数C,通过8折交叉验证,筛选出适配欺诈识别场景的最优参数。我们优先以召回率为评估标准,减少欺诈漏检。
K折交叉验证核心代码如下:
# 定义逻辑回归超参数候选范围 c_param_range = [0.01, 0.1, 1, 10, 100] recall_mean_list = [] # 遍历每一组超参数,执行K折交叉验证 for c in c_param_range: # 初始化逻辑回归模型 lr = LogisticRegression(C=c, solver='lbfgs', max_iter=1000) # K折交叉验证核心代码 score_array = cross_val_score(lr, X_train, y_train, cv=8, scoring='recall') # 计算K折平均召回率 avg_recall = score_array.mean() recall_mean_list.append(avg_recall) print(f"C={c},交叉验证平均召回率:{avg_recall:.4f}") # 筛选交叉验证效果最优的超参数 best_c = c_param_range[np.argmax(recall_mean_list)] print("="*50) print(f"交叉验证筛选得到最优惩罚系数 C = {best_c}")核心参数完整解析:
- cv=8:8折交叉验证,将训练集均匀拆分为8份,轮流训练验证,结果更稳定,规避单次划分偶然性误差
- scoring='recall':指定评估指标为召回率,贴合信用卡欺诈业务,优先保证不漏检欺诈样本
- C:逻辑回归正则化超参数,C越小正则约束越强,抑制过拟合效果越好
- max_iter=1000:增大梯度下降迭代次数,避免模型训练不收敛报错
阶段核心逻辑:每组超参数都会得到一组平均泛化性能,通过对比所有参数的指标,选出适配数据集的最优参数,替代人工盲目调参。
5.2.3 第三阶段:最优参数确定后,模型训练与最终验证
找到最优超参数后,不再修改参数,使用完整训练集训练最终模型,最后用全程隔离的测试集模拟真实业务数据,完成模型最终评估,全程遵循「训练调参、测试验收」的工业建模规范。
最终模型训练与评估代码如下:
# 使用交叉验证筛选出的最优超参数训练最终模型 best_lr = LogisticRegression(C=best_c, solver='lbfgs', max_iter=1000) best_lr.fit(X_train, y_train) # 1.训练集模型评估 train_pred = best_lr.predict(X_train) print("\n【训练集评估报告】") print(classification_report(y_train, train_pred)) cm_plot(y_train, train_pred).show() # 2.独立测试集最终评估(仅使用一次,模拟线上真实效果) test_pred = best_lr.predict(X_test) print("\n【测试集最终评估报告】") print(classification_report(y_test, test_pred, digits=6)) cm_plot(y_test, test_pred).show()阶段核心规范:
- 最优参数只由训练集K折验证结果决定,不参考任何测试集数据
- 测试集仅用于最终效果验收,全程只使用一次,保证评估结果真实可信
- 结合分类报告、混淆矩阵双重评估,规避单一准确率的欺骗性
逻辑回归参数C:正则化系数,值越小,正则化越强,抑制过拟合效果越好。
我们通过 K 折交叉验证遍历一组候选 C 值,选择交叉验证平均召回率最高的超参数(欺诈场景优先召回率)。
核心注意点
1.杜绝数据泄露:测试集必须全程隔离,仅用于最终模型验收,绝对不能参与K折交叉验证与超参数调参,否则模型泛化结果虚高、上线失效。
2.指标按需选择:评估指标不能固定,需贴合业务场景。风险类场景优先召回率,精准审核场景优先精确率,综合场景选用F1、AUC指标。
3.适配不平衡数据:面对正负样本不均衡数据集,必须搭配分层抽样划分数据集,保证每折数据类别比例均衡,避免评估失真。
4.方法具备通用性:K折交叉验证不局限于逻辑回归,适配所有机器学习模型,是通用的模型评估、超参数优选方法。
本章总结
本章主要讲解了K折交叉验证的原理与超参数调优实战。K折交叉验证是通用的机器学习评估方法,适用于所有模型,不局限于逻辑回归,可用于各类模型的性能评估与超参数筛选。
相比单次数据集划分,该方法可有效降低随机误差,让模型评估结果更稳定可靠。工业建模中,需遵循「训练集交叉验证调参、测试集最终验收」的标准流程,结合业务场景选择合适评估指标,提升模型泛化与落地效果。