【一个完整的机器学习分类任务流程(用逻辑回归模型给鸢尾花分类)】
一个完整的机器学习分类任务流程。
用逻辑回归模型给鸢尾花分类,还加了 “自动调参” 功能,全程用专业的 Pipeline 串联,避免出错。
用鸢尾花的 4 个特征(花萼长度、花萼宽度、花瓣长度、花瓣宽度),训练一个模型,自动区分鸢尾花的 3 个品种(标签 0/1/2)。
用 “网格搜索” 自动找最优参数,让模型准确率更高。
1、-----------导入工具包----------------------
from sklearn.datasets import load_iris # 加载鸢尾花数据集(自带的“练习数据”)
from sklearn.model_selection import train_test_split, GridSearchCV # 拆分数据、自动调参工具
from sklearn.pipeline import Pipeline # 流程管道(把多个步骤串起来,避免出错)
from sklearn.preprocessing import StandardScaler, PolynomialFeatures # 数据预处理工具(标准化、特征升维)
from sklearn.linear_model import LogisticRegression # 逻辑回归模型(核心分类算法)
from sklearn.metrics import classification_report # 模型评估报告(看准确率、召回率等)
from sklearn.decomposition import PCA # 降维工具(这里没用到,相当于备用工具)
2、-----------------加载数据----------------
X_origin, y_origin = load_iris(return_X_y=True)
"""
load_iris(return_X_y=True) 会返回两部分数据:
X_origin:特征数据(4 列,每列是一个特征,比如花萼长度);
y_origin:标签数据(1 列,每个值是 0/1/2,代表鸢尾花的 3 个品种);
简单说:X 是 “描述花的特征”,y 是 “花的品种答案”。
"""
3、---------------拆分训练集和测试集(相当于 “分训练题和考试题”)------------
X_train, X_test, y_train, y_test = train_test_split(
X_origin,
y_origin,
test_size=0.2,
random_state=666
)
'''
把所有数据分成两部分:
X_train、y_train:训练集(80% 的数据,相当于 “课后习题”,用来教模型学习特征和标签的关系);
X_test、y_test:测试集(20% 的数据,相当于 “期末考试题”,用来检验模型学得好不好);
关键参数:
test_size=0.2:测试集占 20%(常用比例);
random_state=666:固定随机种子(保证每次运行拆分结果一样,方便复现)。
'''
4、---------------------搭建 Pipeline 流程(相当于 “制定做菜步骤”)-----------------
pipe = Pipeline([
('scaler', StandardScaler()), # 步骤1:数据标准化
('poly', PolynomialFeatures()), # 步骤2:特征升维(给模型加“高阶特征”,提升拟合能力)
('model', LogisticRegression( # LogisticRegression逻辑回归
penalty='elasticnet', # 正则化类型:L1+L2混合(防止模型过拟合)
C=1, # 正则化强度(默认值,后续会自动调参)
l1_ratio=0.2, # L1和L2的比例(默认值,后续自动调参)
solver='saga', # 优化器(支持混合正则化,适合多分类)
max_iter=100 # 最大迭代次数(训练时的“最大步数”)
))
])
'''
核心作用:把 “数据预处理” 和 “模型训练” 串成一个流程,避免 “数据泄露”(比如用测试集的信息训练模型,导致结果作弊)。
流程顺序:先标准化 → 再特征升维 → 最后用逻辑回归训练。
为什么要标准化?逻辑回归对特征尺度敏感(比如有的特征是 1-10,有的是 0-1),标准化后所有特征在同一尺度,模型训练更稳定;
为什么要特征升维?原始特征是 “线性特征”,升维后会生成 “高阶特征”(比如特征 1× 特征 2),让模型能捕捉更复杂的关系(比如花瓣长度和宽度的乘积对品种的影响)。
'''
5、-----------------定义参数网格(相当于 “准备要试的调料组合”)------------------
param_grid = {
'model__C': [0.01, 0.1, 1, 10, 100], # 要测试的C值(正则化强度)
'model__l1_ratio': [0, 0.2, 0.8, 1], # 要测试的l1_ratio值(L1/L2比例)
}
'''
模型的参数(比如C、l1_ratio)直接影响效果,但我们不知道哪个值最好。所以这里定义了 “要测试的参数组合”:
model__C:测试 5 个值(0.01→正则化最强,100→正则化最弱);
model__l1_ratio:测试 4 个值(0→纯 L2,1→纯 L1,0.2/0.8→混合比例);
总共要测试 5×4=20 种参数组合,找出效果最好的。
'''
6、--------------------- 网格搜索(相当于 “自动试所有调料组合,找最好吃的”)-----------
search = GridSearchCV(
pipe, # 要优化的流程(之前定义的Pipeline)
param_grid=param_grid, # 要测试的参数组合
cv=5, # 5折交叉验证(把训练集再分成5份,轮流当“验证集”,避免偶然)
scoring='f1_macro', # 评估指标(多分类任务常用,兼顾准确率和召回率)
verbose=2, # 训练时输出详细信息(让你看到进度)
n_jobs=3 # 用3个CPU核心并行计算(加快调参速度)
)
'''
核心作用:自动用 20 种参数组合训练模型,每种组合都用 5 折交叉验证评估,最后选出 “效果最好的参数组合”。
为什么用交叉验证?避免单次训练的 “运气成分”(比如刚好训练集里的样本都很简单),让最优参数更可靠。
'''
7、-------------------------------训练 + 调参(相当于 “按流程做菜 + 试调料”)-------------
search.fit(X_train, y_train)
'''
解释:运行这行代码后,程序会自动做这些事:
1.对训练集做 “标准化→特征升维→逻辑回归训练”;
2.用 20 种参数组合轮流训练,每种组合用 5 折交叉验证;
3.记录每种组合的效果,找出最好的。
这步会花一点时间(取决于数据量和参数组合数),控制台会输出进度。
'''
8、---------------------输出最优结果(相当于 “看哪个调料组合最好”)---------------------
print('最佳参数:\n', search.best_params_) # 输出效果最好的参数组合
print('最佳模型:\n', search.best_estimator_) # 输出效果最好的完整模型
print('最佳分数:\n', search.best_score_) # 输出最佳模型的训练集分数(5折交叉验证的平均分数)
'''
输出示例:
最佳参数:
{'model__C': 10, 'model__l1_ratio': 0.2}
最佳模型:
Pipeline(steps=[('scaler', StandardScaler()), ('poly', PolynomialFeatures()), ('model', LogisticRegression(C=10, l1_ratio=0.2, penalty='elasticnet', solver='saga'))])
最佳分数:
0.9833333333333334
解读:用 C=10、l1_ratio=0.2 的参数时,模型在训练集上的平均分数是 98.3%,效果很好。
'''
9、--------------------测试模型(相当于 “期末考试”)-----------------
predications = search.predict(X_test) # 用最佳模型预测测试集
'''
用之前选好的 “最佳模型”,对测试集(20% 的新数据)做预测,得到 predications(预测的标签)。
'''
#10、---------------输出评估报告(相当于 “看考试成绩单”)---------------
report = classification_report(y_test, predications)
print('报告:\n', report)
输出示例:
报告:
precision recall f1-score support
0 1.00 1.00 1.00 10
1 1.00 0.91 0.95 11
2 0.90 1.00 0.95 9
accuracy 0.97 30
macro avg 0.97 0.97 0.97 30
weighted avg 0.97 0.97 0.97 30
解读报告里的关键指标(针对多分类):
- precision(精确率):预测为某个品种的样本中,真的是这个品种的比例(比如预测为 0 类的 10 个样本,全对);
- recall(召回率):真实是某个品种的样本中,被模型正确预测的比例(比如真实 1 类有 11 个,预测对了 10 个);
- f1-score:精确率和召回率的平均值(综合指标);
- accuracy(准确率):测试集上总预测正确的比例(这里是 97%,很好);
- support:每个品种的测试集样本数(比如 0 类有 10 个测试样本)。
核心步骤总结:
加载鸢尾花数据 → 拆分训练 / 测试集 → 搭建 “标准化→特征升维→逻辑回归” 的流程 → 用网格搜索试 20 种参数组合 → 找到最优模型 → 用测试集检验效果 → 输出评估报告。
常见疑问
1、为什么用 Pipeline?
答:避免 “数据泄露”:比如如果先对所有数据标准化,再拆分训练 / 测试集,测试集的信息会提前泄露给模型(相当于考试前看了答案),Pipeline 会确保 “只在训练集上做预处理,测试集直接用训练集的预处理规则”。
2、参数 l1_ratio 为什么能选 0 或 1?
答:l1_ratio=0 等价于纯 L2 正则化(惩罚大系数,防止过拟合);l1_ratio=1 等价于纯 L1 正则化(让不重要的特征系数为 0,实现特征筛选);0-1 之间是混合比例。
3、为什么我的结果和示例不一样?
答:可能是 random_state 不同(拆分数据的方式变了),但分数应该都在 95% 以上(鸢尾花数据集很简单)。
4、max_iter=100 会不会不够?
答:有可能!如果运行时出现 ConvergenceWarning(收敛警告),可以把 max_iter 调大(比如 500),在 LogisticRegression 里加 max_iter=500 即可。
如果想修改 / 优化代码(新手可尝试)
- 去掉特征升维:如果觉得模型太复杂,可删除 (‘poly’, PolynomialFeatures()), 这一步,直接用原始特征训练;
- 调整参数范围:比如 model__C 可以加 0.001 或 200,看看是否有更好的结果; 换评估指标:把 scoring=‘f1_macro’ 改成 scoring=‘accuracy’(准确率),更直观。
更多推荐
所有评论(0)