☰
机器学习大作业实战:逻辑回归鸢尾花分类全流程与避坑指南
2026/10/9 11:25:36 网站建设 项目流程

简介:这是一份基于逻辑回归实现鸢尾花分类的机器学习大作业完整资料,压缩包内包含项目源码、实验报告与完整文档说明,适合需要完成课程设计或期末大作业的高校学生,也适合初学者借助完整示例理解分类模型。资源包为zip压缩格式,大小约192.11MB,代码注释详细、部署简单,下载后稍作配置即可运行,可帮助使用者系统掌握逻辑回归的数据预处理、特征选择、模型训练与评估流程。除可直接提交的源码外,配套实验报告还提供了实验背景、步骤分析、结果讨论和结论总结,为撰写课程设计文档提供清晰框架;整个项目结构完整、界面友好,具备良好的可扩展性与实际应用价值。资源目前已有265人浏览学习,整体完成度高,适合用于高分作业、课设选题或复试项目展示。

1. 从“调包跑通”到“把边界函数讲清楚”:鸢尾花逻辑回归大作业的含金量到底在哪

如果你也在赶机器学习大作业,逻辑回归做鸢尾花分类几乎是绕不开的经典题——数据集白送、模型简单、可视化效果好,但正因为人人都会做,想拿高分反而更难。这套资源我拆完之后的第一感受是:它不像多数课程设计那样只丢一个临时脚本,而是把数据探索、特征分布、逻辑回归训练、手写梯度下降、实验报告排版的全链路全备齐了。代码注释细到变量级别,实验报告连答辩时老师可能追问的点都预先埋好了答案。适合两类人:一类是急着交期末大作业、不想在环境配置和格式上翻车的新手;另一类是想把这套题做成“能讲清楚原理”的课程设计。下载后简单布置环境就能跑通,但真正值钱的不是那份准确率,而是藏在代码注释和报告里的那些抗答辩细节。

2. 为什么偏偏是“逻辑回归 + 鸢尾花”:模型原理与数据集里三个隐藏陷阱

2.1 逻辑回归不是“回归”:sigmoid 映射与决策边界

逻辑回归这个名字极具误导性,第一次接触它的人很容易把它当成回归模型。它其实做的是分类——本质上是一个线性模型加了一层 sigmoid 映射。线性回归的输出是实数域上的任意值,而分类任务需要的是“属于某个类别的概率”,所以逻辑回归把线性组合 z = w·x + b 塞进 sigmoid 函数里,压缩到 0 到 1 之间。

sigmoid 函数的表达式是 1 / (1 + exp(-z)),它在 z 大于 0 时输出大于 0.5,小于 0 时输出小于 0.5,所以 0.5 就成了默认的决策阈值。逻辑回归的损失函数也不是均方误差,而是交叉熵。为什么要用交叉熵?因为均方误差配合 sigmoid 会导致梯度在两端趋近于零,参数更新极其缓慢,训练就像陷在泥里走不动;交叉熵在这个组合下的梯度形式干净,误差大时更新快,误差小时更新慢。这个细节你在课程设计答辩时主动讲出来,老师会觉得你真懂,而不只是会调库。

鸢尾花数据集是典型的三分类问题,逻辑回归本身是个二分类器,处理多分类有两种常见策略。一种是 One-vs-Rest(OvR),每次拿一个类别当作正样本、其余全部当作负样本,训练三个二分类器,预测时选概率最高的那个;另一种是 Multinomial(也叫 softmax 回归),直接把 sigmoid 换成 softmax,一次性输出三个类别的概率分布。scikit-learn 里 LogisticRegression 的 multi_class 参数控制这两种方式,默认是 auto,当求解器是 lbfgs 时自动退化为 multinomial。这套作业用的是什么策略,你打开源码里的参数一眼就能看到,但更关键的是要知道为什么选它。

2.2 鸢尾花数据集的三个坑:类别重叠、量纲不一致、多分类退化

鸢尾花数据集一共 150 条样本,三个类别各 50 条,特征有四个:花萼长度、花萼宽度、花瓣长度、花瓣宽度。数据集看似简单,实际做起来有三个坑。

