拓冰建站拓冰建站
首页 / 资讯中心 / 正文

SVM分类Iris数据集的Python实现:从原理到网格调参实战

简介面向机器学习初学者的SVM分类作业资源包基于Python 3.9与IDLE环境借助sklearn、numpy等常用库对经典Iris鸢尾花数据集完成支持向量机建模与实验分析。压缩包共16个文件以PY源码、DOCX实验报告、PNG结果图表为主辅以XML项目配置等文本整体体积仅611KB结构清晰便于对照学习或二次修改。资源内含两个Python脚本分别承担通用流程与SVM专属模型实现并配套完整实验报告文档报告中梳理了数据加载、特征处理、模型训练、参数分析与ROC曲线绘制等关键环节同时提供多张实验截图可直观还原分类效果与评估结果。读者按脚本注释即可复现鸢尾花分类任务适合用于机器学习课程作业、期末设计或自学SVM的入门对照。目前已有990人学习下载内容轻量且覆盖从原理到代码实现的主要路径具有较好的参考价值。1. 拿着Iris交SVM作业最常见的翻车点不在代码很多同学拿到“Python机器学习SVM作业源码实验报告”这个需求时第一步是去CSDN或GitHub找一份跑得通的代码fit完打印一个准确率截图贴进Word实验报告里写三段“模型表现良好”。但这样的作业通常在答辩或查重时暴露出问题为什么选SVM而不是逻辑回归C参数调大决策边界会怎样变化RBF核的gamma取0.1和10的区别在哪里这些问题当面一问代码是不是自己写的立刻暴露。这篇文章从SVM的分类原理讲到Iris数据集上的完整实现再落到网格调参、决策边界可视化和实验报告的数据组织方式目标是让你从“能跑”走到“能讲”。适合正在赶机器学习课程作业、以及想把手头分类任务从demo级别提升到可用级别的人。2. SVM分类Iris的原理间隔、支持向量与核函数选择2.1 为什么Iris是SVM入门的标准数据集Iris鸢尾花数据集共150条样本4个特征分别是花萼长度、花萼宽度、花瓣长度、花瓣宽度标签是Setosa、Versicolor、Virginica三个品种每个品种50条。这个数据集有个非常讨巧的特性其中Setosa与另外两类几乎线性可分而Versicolor与Virginica的特征分布存在明显重叠。这意味着同一个数据集里你既能观察到线性SVM的干净边界又能看到当类间重叠时模型如何通过软间隔和核函数妥协。从机器学习的角度看Iris样本量小、特征量纲接近、无缺失值几乎不需要做特征工程就能直接套用模型。但这恰恰也是它的陷阱因为预处理太顺很多人在学SVM时根本没意识到“特征缩放”这件事。SVM依赖距离度量如果特征的数值范围差出几个数量级间隔计算会被大数值特征主导。Iris的4个特征都集中在0到8之间所以即使不做标准化结果也不会差太多但真实数据集不会这么配合。2.2 间隔最大化的本质是让模型更稳SVM做分类时要找的超平面可以写成 w·x b 0其中w是法向量b是偏置。对于二分类问题落在超平面两侧的样本分别被预测为正类和负类但SVM不满足于“能分开”它要求间隔最大。任何超平面y坐标方向上的偏移都会让部分点离决策边界过近一旦测试数据带上噪声这些点就会越过边界被分错。最大间隔的本质是给模型预留一个缓冲带让分类器对数据扰动更鲁棒。间隔的几何意义是两类支持向量之间的垂直距离大小为 2/‖w‖。最大化间隔等价于最小化 ‖w‖²/2这是一个带线性约束的凸二次规划问题可以用拉格朗日乘子法转成对偶形式求解。这里不需要推导到很深的程度但作业里被问“为什么叫支持向量机”你要能说清楚一句话最终的决策函数只由距离超平面最近的那几个样本决定那些样本就是支持向量其他样本的梯度贡献为零。这也是SVM的一大优势模型只需要记住支持向量而不是全部训练数据。2.3 软间隔与正则化参数CIris里Versicolor和Virginica存在重叠强行用硬间隔找一个能把所有训练样本都分对的超平面几乎不可能即使能也会非常曲折。此时引入软间隔允许部分样本犯错。原始的优化目标从“所有样本都要在间隔之外”放宽为“尽量在间隔内允许少量越界”并在目标函数里加上惩罚项于是约束条件变成加上松弛变量ξ的版本目标函数变为minimize (1/2)‖w‖² C·Σξ_i这里的C就是正则化参数。C越大对错分样本的惩罚越大模型会拼命把训练样本分正确结果趋近于硬间隔更容易过拟合C越小对错误的容忍度越高间隔可以更宽但可能欠拟合。在Iris上C从0.01到100扫一圈你会发现边界从“宽松而平滑”逐渐变成“紧贴样本点”这就是SVM调参里最直观的感受。2.4 核函数线性不可分时怎么处理软间隔解决的是“虽然有噪声但大致线性可分”的问题如果两类数据在原始空间里纠缠成一团线性超平面再怎么放宽也分不开。核函数的思路是把样本隐式映射到高维空间在高维空间里做线性分类再映射回来时原始空间的决策边界就变成了曲线。sklearn的SVC支持四种核函数它们的适用场景差别很大核函数决策边界形态适合的场景关键参数linear直线/平面特征多、样本量适中基本线性可分Cpoly多项式曲线有先验的多项式关系边界较平滑degree, Crbf任意弯曲边界最常用默认选择能拟合复杂边界C, gammasigmoid类神经网络曲线实际效果依赖参数不推荐优先使用C, gammaRBF核的表达式是 exp(-gamma·‖x-x‖²)gamma控制单个训练样本的影响半径。gamma越小影响半径越大决策边界越平滑欠拟合风险高gamma越大每个样本只影响自己附近的一小片区域边界越曲折过拟合风险高。Iris数据在linear和rbf上都能得到不错结果区别体现在Versicolor和Virginica的重叠区域怎么切分。3. 用Python实现Iris的SVM分类最小可运行代码3.1 环境依赖与数据加载做这个作业不需要搭集群一台普通笔记本加三个库就够了scikit-learn提供SVC模型和数据集pandas做数据观察matplotlib画图。版本上sklearn 1.0以上即可Python 3.8以上都兼容。from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split from sklearn.svm import SVC from sklearn.metrics import accuracy_score, classification_report, confusion_matrix iris load_iris() X iris.data # 特征矩阵形状 (150, 4) y iris.target # 标签向量0/1/2 分别对应三种鸢尾花 print(特征名称:, iris.feature_names) print(类别名称:, iris.target_names) print(数据形状:, X.shape)这里用load_iris直接拿数据不需要自己下载文件。X是150行4列的浮点数组y是0到2的整数标签。注意sklearn的SVC对输入格式要求是二维数组X不能写成Seriesy可以是一维数组。3.2 训练集测试集划分原始数据不能既训练又评估否则会得到一个虚高的准确率。常见做法是以7:3比例拆成训练集和测试集并用stratify参数按类别比例分层抽样保证训练集和测试集里三种花的比例与原数据集一致。X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.3, random_state42, stratifyy ) print(训练集样本数:, X_train.shape[0]) print(测试集样本数:, X_test.shape[0])test_size0.3表示留出30%做测试在150条样本下就是45条。random_state固定随机种子让实验可复现交作业时写上种子值老师重新跑也能得到相同结果。stratifyy这一行是和随机拆分最容易被忽略的区别不写的话小数据集上某一类可能全部落在训练集里导致测试集完全分不对这一类。3.3 训练线性SVM并评估Iris的前两类与第三类的可分性差异很大先从线性核开始得到一组基线指标再去对比RBF是否真的更优。model SVC(kernellinear, C1.0) model.fit(X_train, y_train) y_pred model.predict(X_test) print(准确率:, accuracy_score(y_test, y_pred)) print(\n分类报告:\n, classification_report(y_test, y_pred, target_namesiris.target_names)) print(混淆矩阵:\n, confusion_matrix(y_test, y_pred))fit函数在内部求解二次规划问题Iris只有105条训练样本几乎瞬间完成。C1.0是sklearn的默认值对线性核来说Iris上这个默认值表现已经不错。classification_report给出每个类别的precision、recall和F1值比只看准确率更能定位是哪一类在混淆。confusion_matrix的每一行代表真实类别每一列代表预测类别对角线越集中说明分类越准。如果直接跑上面的代码准确率通常在0.93到1.0之间波动。random_state固定为42后线性核几乎不会分错样本。3.4 RBF核与参数初探把kernel换成rbf再设置一个固定的gamma看看和线性核的差异。model_rbf SVC(kernelrbf, C1.0, gamma0.5) model_rbf.fit(X_train, y_train) y_pred_rbf model_rbf.predict(X_test) print(RBF核准确率:, accuracy_score(y_test, y_pred_rbf)) print(支持向量数量:, len(model_rbf.support_vectors_))gamma0.5意味着单个样本的影响半径在特征值范围0到8里大约覆盖一个中等区域。支持向量数量能直接从侧面反映模型复杂度线性核在Iris上支持向量通常只有二十个左右RBF核在同样的C下会略多一些。如果gamma开得很大支持向量数量会明显上升模型开始“记住”训练点这是过拟合的前兆。4. 调参与边界可视化把网格搜索和matplotlib做成报告素材4.1 用pandas观察特征分布训练模型之前先看看哪些特征对分类最有帮助。花萼和花瓣的长度、宽度它们的分布范围不同有些特征在三个类别之间重叠严重有些则几乎完全分开。import pandas as pd df pd.DataFrame( iris.data, columnsiris.feature_names ) df[species] iris.target_names[iris.target] print(df.groupby(species).describe().T)pandas的groupbydescribe会一次性输出每个类别下每个特征的均值、标准差、最小值和四分位数。以Iris为例petal length和petal width在Setosa和另两类之间几乎没有重叠而sepal width在三个类别上分布交叉非常严重。这说明只靠花萼宽度做分类会很差也解释了为什么作业里有人取单一特征训练时准确率只有七成。4.2 GridSearchCV交叉验证找最优参数手动一个个试C和gamma不是不行但参数之间有交互作用C调大后gamma的合适区间会变。用GridSearchCV做5折交叉验证把两个参数一起搜索结果更可靠。from sklearn.model_selection import GridSearchCV param_grid { C: [0.1, 1, 10, 100], gamma: [0.01, 0.1, 1, 10], kernel: [rbf] } grid GridSearchCV( SVC(), param_grid, cv5, scoringaccuracy, n_jobs-1 ) grid.fit(X_train, y_train) print(最优参数:, grid.best_params_) print(交叉验证最优准确率:, grid.best_score_) print(测试集准确率:, accuracy_score(y_test, grid.best_estimator_.predict(X_test))) results pd.DataFrame(grid.cv_results_)[[params, mean_test_score, rank_test_score]] print(results.sort_values(rank_test_score).head(5))cv5表示把训练数据切成5份轮流拿4份训练、1份验证一共跑5轮把5次准确率平均。它能避免一次划分运气太好或太坏造成的误判。n_jobs-1表示用所有CPU核并行16个参数组合乘5折共80次训练在Iris上十几秒就能结束。输出里的mean_test_score是交叉验证均值和测试集准确率是两个概念前者只用于选参数后者才是报告里该写的最终指标。grid.cv_results_里包含每组参数对应的详细得分把它转成DataFrame排序后可以直接贴进实验报告作为调参过程记录。4.3 绘制SVM决策边界并保存图片完整4维特征没法画二维图常见做法是取前两个特征做可视化示意并在报告里注明“图中只展示部分维度”。下面的代码用颜色填充区域表示分类结果边界线两侧就是SVM决策区域。import numpy as np import matplotlib.pyplot as plt # 只用花萼长度和花萼宽度做可视化 X_vis X_train[:, :2] y_vis y_train model_vis SVC(kernelrbf, C1.0, gamma0.5) model_vis.fit(X_vis, y_vis) # 生成网格点覆盖训练数据分布范围并向外扩0.5 x_min, x_max X_vis[:, 0].min() - 0.5, X_vis[:, 0].max() 0.5 y_min, y_max X_vis[:, 1].min() - 0.5, X_vis[:, 1].max() 0.5 xx, yy np.meshgrid( np.linspace(x_min, x_max, 300), np.linspace(y_min, y_max, 300) ) Z model_vis.predict(np.c_[xx.ravel(), yy.ravel()]) Z Z.reshape(xx.shape) plt.contourf(xx, yy, Z, alpha0.4, cmapplt.cm.RdYlBu) plt.scatter( X_vis[:, 0], X_vis[:, 1], cy_vis, edgecolorsk, cmapplt.cm.RdYlBu ) plt.xlabel(sepal length (cm)) plt.ylabel(sepal width (cm)) plt.colorbar() # 圈出支持向量 plt.scatter( model_vis.support_vectors_[:, 0], model_vis.support_vectors_[:, 1], s100, facecolorsnone, edgecolorsk, labelsupport vectors ) plt.legend() plt.savefig(svm_decision_boundary.png, dpi150, bbox_inchestight) plt.show()np.meshgrid生成一个300×300的坐标网格np.c_把网格坐标拼成两列交给predict一次性预测。contourf填充每个网格点的预测类别颜色分界处就是决策边界。支持向量用空心圆画在图上你能直接看到它们贴着边界分布这比任何文字解释都有说服力实验报告里放这张图比表格更占视觉优势。from sklearn.preprocessing import StandardScaler scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test)这段代码是给第5章做铺垫的但在第4章里值得先看一眼标准化在真实数据集上往往是必要的Iris不标准化也能跑但加上这一步之后RBF核的gamma搜索范围可以缩小不会因为某个特征数值范围过大扭曲距离。5. 实验报告怎么写结果表格、验证方法与常见坑5.1 报告里的结果表格怎么组织SVM作业的实验报告核心是回答三个问题选了哪些参数、为什么这么选、结果说明什么。参数搜索过程建议直接用GridSearchCV的输出整理成表下面是个可直接使用的模板结构核函数Cgamma5折交叉验证准确率测试集准确率linear1.0-0.9810.978rbf1.00.50.9620.956rbf100.10.9900.978rbf100100.9520.933表格里很容易看出一个规律C过大或gamma过大时交叉验证分数和测试集分数同时下降这就是过拟合的定量证据。报告里不要只放最后一行把搜索过程放出来老师能直接看到你的调参逻辑。支持向量数量的变化也值得写进去C越大支持向量越少边界越激进这个观察能体现你对SVM几何意义的理解。5.2 三个容易被追问的验证细节第一个是特征缩放。Iris不做标准化和做了标准化准确率可能都差不多但报告里主动写清楚“本数据集量纲接近未标准化对结果影响有限实际项目中应先做StandardScaler”这句话能让答辩老师知道你不是漏了而是判断过。第二个是交叉验证与测试集分离。GridSearchCV在训练集内部做验证选出最优参数后再用根本没参与训练的测试集做最终评估。如果直接用全部数据搜索参数再把同一批数据跑准确率得到的是过拟合的虚高数字这个错误实习生常犯。第三个是核函数的性能对比。不要只报RBF的准确率把linear、rbf各跑一遍放在同一张表里。Iris上空RBF往往并不比linear强多少这份“负结果”反而是好的讨论素材说明数据本身的可分性让核函数没有发挥空间也能引出“核函数不是越复杂越好”的结论。5.3 把Iris代码移植到其他数据集的检查清单从Iris作业迁移到自己的数据最怕的是直接换load数据就fit。写作业时顺手做一个检查清单将来能直接复用。第一看特征量纲用StandardScaler做标准化这个不能省。第二确认标签是整数编码SVC不认字符串要用sklearn的LabelEncoder转换。第三检查类别是否不平衡如果某一类只占5%准确率会被多数类主导需要打开SVC的class_weight参数。第四中等规模数据上GridSearchCV的param_grid可以先用粗粒度扫一遍定位参数量级后再细化不必一开始就上小数点后三位的精确值。把这个清单附在实验报告末尾整篇作业的完成度会明显高一个档次。本文还有配套的精品资源点击获取
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门