简介:面向机器学习初学者的SVM分类实战项目包,基于Python 3.9与sklearn、numpy、Matplotlib构建。项目以经典Iris鸢尾花数据集为样本,包含数据加载、特征处理、模型训练与分类结果可视化等完整流程,并配有详细实验报告。压缩包共18个文件,其中2个Python源码用于实现SVM分类与图形绘制,2份docx报告提供原理分析和结论整理,7张png包含ROC曲线、各类花卉样本图等关键输出,另有xml、gitignore等配置文件辅助环境还原,整体仅631KB,便于快速下载与本地实验。已有970人学习下载,适合正在完成SVM课程作业或希望掌握分类模型应用的学习者。通过源码可直接运行并复现分类结果,结合报告中的模块说明与可视化输出,可深入理解SVM核函数、决策边界及评估指标等关键环节;完整目录结构及运行截图亦可作为课程设计或实验报告的参考模板。
1. 用SVM跑通鸢尾花分类:这份作业源码到底能帮你省多少事
这份机器学习SVM作业,基于Iris鸢尾花数据样本实现SVM分类,源码加报告打包在一起,正好是很多课程设计里“数据加载→可视化→模型训练→评估→写报告”的标准闭环。它的价值不在于算法多前沿,而在于把sklearn、numpy、Matplotlib这几个最常用的库,以最直白的方式串了一遍——对刚接触机器学习的同学来说,照着这份源码跑通一次,比看十篇教程都管用。资源里有两个Python文件、一个实验报告docx,还有若干训练过程中生成的ROC曲线图和数据分布图。适合正在做模式识别课程设计、机器学习期末作业,或者想快速上手SVM却不想从零造轮子的人。下面我按实际落地顺序,把文件作用、运行步骤和坑位一一拆开,你看完可以直接在自己的电脑上复现。
2. 环境与代码结构:先搞清文件里有什么,再决定怎么改
2.1 文件清单与各自用途
我把压缩包解压后整理了一下,核心文件就几个,别被那一堆图片和.idea目录吓到。.idea是PyCharm的工程配置,对你运行没任何影响;~$学习SVM作业报告.docx是Word打开时生成的临时锁文件,正常关闭后会自动消失,可以忽略。真正要关注的是这些:
| 文件/目录 | 类型 | 作用 |
|---|---|---|
svm_flower.py | Python脚本 | SVM分类主逻辑,加载数据、划分训练测试集、训练分类器、输出准确率 |
flower1.py | Python脚本 | 数据可视化辅助脚本,生成鸢尾花特征分布图、花瓣/花萼散点图 |
机器学习SVM作业报告.docx | Word文档 | 实验报告,包含实验目的、方法、ROC曲线分析和结论 |
flower.png | 图片 | 鸢尾花样本图示,可能用于报告封面 |
1_1.png / 1_2.png / 2_1.png / 2_2.png | 图片 | 训练过程产生的可视化输出,对应不同核函数或特征组合的图 |
1.png / 2_1.png / ROC.png | 图片 | 最终结果图,特别是ROC曲线图 |
LICENSE | 文本 | 开源协议文件,正常使用不受影响 |
flower1.py和svm_flower.py的分工非常清晰:一个管画图,一个管训练。这种拆分习惯很好,因为可视化代码和模型代码混在一个文件里,后期调参会非常痛苦——每次改一个C或gamma都要重新跑一遍画图逻辑,浪费时间不说,生成的图还会互相覆盖。资源里强化了这种分离,推荐保留。
2.2 搭建Python 3.9环境与安装依赖
报告中明确写的是“Python 3.9的IDLE作为编程环境”,也就是说这份源码不需要你在Linux服务器上折腾,本地Windows装个IDLE就能跑。不过IDLE的调试体验确实一般,我建议你直接用PyCharm或VS Code,但环境版本要严格对齐:
python --version # Python 3.9.x pip install numpy scikit-learn matplotlib这里有几个点需要说明。第一,sklearn的安装包名是scikit-learn,不是sklearn,直接pip install sklearn会在部分老版本pip上报错,这是新手最常见的翻车点。第二,版本不要贪新,比如scikit-learn1.2以上的版本对svm.SVC的默认参数有微调,但影响不大;真正要留意的是画图函数的中文字体问题,后面避坑章会讲。第三,如果你用的是Anaconda,直接pip install没问题,但别把conda install和pip install混用,容易把依赖搞乱。
装完依赖后,建议先跑flower1.py验证绘图环境,再跑svm_flower.py验证模型逻辑。不要一上来就两个文件连跑,因为绘图脚本里的plt.show()会阻塞线程,如果两张图没关掉,下一个脚本可能卡在内存里。血的教训。
3. 核心实现:从数据加载到SVM分类的完整流程
3.1 数据加载与预处理:为什么用鸢尾花而不是自己造数据
鸢尾花数据集一共150条样本,4个特征(花萼长宽、花瓣长宽),3个类别(Setosa、Versicolor、Virginica),每类50条。用SVM跑这个数据集的好处很明显:样本量小,训练快,特征维度低,可视化容易。而且它是sklearn内置数据集,加载时不需要额外下载文件,不会出现文件路径不对导致的FileNotFoundError。对于课程设计来说,这算是“来就打”的典型场景。
flower1.py里通常会做这样几件事:加载数据、把特征和标签分离、绘制散点图观察分布。核心逻辑类似:
from sklearn.datasets import load_iris import matplotlib.pyplot as plt iris = load_iris() X = iris.data # 150行4列的特征矩阵 y = iris.target # 150个标签,取值0/1/2 # 取前两个特征绘制散点图,观察线性可分性 plt.scatter(X[y == 0, 0], X[y == 0, 1], label='Setosa') plt.scatter(X[y == 1, 0], X[y == 1, 1], label='Versicolor') plt.scatter(X[y == 2, 0], X[y == 2, 1], label='Virginica') plt.xlabel('Sepal length') plt.ylabel('Sepal width') plt.legend() plt.savefig('flower.png', dpi=120) plt.show()注意这里我用了X[y == 0, 0]这种布尔索引,它的含义是:在所有样本中,选出标签为0的样本的第一列特征。这种写法比for循环快,而且更Pythonic。画图时选哪两个特征有讲究——鸢尾花数据里,花瓣长宽比花萼长宽的区分度更高,所以很多作业里会同时画两套散点图,一套看花萼,一套看花瓣,然后对比哪个特征组合让三类样本分得更开。这个观察会直接影响你在报告里写“为什么选择RBF核函数”的论据。
3.2 训练SVM分类器:svm_flower.py的骨架与参数说明
SVM的核心思想是找一个超平面,让不同类别的样本间隔最大化。鸢尾花是3分类问题,sklearn的svm.SVC默认采用“一对一”(one-vs-one)策略,也就是在每两个类别之间训练一个二分类器,最后投票决定样本归属。这套逻辑不需要你手动实现,但如果你在PPT答辩时能说清楚“为什么要用OVO而不是OVR”,教授会高看你一眼。
svm_flower.py的典型实现如下:
from sklearn import svm from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score, roc_curve, auc from sklearn.preprocessing import label_binarize import numpy as np from sklearn.datasets import load_iris iris = load_iris() X = iris.data y = iris.target # 按7:3划分训练集和测试集,随机种子固定,方便复现 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=42 ) # 使用RBF核函数,C和gamma先给默认值 clf = svm.SVC(kernel='rbf', C=1.0, gamma='scale', probability=True) clf.fit(X_train, y_train) y_pred = clf.predict(X_test) print("准确率:", accuracy_score(y_test, y_pred)) # 对标签做二值化,用于绘制多分类ROC曲线 y_bin = label_binarize(y_test, classes=[0, 1, 2]) y_score = clf.predict_proba(X_test) fpr = dict() tpr = dict() roc_auc = dict() for i in range(3): fpr[i], tpr[i], _ = roc_curve(y_bin[:, i], y_score[:, i]) roc_auc[i] = auc(fpr[i], tpr[i]) print("各类别AUC:", roc_auc)这段代码里有几个参数要重点解释。C是惩罚系数,代表对误分类的容忍度:C越大,模型越不愿意放过任何一个错分样本,容易过拟合;C越小,模型越平滑,但容易欠拟合。gamma是RBF核的宽度参数,gamma越大,每个样本的影响力越小,决策边界越复杂;gamma越小,边界越平缓。这里用的'scale'是sklearn 1.0之后推荐的默认值,它会根据特征数量自动计算一个合理的初始gamma,比自己拍脑袋填个0.1靠谱得多。probability=True必须开,因为后面画ROC曲线要调用predict_proba(),不开的话会AttributeError。
3.3 调参方向与网格搜索:别让作业止步于默认参数
很多同学跑完默认参数就交作业,准确率大概在0.93左右(随机种子42)。这个分数交课程设计够了,但如果你想在报告里写点“优化”的东西,建议做一次简单的网格搜索。常见做法是用GridSearchCV:
from sklearn.model_selection import GridSearchCV param_grid = { 'C': [0.1, 1, 10], 'gamma': ['scale', 0.01, 0.1], 'kernel': ['rbf'] } grid = GridSearchCV(svm.SVC(probability=True), param_grid, cv=5) grid.fit(X_train, y_train) print("最优参数:", grid.best_params_) print("最优交叉验证得分:", grid.best_score_)cv=5表示5折交叉验证,也就是把训练集再分成5份,轮流拿其中一份当验证集,其余当训练集,最后取平均分。这么做的意义是让参数选择不依赖某一次偶然的训练测试集划分。注意网格搜索跑完后,要用grid.best_estimator_重新在完整训练集上训练,再对测试集预测,否则你拿到的grid.score(X_test, y_test)只是最优模型在交叉验证下的平均水平,不是最终测试集得分。这一点在报告里写清楚,导师会觉得你真懂。
4. 避坑与常见问题:编译、画图和报告生成中的五个坑
4.1 现象:ImportError: No module named 'sklearn'
原因:Python环境里没有安装scikit-learn,或者你在IDLE里用的是系统Python,而pip装到了另一个Python环境下(比如Anaconda的base环境)。Windows上最常见的是安装了多个Python版本,IDLE默认打开的是C:\Python39,但你在cmd里用pip装的是C:\Users\XX\AppData\Local\Programs\Python\Python310。
解决:在IDLE里先执行import sys; print(sys.executable),看看当前解释器路径。然后打开cmd,用这个路径对应的pip安装,例如:
C:\Python39\python.exe -m pip install scikit-learn numpy matplotlib强制用解释器路径调用pip,避免装到别的环境里。
4.2 现象:运行plt.show()之后程序不往下走,也没有报错
原因:Matplotlib默认阻塞模式,show()会一直挂起直到你手动关掉所有图窗。如果你写完代码忘了添加plt.savefig(),图一多就卡在画图步骤。
解决:在每次plt.show()之前先plt.savefig('xxx.png', dpi=120),并且可以在代码里加上plt.close('all')释放内存。想改交互模式也可以写plt.ion(),但对作业来说不推荐,因为非阻塞模式下生成的图容易不完整。
4.3 现象:保存的图片中文显示为小方框
原因:Matplotlib默认字体不支持中文,报告里插入的图如果是“花瓣长度/宽度”这类带中文的标签,需要手动指定中文字体。
解决:在画图代码开头统一设置字体:
import matplotlib.pyplot as plt plt.rcParams['font.sans-serif'] = ['SimHei'] # Windows黑体 plt.rcParams['axes.unicode_minus'] = False # 解决负号显示异常如果你用的是macOS,把SimHei换成Arial Unicode MS;Linux下需要先安装中文字体包,否则还是方框。
4.4 现象:ROC曲线的横坐标从0到1,但曲线只有一段折线,不像教科书那种光滑曲线
原因:训练样本太少,或者你用的是线性核且数据线性不可分,导致ROC曲线上的点不够密。另一个常见原因是直接对多分类数据调用roc_curve,没做label_binarize,结果把三分类当二分类处理了。
解决:把probability=True打开,确保predict_proba输出的是列数为3的概率矩阵;用label_binarize对标签做二值化,然后对每个类别分别画一条ROC曲线,再取平均。样本少导致的锯齿形属于正常现象,报告里可以诚实说明“受样本量限制,ROC曲线呈阶梯状”。
4.5 现象:报告里的准确率和自己跑出来的不一致,差了0.3以上
原因:train_test_split没有设置random_state,每次运行随机划分都不一样;或者报告作者用的数据划分方式和你的不同。这是课程设计里最容易引发质疑的地方。
解决:在代码里固定随机种子:
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.3, random_state=42 )然后运行结果和报告对比。如果还是不一致,那就要看报告里是否用了全部数据训练、全部数据测试(过拟合)——很多老师给的模板报告里准确率偏高就是这么来的。你复现时保留自己的划分方式,在报告里注明“为保证可比性,固定random_state=42”,这就显专业。
5. 进阶技巧:把这份作业改造成你自己的实验报告与可视化
拿到一份能跑的源码只是第一步,真正让作业出彩的是你把它改造成“自己的东西”。这里给你三个最实用的进阶方向。
第一个方向是做特征对比实验。鸢尾花有4个特征,你可以分别用“花萼特征”“花瓣特征”“全部特征”训练三个SVM,在报告里放一张对比表格:哪个特征组合准确率最高,哪个组合画出来的决策边界最有区分度。这正好呼应flower1.py里画的散点图——如果你发现花瓣特征的两类样本重叠度低,那论文里就可以写“花瓣特征对Versicolor和Virginica的区分能力优于花萼特征”,这个结论有理有据。
第二个方向是核函数对比。把svm.SVC的kernel分别改成linear、poly、rbf,记录三个核函数下的准确率和训练时间。注意poly核需要额外调degree参数,比如svm.SVC(kernel='poly', degree=3)。报告里可以画一张三张ROC曲线的叠加图,三条线颜色不同,图例标明核函数名称,AUC值标在曲线上。这套图比单纯贴一个准分数有说服力得多。
第三个方向是验证模型的稳定性。用cross_val_score对最优模型做10次5折交叉验证,输出均值和标准差,比如“平均准确率0.956,标准差0.021”。标准差越小,说明模型越稳定,这也是答辩时老师喜欢问的“你怎么证明你的模型不是碰巧跑得好”。
我自己以前也用过这份作业源码,第一次跑的时候只顾着看准确率,没检查flower1.py生成的散点图——结果报告里就放了张所有点挤成一团的图,答辩时被问“这个特征的区分度体现在哪”,我当场语塞。从那以后我每次拿到别人的作业源码,都强制先跑一遍数据可视化部分,确认能出图画、能明显看出类别边界,再动模型参数。这份资源里的flower1.py和svm_flower.py正好拆开了这两步,希望你也能把这个习惯带走。希望帮到你。
本文还有配套的精品资源,点击获取