第一个坑是类别重叠。Setosa 这个类别和另外两类在特征空间里完全线性可分,随便一个模型都能把它干净地分出来;但 Versicolor 和 Virginica 在花瓣长度和花瓣宽度上有明显的重叠区域,真正的挑战在这里。很多同学跑完看准确率 97%、98% 就觉得万事大吉,但报告里没有任何分析告诉老师“错误集中在哪两个类别之间”,这在高分作业里是不可接受的。

第二个坑是量纲不一致。四个特征的数值范围差别明显,花萼宽度大致在 2.0 到 4.4 之间,花瓣长度能到 5.0 以上。逻辑回归的损失函数对特征尺度敏感,因为梯度更新的步伐会被大数值特征主导。如果不对特征做标准化,决策边界会被拉歪,而且解释系数重要性时会得出完全错误的结论。这也是为什么源码里必须在训练之前接一个 StandardScaler,而不是直接裸特征塞进模型。

第三个坑叫多分类退化。用 OvR 做三分类时,每个二分类器的正负样本比例是 1:2,类别不平衡虽然不严重,但对新手来说最容易被忽视的是标签与类别名的对应关系。鸢尾花的 target 是整数 0、1、2,对应 setosa、versicolor、virginica。作业里如果漏掉 target_names 的映射,混淆矩阵画出来就变成一堆数字,答辩时老师问“这个 0 是什么花”你就只能尴尬。

还有一个有点反直觉的点:这个数据集的精度上限很高,线性模型轻松就能到 90% 以上的准确率。有些同学拿到这个结果后以为模型已经最优了,实际上对这份作业来说,准确率只是一个起点,能解释清楚“错误为什么集中出现在 versicolor 和 virginica 之间”才是拿高分的关键。源码里把 pairplot 和混淆矩阵的分析都做了出来,你复现的时候不要跳过那一段可视化代码,那是整个报告最有说服力的部分。

3. 源码复现全流程:从数据加载到可视化报告,手把手拆开跑一遍

3.1 环境准备与数据加载:别在第一步就卡住

这份资源按 Python 语言编写,核心依赖是 scikit-learn、pandas、matplotlib。建议直接用 Python 3.8 以上的环境,安装命令也很常规。值得提醒的是,如果你在用国内源安装,建议给命令加一个清华镜像参数,否则 numPy 这种包下载可能会慢到让你误以为卡死了。

环境就绪后先跑数据加载脚本,这是整个项目的起点:

# 01_load_data.py import pandas as pd import numpy as np from sklearn.datasets import load_iris # 鸢尾花数据集内置在 sklearn 里,不需要额外下载文件 iris = load_iris() # data 是 (150, 4) 的特征矩阵,feature_names 是四个特征名 X = pd.DataFrame(iris.data, columns=iris.feature_names) # target 是整数标签,0=setosa, 1=versicolor, 2=virginica y = pd.Series(iris.target, name="target") print(X.shape, y.value_counts().to_dict())

这段代码的逻辑很简单但有一个细节容易被忽略:load_iris 返回的是一个 Bunch 对象,data 和 target 都是 NumPy 数组,如果不转成 DataFrame 和 Series,后续做数据探索时没法直接用列名操作,可视化代码也会变得很别扭。转成 pandas 结构纯粹是为了后面少写两行废话。

你运行后应该输出 (150, 4) 和 {'0': 50, '1': 50, '2': 50}。如果你看到的是别的样子,比如某个类别不是 50,那说明 sklearn 版本异常或者数据加载被中断,先别往下走,检查一下 sklearn 的完整性。

3.2 数据切分与标准化:随机种子和 stratify 为什么必须写

训练模型前要切分数据,但切分不是简单一行 train_test_split 就完事。很多新手作业里的经典错误是:不设置 random_state,每次运行结果都变;不做分层抽样,导致某个类别在测试集里只剩两三条。这份资源里的切分代码是值得直接抄的:

