保姆级教程:用Python+LIBSVM复现《机器学习》西瓜数据集实验(附完整代码)
从理论到实践PythonLIBSVM实现西瓜数据集分类全流程解析在机器学习领域支持向量机(SVM)一直以其优秀的分类性能和清晰的数学原理备受推崇。但对于初学者来说从书本上的公式推导到实际代码实现往往存在一道难以跨越的鸿沟。本文将带领读者使用Python和LIBSVM工具包完整复现《机器学习》中的经典西瓜数据集分类实验通过对比线性核与高斯核的表现差异深入理解SVM的核心思想与应用技巧。1. 实验环境搭建与数据准备1.1 开发环境配置LIBSVM作为经典的SVM实现库可以通过多种方式安装。对于Python开发者最便捷的方式是使用pippip install -U libsvm-official为方便数据分析和可视化建议同时安装以下依赖库pip install numpy matplotlib openpyxl验证安装是否成功from libsvm.svmutil import * print(LIBSVM版本:, svm_version())1.2 数据集格式转换西瓜数据集3.0α包含17个样本每个样本有2个特征密度和含糖率和1个类别标签好瓜或坏瓜。LIBSVM要求数据格式为[类别标签] [特征编号1]:[特征值1] [特征编号2]:[特征值2]...假设原始数据存储在Excel中转换代码如下import openpyxl def excel_to_libsvm(input_path, output_path): wb openpyxl.load_workbook(input_path) sheet wb.active with open(output_path, w) as f: for row in sheet.iter_rows(min_row2, values_onlyTrue): label int(row[0]) features [f{i1}:{val} for i, val in enumerate(row[1:])] line f{label} { .join(features)}\n f.write(line) excel_to_libsvm(watermelon3.0.xlsx, watermelon.libsvm)转换后的数据示例如下1 1:0.697 2:0.46 1 1:0.774 2:0.376 0 1:0.666 2:0.0912. SVM模型训练与评估2.1 数据加载与基本训练LIBSVM提供了简洁的API接口首先加载转换后的数据from libsvm.svmutil import * # 加载数据 y, x svm_read_problem(watermelon.libsvm) # 线性核训练 linear_model svm_train(y, x, -t 0 -c 1) p_label, p_acc, p_val svm_predict(y, x, linear_model)关键参数说明-t 0指定线性核函数-c 1设置惩罚系数C的初始值2.2 高斯核(RBF)训练# 高斯核训练 rbf_model svm_train(y, x, -t 2 -c 1 -g 0.5) p_label, p_acc, p_val svm_predict(y, x, rbf_model)新增参数-t 2指定高斯核函数-g 0.5设置高斯核的γ参数3. 结果可视化与分析3.1 决策边界绘制可视化是理解模型行为的重要手段以下是绘制决策边界的代码import numpy as np import matplotlib.pyplot as plt def plot_decision_boundary(model, x, y, title): # 生成网格点 x_min, x_max min(i[1] for i in x)-0.1, max(i[1] for i in x)0.1 y_min, y_max min(i[2] for i in x)-0.1, max(i[2] for i in x)0.1 xx, yy np.meshgrid(np.linspace(x_min, x_max, 500), np.linspace(y_min, y_max, 500)) # 预测网格点类别 grid_points np.c_[xx.ravel(), yy.ravel()] grid_labels np.zeros(len(grid_points)) grid_data [dict(enumerate(row, 1)) for row in grid_points] p_label, _, _ svm_predict(grid_labels, grid_data, model) # 绘制结果 plt.figure(figsize(10, 6)) plt.contourf(xx, yy, np.array(p_label).reshape(xx.shape), alpha0.3) plt.scatter([i[1] for i in x], [i[2] for i in x], cy, edgecolorsk) plt.xlabel(密度) plt.ylabel(含糖率) plt.title(title) plt.show() plot_decision_boundary(linear_model, x, y, 线性核决策边界) plot_decision_boundary(rbf_model, x, y, 高斯核决策边界)3.2 性能对比分析通过调整参数我们得到以下对比结果核函数参数设置训练准确率支持向量数量线性核C182.35%7线性核C10082.35%5高斯核C1, γ0.582.35%9高斯核C10000, γ10100%17从结果可以看出线性核在原始特征空间中难以完美分类高斯核通过特征变换实现了完全分类增大C值会减少分类错误但可能导致过拟合4. 参数调优与模型选择4.1 交叉验证调参LIBSVM内置了交叉验证功能可用于参数优化# 寻找最佳C和γ best_c, best_g, best_rate 0, 0, 0 for c in [0.1, 1, 10, 100, 1000]: for g in [0.001, 0.01, 0.1, 1, 10]: rate svm_train(y, x, f-t 2 -v 5 -c {c} -g {g}) if rate best_rate: best_c, best_g, best_rate c, g, rate print(f最佳参数: C{best_c}, γ{best_g}, 准确率{best_rate}%)4.2 不同核函数的适用场景线性核特征数量多、样本量适中、线性可分或近似线性可分优点计算快、不易过拟合缺点无法处理复杂非线性关系高斯核样本量不大、特征数量少、非线性可分优点强大的非线性建模能力缺点需要调参、计算复杂度高在实际项目中建议先尝试线性核如果效果不佳再考虑非线性核。对于文本分类等特征维度很高的问题线性核通常已经足够。5. 进阶技巧与常见问题5.1 类别不平衡处理当正负样本比例失衡时可以通过设置类别权重来改善模型表现# 设置类别权重 weight_param -w1 2 -w0 1 # 正样本权重为2 model svm_train(y, x, f-t 0 -c 1 {weight_param})5.2 模型保存与加载训练好的模型可以保存到文件供后续使用# 保存模型 svm_save_model(watermelon.model, model) # 加载模型 loaded_model svm_load_model(watermelon.model)5.3 常见错误排查数据格式错误确保特征编号从1开始连续编号内存不足对于大数据集减小缓存大小-m参数收敛问题调整终止容差-e参数在完成这个实验的过程中我发现高斯核虽然在这个小数据集上表现完美但在实际项目中需要警惕过拟合风险。一个实用的技巧是在调参时保留部分验证集避免仅依赖训练集准确率做决策。