当前位置: 首页 > news >正文

保姆级教程:用Python+LIBSVM复现西瓜书SVM习题(附完整代码与数据集)

从理论到实践PythonLIBSVM实现西瓜书SVM习题全流程解析在机器学习领域支持向量机(SVM)一直以其优秀的分类性能和清晰的数学原理备受推崇。周志华教授的《机器学习》(西瓜书)作为国内经典教材其第六章对SVM的理论讲解深入浅出但许多学习者在将理论知识转化为代码实践时常常感到无从下手。本文将带你完整复现西瓜书第六章的关键习题使用Python和LIBSVM库在西瓜数据集3.0a上实现线性核与高斯核SVM的对比实验。1. 环境准备与工具安装工欲善其事必先利其器。在开始编码前我们需要配置好开发环境。推荐使用Python 3.7及以上版本这是目前机器学习领域最稳定且广泛支持的版本。首先安装必要的库pip install numpy matplotlib scikit-learn libsvm-official注意libsvm-official是LIBSVM的Python接口相比原始C版本更易于使用。验证安装是否成功import numpy as np import matplotlib.pyplot as plt from libsvm.svm import svm_parameter, svm_problem from libsvm.svmutil import svm_train, svm_predict print(所有库已成功导入)如果运行没有报错说明环境已准备就绪。接下来我们创建项目目录结构/svm_experiment /data # 存放数据集 /notebooks # Jupyter笔记本 /scripts # Python脚本 /results # 实验结果和图表2. 数据准备与预处理西瓜数据集3.0a是西瓜书中常用的示例数据集包含两个类别的西瓜样本每个样本有2个特征。我们将手动创建这个数据集确保与教材一致。# 西瓜数据集3.0a X np.array([ [0.697, 0.460], [0.774, 0.376], [0.634, 0.264], [0.608, 0.318], [0.556, 0.215], [0.403, 0.237], [0.481, 0.149], [0.437, 0.211], [0.666, 0.091], [0.243, 0.267], [0.245, 0.057], [0.343, 0.099], [0.639, 0.161], [0.657, 0.198], [0.360, 0.370], [0.593, 0.042], [0.719, 0.103] ]) y np.array([1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1])为了更好地理解数据我们先进行可视化plt.scatter(X[y1, 0], X[y1, 1], cr, label好瓜) plt.scatter(X[y-1, 0], X[y-1, 1], cb, label坏瓜) plt.xlabel(密度) plt.ylabel(含糖率) plt.legend() plt.title(西瓜数据集3.0a分布) plt.show()从散点图可以直观看出两类西瓜在特征空间中有一定的线性可分性但也存在部分重叠区域这为我们比较不同核函数的性能提供了很好的案例。3. 线性核SVM实现与解析线性核是SVM中最简单的核函数适用于近似线性可分的数据。我们先配置LIBSVM参数# 设置线性核参数 param_linear svm_parameter( -s 0 -t 0 -c 4 -b 1 # 分类任务线性核惩罚系数C4启用概率估计 )关键参数说明-s 0C-SVC分类器-t 0线性核-c 4惩罚系数控制分类边界的硬度-b 1启用概率估计训练模型并获取支持向量prob svm_problem(y, X) model_linear svm_train(prob, param_linear) # 获取支持向量 sv_indices model_linear.get_sv_indices() sv_coef model_linear.get_sv_coef() sv model_linear.get_SV() print(f找到 {len(sv_indices)} 个支持向量) print(支持向量索引:, sv_indices) print(支持向量系数:, sv_coef)可视化决策边界和支持向量# 创建网格点用于绘制决策边界 xx, yy np.meshgrid(np.linspace(0.2, 0.8, 500), np.linspace(0, 0.5, 500)) Z np.zeros(xx.shape) # 预测每个网格点的类别 for i in range(xx.shape[0]): for j in range(xx.shape[1]): Z[i,j] svm_predict([0], [[xx[i,j], yy[i,j]]], model_linear)[0][0] # 绘制结果 plt.contourf(xx, yy, Z, alpha0.2) plt.scatter(X[y1, 0], X[y1, 1], cr, label好瓜) plt.scatter(X[y-1, 0], X[y-1, 1], cb, label坏瓜) plt.scatter(X[sv_indices-1, 0], X[sv_indices-1, 1], s100, facecolorsnone, edgecolorsk, label支持向量) plt.xlabel(密度) plt.ylabel(含糖率) plt.legend() plt.title(线性核SVM决策边界) plt.show()线性核SVM在西瓜数据集上的表现相当不错能够找到合理的分界线将大部分样本正确分类。支持向量主要集中在两类样本的交界处这些关键样本决定了最终的决策边界。4. 高斯核SVM实现与对比分析高斯核(RBF核)能够处理更复杂的非线性分类问题。我们保持其他参数不变仅修改核函数类型param_rbf svm_parameter( -s 0 -t 2 -c 4 -g 0.5 -b 1 # 高斯核gamma0.5 )新增参数-t 2高斯核-g 0.5核函数参数gamma控制单个样本的影响范围训练高斯核模型model_rbf svm_train(prob, param_rbf) # 获取支持向量信息 sv_indices_rbf model_rbf.get_sv_indices() sv_coef_rbf model_rbf.get_sv_coef() sv_rbf model_rbf.get_SV() print(f高斯核找到 {len(sv_indices_rbf)} 个支持向量)可视化高斯核的决策边界# 预测网格点类别 Z_rbf np.zeros(xx.shape) for i in range(xx.shape[0]): for j in range(xx.shape[1]): Z_rbf[i,j] svm_predict([0], [[xx[i,j], yy[i,j]]], model_rbf)[0][0] # 绘制结果 plt.contourf(xx, yy, Z_rbf, alpha0.2) plt.scatter(X[y1, 0], X[y1, 1], cr, label好瓜) plt.scatter(X[y-1, 0], X[y-1, 1], cb, label坏瓜) plt.scatter(X[sv_indices_rbf-1, 0], X[sv_indices_rbf-1, 1], s100, facecolorsnone, edgecolorsk, label支持向量) plt.xlabel(密度) plt.ylabel(含糖率) plt.legend() plt.title(高斯核SVM决策边界) plt.show()高斯核SVM产生了更灵活的决策边界能够更好地拟合数据的分布。有趣的是在这个特定数据集上两种核函数找到的支持向量完全相同这与数据集的特性和参数选择有关。5. 模型评估与参数调优为了全面比较两种核函数的性能我们需要引入量化评估指标。首先定义评估函数def evaluate_model(model, X_test, y_test): p_label, p_acc, p_val svm_predict(y_test, X_test, model) return { accuracy: p_acc[0], precision: p_acc[2], recall: p_acc[3] }使用5折交叉验证比较模型from sklearn.model_selection import KFold kf KFold(n_splits5, shuffleTrue, random_state42) linear_scores [] rbf_scores [] for train_index, test_index in kf.split(X): X_train, X_test X[train_index], X[test_index] y_train, y_test y[train_index], y[test_index] # 训练线性模型 prob_train svm_problem(y_train, X_train) model_linear svm_train(prob_train, param_linear) linear_scores.append(evaluate_model(model_linear, X_test, y_test)) # 训练高斯核模型 model_rbf svm_train(prob_train, param_rbf) rbf_scores.append(evaluate_model(model_rbf, X_test, y_test)) # 计算平均得分 avg_linear {k: np.mean([s[k] for s in linear_scores]) for k in linear_scores[0]} avg_rbf {k: np.mean([s[k] for s in rbf_scores]) for k in rbf_scores[0]} print(线性核平均表现:, avg_linear) print(高斯核平均表现:, avg_rbf)参数调优是SVM应用中的关键步骤。我们可以使用网格搜索寻找最优的C和gamma参数from sklearn.model_selection import GridSearchCV from libsvm.svmutil import svm_train_validation # 定义参数网格 param_grid { C: [0.1, 1, 10, 100], gamma: [0.01, 0.1, 1, 10] } # 执行网格搜索 best_score 0 best_params {} for C in param_grid[C]: for gamma in param_grid[gamma]: param svm_parameter(f-s 0 -t 2 -c {C} -g {gamma} -v 5) # 5折交叉验证 current_score svm_train_validation(y, X, param) if current_score best_score: best_score current_score best_params {C: C, gamma: gamma} print(f最佳参数: {best_params}, 交叉验证准确率: {best_score}%)在实际项目中参数调优可能需要更精细的搜索范围和更复杂的验证策略但对于这个教学示例上述方法已经足够展示核心思路。6. 进阶探讨与扩展实验理解了基础实现后我们可以进一步探讨几个有趣的问题1. 支持向量数量与模型复杂度的关系通过调整惩罚参数C观察支持向量数量的变化C_values [0.01, 0.1, 1, 10, 100] sv_counts [] for C in C_values: param svm_parameter(f-s 0 -t 0 -c {C}) model svm_train(prob, param) sv_counts.append(len(model.get_sv_indices())) plt.plot(C_values, sv_counts, bo-) plt.xscale(log) plt.xlabel(惩罚参数C (log scale)) plt.ylabel(支持向量数量) plt.title(C参数与支持向量数量的关系) plt.show()2. 核函数选择对决策边界的影响比较不同gamma值下高斯核的表现gamma_values [0.01, 0.1, 1, 10] plt.figure(figsize(12, 8)) for i, gamma in enumerate(gamma_values): param svm_parameter(f-s 0 -t 2 -c 1 -g {gamma}) model svm_train(prob, param) # 预测网格点 Z np.zeros(xx.shape) for i_ in range(xx.shape[0]): for j in range(xx.shape[1]): Z[i_,j] svm_predict([0], [[xx[i_,j], yy[i_,j]]], model)[0][0] plt.subplot(2, 2, i1) plt.contourf(xx, yy, Z, alpha0.2) plt.scatter(X[:,0], X[:,1], c[r if label1 else b for label in y]) plt.title(fgamma{gamma}) plt.tight_layout() plt.show()3. 扩展到多分类问题虽然西瓜数据集是二分类问题但我们可以简单扩展代码处理多分类场景。LIBSVM原生支持一对多的多分类策略# 假设我们有一个三分类问题 y_multi np.array([0, 0, 1, 1, 2, 2]) # 示例标签 X_multi np.random.rand(6, 2) # 示例特征 param_multi svm_parameter(-s 0 -t 0) prob_multi svm_problem(y_multi, X_multi) model_multi svm_train(prob_multi, param_multi) # 预测时自动处理多分类 p_label, p_acc, p_val svm_predict(y_multi, X_multi, model_multi)
http://www.gsyq.cn/news/1413529.html