# 02_split_scale.py from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler # stratify=y 保证三个类别在训练集和测试集中的比例一致 # random_state=42 固定随机序列,让结果可复现 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y ) scaler = StandardScaler() # 先在训练集上 fit,得到均值和标准差 X_train_s = scaler.fit_transform(X_train) # 再用同一套统计量去 transform 测试集,绝对不能重新 fit X_test_s = scaler.transform(X_test)

这里有两个参数必须讲清楚。stratify=y 的作用是分层抽样,因为鸢尾花每类只有 50 条样本,假如随机切分时某一类在测试集中特别少,准确率的波动会剧烈到不可信;加了它之后,切分前后的类别分布基本一致。random_state=42 的作用更直接,它让整套实验有一个可复现的随机序列,你关掉 Jupyter 再打开,重新跑一遍得到的结果还是同一个,写报告时截图和代码输出不会对不上。

标准化这段代码是整份作业里最容易出“低于及格线”级别错误的地方。StandardScaler 必须在训练集上 fit,再用同一个 scaler 去 transform 测试集。原因是测试集代表的是一切“未见过”的数据,你如果在全量数据上算均值和标准差,测试集的信息就已经泄漏到了训练阶段,评估出来的准确率会虚高。这也是老师最爱问的“什么是数据泄漏”,源码里专门把这行拆开写,目的就是让你在答辩时能接住这个问题。

3.3 模型训练与评估:准确率只是入场券

模型训练部分用的是 sklearn 的 LogisticRegression,代码简洁到没什么可发挥的空间,但超参数设置需要解读:

# 03_train_eval.py from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score, classification_report, confusion_matrix # solver 选 lbfgs,适合小数据集和多分类 softmax # max_iter 调大到 200,防止数据标准化后收敛迭代不够 clf = LogisticRegression(max_iter=200, C=1.0, solver="lbfgs") clf.fit(X_train_s, y_train) y_pred = clf.predict(X_test_s) print("accuracy:", accuracy_score(y_test, y_pred)) print(classification_report( y_test, y_pred, target_names=iris.target_names )) print(confusion_matrix(y_test, y_pred))

solver 参数值得多说两句。逻辑回归的求解器有 liblinear、lbfgs、newton-cg、sag 等,对鸢尾花这种 150 条样本的小数据集,lbfgs 是最稳妥的选择——它适用于多分类 softmax,收敛速度快,内存开销低。如果你选 liblinear,它只支持 OvR 模式,结果通常也还行,但报告里解释模型时就得按二分类器集合的视角写,多一层复杂度。

max_iter 是一个典型的“新手不知道为什么翻车”的参数。lbfgs 是迭代求解器,默认最大迭代是 100 次,但鸢尾花数据经过标准化之后,损失函数的最小值点附近比较平缓,100 次有时不足以收敛到严格阈值,于是 sklearn 会给你甩一个 ConvergenceWarning。模型实际上已经跑得很好,但那个警告印在截图里很掉价,老师会怀疑你的代码素养。把它调到 200 算是给足余量,同时不影响任何性能。

分类报告里的 precision、recall、f1-score 是三分类评估的核心指标。在鸢尾花作业里要特别看 versicolor 和 virginica 两行的 recall,如果某一类的 recall 明显低于另一类,说明模型在两类重叠区域的偏置方向值得分析。报告里如果能写一句“错误集中在 versicolor 被误判为 virginica,这与花瓣长度分布重叠区域一致”,立刻比单纯摆一个 97% 准确率有深度。

3.4 手写逻辑回归:让作业从“调包”升级为“懂原理”的关键加分项

纯用 sklearn 完成作业只能拿一个基础分,因为老师一眼就能看出你只会调包。这份资源里最有价值的是它手写了一个简化版逻辑回归,用梯度下降训练参数,虽然精度略低于 sklearn 的 lbfgs,但能证明你理解迭代优化过程。完整代码如下:

# 04_manual_lr.py import numpy as np def sigmoid(z): # 数值稳定版本,防止 exp 溢出 return 1 / (1 + np.exp(-np.clip(z, -500, 500))) def train_binary(X, y, lr=0.1, epochs=500): # X 是特征矩阵,y 是 0/1 标签 # 在 X 前加一列全 1,对应偏置项 b X = np.c_[np.ones(X.shape[0]), X] w = np.zeros(X.shape[1]) m = len(y) for _ in range(epochs): pred = sigmoid(X @ w) grad = (X.T @ (pred - y)) / m w -= lr * grad return w # 对三个类别分别用 OvR 方式训练 W = [] for c in range(3): y_bin = (y_train == c).astype(int) w_c = train_binary(X_train_s, y_bin) W.append(w_c) W = np.array(W) # 形状 (3, n_features+1)

这段代码只用了 NumPy,没有任何机器学习库参与,核心逻辑就两个步骤:算梯度、更新参数。grad 的推导逻辑是交叉熵损失对 w 求导的结果,形式是 X 转置点乘(预测概率减真实标签)再除以样本数。这个公式在高等数学和机器学习课里都出现过,能自己写出来并跑通,含金量远超一个 100% 准确率。

训练完成后预测阶段要把三个二分类器的概率都算出来,然后选最大的那个作为最终类别:

# 用训练好的 W 做预测 X_te = np.c_[np.ones(X_test_s.shape[0]), X_test_s] probs = sigmoid(X_te @ W.T) # 每一行是三类各自的概率 y_pred_manual = probs.argmax(axis=1)

参数上要注意 lr 和 epochs 的配合。lr 设 0.1 对标准化后的特征比较合适,如果设得过大,loss 会震荡;epochs 设 500 对这个数据量级足够收敛到稳定值。这组手写模型的准确率通常会比 sklearn 版本低 1 到 2 个百分点,但报告中可以坦诚地写清楚差异来源——sklearn 的 lbfgs 是拟牛顿法,收敛更精细,你的手写版是简单梯度下降,两者对比本身就是很好的实验结论。

4. 实验报告怎么排才能像满分作业:结构、图表与答辩追问一次备齐

4.1 实验报告的五段式骨架:从摘要到结论的完整叙事线

这份资源附带的实验报告是整个压缩包的另一半价值。很多同学源码写得不错,报告却写成“我用了什么模型、准确率多少”的三行流水账,把分数硬生生拉低一档。拆开这份满分实验报告,你会发现它的骨架是固定的五段式,每一段的篇幅和职责都非常清晰,可以直接当模板套用。

实验报告的结构可以参照下表:

章节核心内容篇幅建议写作要点
摘要问题定义、方法选型、核心结论200 - 300 字三者缺一不可,禁止只写准确率
数据探索数据规模、类别分布、特征统计、相关性1 - 2 页必须配 pairplot 或箱线图
模型原理sigmoid 推导、损失函数、求解器选型1 - 2 页公式推演要完整,别抄教材原话
实验设计切分方式、标准化、评估指标、对比实验1 页写清为什么用这些设置
结果分析混淆矩阵、分类报告、错误分布分析1 页分析错误的类别倾向,不摆数字

摘要部分最容易被写成“本项目使用逻辑回归对鸢尾花分类,准确率达 97%”——这等于什么都没说。高分摘要把问题、方法、结论三个要素串起来,写法是:“针对鸢尾花数据集三分类问题,本文采用逻辑回归模型,通过 OvR 策略将二分类器扩展到三分类,并对比了 sklearn 实现与手写梯度下降实现的性能差异。实验结果表明,经标准化后的模型在测试集上达到 96% 的准确率,错误主要集中于 versicolor 与 virginica 的重叠区域。”一句话把任务和方法说清,还给出了比准确率更深入的分析点。

数据探索这一章千万别截皮尔逊相关系数热力图就完事,更要有特征分布的解读。比如花瓣长度在三类间的区分度明显高于花萼宽度,这就是报告中可以自然推导出“花瓣特征是分类的主要信息源”这一结论的关键证据。这条结论不仅撑起了数据探索章,还能支撑模型原理章里“为什么逻辑回归在鸢尾花上有效”的论述。

4.2 图表与公式排版:决定性的一步在字号和图表