相关文章:

  • 8块8的24GHz微波感应模块,实测距离为啥只有10厘米?手把手教你排查和优化
  • Gemini正则与传统引擎的本质差异:基于LLM Tokenizer对齐的11项语法行为对比实验报告(附可复现Jupyter Notebook)
  • 告别烧钱试飞:手把手教你用AirSim+UE4.22.3搭建无人机视觉算法仿真环境(附避坑指南)
  • CentOS7网络配置踩坑实录:从nmcli命令报错到ifcfg文件修改,我都经历了什么
  • Armv8-A处理器中启用NEON与FPU的完整指南
  • 如何用LibreDWG彻底摆脱AutoCAD依赖?开源DWG处理终极指南
  • 终极化学AI助手:ChemCrow免费完整使用指南
  • 终极3D打印切片软件PrusaSlicer:从新手到专家的高效工作流指南
  • 告别定时器不准!STM32H743用TIM17精准驱动Canfestival的保姆级避坑指南
  • 深入解析Bambu Studio多语言本地化架构:5个关键技术实现方案
  • 如何一键安装BetterNCM:网易云音乐插件管理终极指南
  • 从雷赛伺服电机选型案例出发:如何把11.9倍的糟糕惯量比优化到5倍以内?
  • 别再让Flink Dashboard裸奔了!手把手教你复现CVE-2020-17518并加固(附Docker环境)
  • TimesFM动态协变量:技术深度解析与实践避坑指南
  • 2026年成都系统开发公司技术实力实测盘点:成都软件开发、四川APP开发、四川CRM开发、四川GEO优化、四川UI设计选择指南 - 优质品牌商家
  • 如何用通达信缠论插件ChanlunX实现智能技术分析:3分钟终极指南
  • 免费.brd文件查看器OpenBoardView:硬件工程师的终极开源解决方案
  • 2026年智能体技能框架解析:从核心原理到七大主流技术选型指南
  • Adafruit Playground扩展主板设计:从DB15接口到3D打印外壳的工程实践
  • Obsidian模板库:用Zettelkasten方法构建你的第二大脑
  • Poppins字体终极指南:免费开源的多语言几何字体解决方案
  • 贵阳黄金上门回收实评,福运来黄金回收高居榜首 - 黄金回收
  • ChemCrow:化学AI助手的完整使用指南与实战应用
  • 哪些行业目前最适合引入AI数字员工?实在Agent商业案例库助力企业高效完成数字化转型
  • Cadence SPB17.4新手必看:ORCAP-2434封装缺失警告的终极排查与修复指南
  • 衢州黄金上门回收,福运来黄金回收备受信赖之选 - 黄金回收
  • 一文讲透|盘点2026年遥遥领先的的降AIGC网站
  • 告别硬编码断言!基于Skills的接口测试,智能体自动组合请求与校验(附代码)
  • Lumafly:空洞骑士模组管理终极指南,告别繁琐的一键式解决方案
  • 学术写作效率突破!2026全流程AI论文软件深度解析