实验报告的观感左右着评分,排版精美的报告和粗糙的报告在同等技术水平下,分差能有 5 分以上。答辩场景下,老师默认你代码没问题,报告反映的是你的专业写作能力。图表方面要注意三个细节:所有图的尺寸统一、字号统一、坐标轴必须有标签。

训练过程可视化是值得放进报告的额外加分项——在逻辑回归训练中记录每一轮迭代的 loss 值,画出一条下降曲线。这条曲线直观证明了模型在收敛,比一万字描述“我观察了 loss 的下降过程”都更有力。曲线图中横轴是 epoch,纵轴是交叉熵损失,训练好的曲线应是一条陡降后趋平的线。如果曲线出现振荡,说明学习率过大或数据未标准化,报告里也可以专门分析这种失败案例,反而体现出更真实的实验过程。这也是这份资源里做好的“实验记录类”可视化,和我见过的满分作业风格一致。

源码里画 pairplot 那一段代码建议完整保留并重命名输出文件,比如改成 feature_distribution.png,插入报告时保持文件名和图中内容一致。插图的引用规范是图下方居中写“图1 鸢尾花特征分布矩阵”,正文中写“如图1所示”,这一点细节能让老师对你的严谨程度产生很强的信任感。

公式排版要特别注意。逻辑回归的核心公式包括 sigmoid 函数、交叉熵损失、梯度更新式,至少要保证这三行是标准排版而不是截图。报告里最好用一个独立小节写手动梯度下降的实现思路,包括推导误差函数对权重的梯度公式,已完成训练的模型参数权重的含义解读——比如花瓣特征的权重绝对值最大,说明它对分类贡献最强,完全对应数据探索部分的观察。

4.3 答辩最可能被追问的四个问题与应对思路

答辩是这门大作业的最后一关。源码和报告是静态的,口头回答才是老师判断“这人到底懂不懂”的关键时刻。我盘点了这份资源里最有针对性的几个追问点,直接把应对思路准备好。

第一个问题:“逻辑回归是回归还是分类?为什么叫回归?”满分的答案是:“逻辑回归本质是分类模型,名字里的回归来源于它在线性回归的基础上做了 sigmoid 变换,输出的是条件概率估计。”如果还愿意多说,可以补一句“它计算的是 P(Y|X) 属于某一类的后验概率”,这句话会显得你不是背出来的。

第二个问题:“为什么特征要标准化?”回答思路是:“逻辑回归使用梯度下降优化,不同特征量纲差异大会导致梯度更新方向被大数值特征主导,收敛变慢,还可能让决策边界偏移;标准化后所有特征被压缩到近似同一尺度,每个特征对分类的贡献被公平对待。”注意,从决策边界偏移角度回答是最容易打动老师的。

第三个问题:“三类样本重叠,为什么模型还能有 97% 的准确率?”这个问题直接考察你对自己实验的理解。答案是:“重叠只体现在部分特征上,花瓣长度和宽度仍然保留了较强的类别区分度;模型的决策边界在二维投影下看似有交叉区域,但在四维特征空间中依然能找到一个较好的线性超平面。准确率并不说明线性可分,只说明重叠区域没有明显覆盖到多数样本。”

第四个问题:“sklearn 版本和你手写的版本,结果差异是什么?”答案是:“sklearn 的 lbfgs 是拟牛顿法,利用二阶信息近似,收敛精度更高;手写版是简单梯度下降,步长固定,精度略低,但整体趋势一致。这个对比说明模型的有效性主要来自数据特征和模型形式,优化器的差异只是在收敛速度上。”这个问题如果你能接上,整场答辩基本就稳了。

5. 避坑指南:鸢尾花逻辑回归作业里高频翻车的六类问题

5.1 准确率逼近 100%,老师反而质疑是抄的

现象:测试集准确率直接到 100%,你自己觉得爽,但老师第一反应是“这人有问题”。因为鸢尾花数据集本身就存在类别重叠,合理的线性模型准确率通常在 93% 到 98% 之间,满分结果往往意味着训练和测试数据发生了泄漏,或者评估方式有误。

原因:最常见的是在全量数据上做标准化后切分,或者跑完网格搜索后在全部数据上重新训练评估。测试集的信息在训练阶段就已经被模型了解过,评估自然虚高。

解决:严格保证训练集、测试集分开处理,标准化只在训练集上 fit,评估只用测试集。如果你的结果确实高于 98%,检查一下是不是把训练集的预测结果当成测试集输出了,这是新手最容易犯的无心之失。

5.2 StandardScaler 的 fit 时机错了,整个实验都在泄漏

现象:你在训练之前先对整个 X 做了 fit_transform,再切分训练集和测试集。这时训练集里已经包含了测试集的均值和方差信息,相当于把试卷答案提前交给了模型。

原因:数据泄漏不是模型 bug,而是流程设计错误。很多教程演示标准化时图省事,直接在全量数据上调用 fit_transform,新手照抄就出了同样的问题。

解决:把 fit_transform 和 transform 拆开,先后顺序是切分两集,再在训练集上 fit,再 transform 测试集。源码里 02_split_scale.py 就是标准写法。我在复盘这套作业时用一句话记住这个规则:“模型永远不该事先知道测试集的统计量”。

5.3 多分类标签与预测结果对不上,混淆矩阵看懵了

现象:混淆矩阵输出后,你看不清哪个数字对应哪种花,报告里的结论也写得含含糊糊。你在 submission 里说“第三类准确率最高”,到底第三类是 versicolor 还是 virginica,老师看两遍也不知道结论明确没有。

原因:target 是整数 0/1/2,你打印 y_pred 时看到的是 NumPy 数组里的数字,没有做 target_names 映射。

解决:评估时一律用 target_names=iris.target_names 输出报告,混淆矩阵用 pandas 加列名和行名再打印。这个小改动直接决定报告的可读性。

5.4 报告截图和代码输出对不上,随机种子没固定

现象:报告中截图显示准确率 96.7%,老师运行代码得到 93.3%,立刻怀疑报告是拼凑的。原因很简单:你没设置 random_state,每一次运行都重新随机切分数据,结果自然每次不同。

解决:train_test_split 必须带 random_state,且建议固定为某个常见值如 42,同时报告里明确写“实验采用随机种子 42”。种子选多少不重要,重要的是固定下来,报告截图和可复现结果保持一致。

5.5 sklearn 版本不同,输出的警告和系数都不一样

现象:资源作者用的是旧版本或新版本,你换了版本后,函数明明一样但结果有细微差别,甚至出现弃用警告。sklearn 的 LogisticRegression 默认参数在版本迭代中发生过调整,solver 的默认值在不同版本中不同,多分类策略的默认行为也不同,这会让你的运行结果与报告不完全一致。

原因:文档说明里写的是作者当时的运行环境,你无法保证完全复现。

解决:保持项目里的 requirements.txt 版本约束,至少约束 sklearn 主版本,然后在代码里显式指定 solver、multi_class、max_iter 参数,不依赖任何默认值。这样无论环境怎么变化,逻辑都是确定的。

5.6 手写梯度下降的 loss 振荡,直接就写“模型发散”

现象:自己实现逻辑回归时,loss 没有单调下降,而是跳着走,于是你认为手写实现失败了,放弃这部分代码。这其实是参数设置问题,不是算法问题。学习率过大时参数更新步长跨过了最低点,loss 就会反复震荡。

原因:梯度下降的收敛条件是学习率和迭代次数的配合。鸢尾花数据量小,标准化后的特征数值在 0 附近,学习率超过 0.5 就很容易振荡。

解决:先把学习率降到 0.1 或 0.01,观察 loss 曲线如果仍然震荡继续降。或者使用自适应学习率的方式,让学习率随迭代次数衰减,比如 lr = initial_lr / (1 + t * decay),这是最简单有效的手段。源码里写的是固定学习率,更稳。

5.7 报告里公式和图没有编号,被批“排版态度不端正”

现象:报告里公式直接用截图放进 Word,图和表也没有编号,答辩被老师提了一句“格式再改改”。究其原因,公式和图表是报告的骨架,一线老师几乎都默认这是写作的基本功,无需提醒。

解决:所有公式用 LaTeX 或 Word 自带公式编辑器重排,所有图统一编号并加图注,表中数据保留两位小数。更重要的是一致性——图的尺寸、字体、坐标轴标签必须统一风格。

6. 吃干榨净:把决策边界可视化和参数调优塞进作业,从“做完”到“做好”

6.1 决策边界可视化:一张图顶过一千字

绝大多数同学的作业到混淆矩阵就结束了,但满分作业往往会再往前走一步:把决策边界画出来。这一步技术难度低,视觉冲击力强,报告里的价值密度极高。核心代码如下:

# 05_decision_boundary.py import matplotlib.pyplot as plt from sklearn.inspection import DecisionBoundaryDisplay # 为了能画二维图,只取前两个特征(花萼长、花萼宽)做演示 X_2d = X_train_s[:, :2] clf_2d = LogisticRegression(C=1.0, max_iter=200) clf_2d.fit(X_2d, y_train) DecisionBoundaryDisplay.from_estimator( clf_2d, X_2d, response_method="predict", cmap=plt.cm.RdYlBu, alpha=0.6 ) plt.scatter(X_2d[:, 0], X_2d[:, 1], c=y_train, edgecolor="k", s=40) plt.xlabel("sepal length (standardized)") plt.ylabel("sepal width (standardized)") plt.show()

DecisionBoundaryDisplay 这个 API 最大的优势是几行代码就把网格背景和真实样本点叠在一张图上,你根本不用手动生成网格坐标再逐个预测。需要注意,因为只用了两个特征,模型丢失了花瓣长度的信息,分类效果会变差,所以这张图的作用是“可视化决策边界形态”而不是“证明模型多准”。报告中写清楚“仅用前两个特征绘制示意图”就不会被抓逻辑问题。如果想展示最佳效果,可以再选花瓣长度和花瓣宽度作为特征重画一张,那一张的分类效果更接近完整模型。这两张图对比放在报告里,几何直观性极强。

6.2 超参数调优:用网格搜索把 C 值的取舍写明白

逻辑回归里唯一需要认真调的连续超参数是正则化强度 C,C 越小正则化越强,决策边界越平滑;C 越大模型越贴近训练数据。对于鸢尾花这种小样本、特征少的数据集,C 的选择对准确率影响不大,但分析过程本身是课程设计里一块不错的展示材料。

# 06_grid_search.py from sklearn.model_selection import GridSearchCV param_grid = { "C": [0.01, 0.1, 1, 10, 100], "solver": ["lbfgs", "liblinear"], } grid = GridSearchCV( LogisticRegression(max_iter=500), param_grid, cv=5 ) grid.fit(X_train_s, y_train) print("best C:", grid.best_params_) print("best cv score:", grid.best_score_)

这段代码做了五折交叉验证,对每一组参数评估五次取平均。好处是结果对数据切分的敏感性低得多,比单一测试集上的准确率更有说服力。你会看到最优 C 基本落在 1 附近,而 solver 的影响很小,这个结论与理论预期一致:数据量小、特征四维,正则化过强反而压缩了模型表达能力。在你的报告里把网格搜索的表格放进去,比简单单一模型得出的结论完整度高出一个档次。顺便提一下,如果资源里没有这段可以参考其他课程设计的写法,建议自己补上,几十行代码带来的印象分很值。

6.3 复盘习惯

回顾我拆解这套项目的整个过程,看看别人家的满分作业在哪些环节投入了精力——注释写到变量级、实验报告把每一步设计原因讲清楚、答辩问什么都能接住、每个参数设置背后都有它的理由。从那以后,我交机器学习类的课程作业都会强制走一遍固定流程:先跑通、再自查数据是否泄漏随机种子是否固定,再补手写实现和可视化,最后写报告时把报告里每一句结论都反推回代码输出,确认有据可查。养成这个循环,期末你会轻松不少。希望这份资源对你的课程设计或期末大作业有点实际帮助。

本文还有配套的精品资源,点击获取

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

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

立即咨询