首页 短视频

从线性到非线性:用 Python 玩转支持向量机 SVM

分类:短视频
字数: (2219)
阅读: (4846)
内容摘要:从线性到非线性:用 Python 玩转支持向量机 SVM,

在机器学习的世界里,支持向量机(SVM)是一个非常强大的算法,尤其擅长处理高维数据和非线性分类问题。本文将结合吴恩达机器学习笔记(10)的内容,深入剖析 SVM 的底层原理,并结合实际案例,分享我在项目中使用 SVM 解决问题的经验,以及一些常见的坑。

SVM 的核心思想:寻找最优分割超平面

SVM 的核心思想在于找到一个最优的分割超平面,能够最大程度地将不同类别的数据点分隔开来。这个超平面需要满足两个关键条件:

  1. 最大化间隔(Margin Maximization):超平面与距离它最近的两个类别的数据点之间的距离(margin)要尽可能大。这能够提高模型的泛化能力,使其在面对新的、未见过的数据时也能有较好的表现。
  2. 正确分类:尽可能正确地将所有数据点划分到对应的类别中。

线性可分的情况:硬间隔 SVM

当数据是线性可分的,我们可以找到一个超平面完美地将数据分隔开。这种情况下,我们追求的是“硬间隔”,即不允许任何数据点落入 margin 内部。这时的优化目标可以表示为:

从线性到非线性:用 Python 玩转支持向量机 SVM
minimize  ||w||^2 / 2
subject to  y_i(w^T x_i + b) >= 1  for all i

其中,w 是超平面的法向量,b 是截距,x_i 是数据点,y_i 是数据点的标签(+1 或 -1)。

线性不可分的情况:软间隔 SVM

现实世界的数据往往不是完美线性可分的。为了处理这种情况,SVM 引入了“软间隔”的概念,允许一些数据点落入 margin 内部,甚至被错误分类。这时,优化目标需要加入一个惩罚项,用于惩罚那些违反 margin 约束的数据点:

从线性到非线性:用 Python 玩转支持向量机 SVM
minimize  ||w||^2 / 2 + C * sum(xi_i)
subject to  y_i(w^T x_i + b) >= 1 - xi_i  for all i
             xi_i >= 0  for all i

其中,C 是惩罚系数,xi_i 是松弛变量,表示数据点 x_i 违反 margin 约束的程度。C 值越大,表示对错误分类的容忍度越低,模型会更加努力地去正确分类所有数据点,但也可能导致过拟合。

核函数:将数据映射到高维空间

对于非线性可分的数据,SVM 的一个重要技巧是使用核函数(Kernel Function)将数据映射到高维空间,使得数据在高维空间中变得线性可分。常用的核函数包括:

从线性到非线性:用 Python 玩转支持向量机 SVM
  • 线性核(Linear Kernel)K(x, x') = x^T x'
  • 多项式核(Polynomial Kernel)K(x, x') = (x^T x' + r)^d
  • 径向基函数核(RBF Kernel)K(x, x') = exp(-||x - x'||^2 / (2 * sigma^2))

RBF 核是 SVM 中最常用的核函数之一,因为它具有很强的灵活性,能够处理各种复杂的非线性关系。但是,RBF 核也有一些缺点,例如需要调整两个参数:Cgamma(gamma = 1 / (2 * sigma^2))。不合适的参数设置可能导致过拟合或欠拟合。

Python 实战:使用 scikit-learn 构建 SVM 模型

下面是一个使用 scikit-learn 构建 SVM 模型的 Python 代码示例:

从线性到非线性:用 Python 玩转支持向量机 SVM
from sklearn import svm
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import numpy as np

# 1. 准备数据
X = np.array([[1, 2], [2, 3], [3, 3], [2, 1], [3, 2]])  # 特征数据
y = np.array([0, 0, 0, 1, 1])  # 标签数据 (0 和 1)

# 2. 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# 3. 创建 SVM 模型(使用 RBF 核)
clf = svm.SVC(kernel='rbf', C=1, gamma='scale') # gamma='scale' 是一个建议的默认值

# 4. 训练模型
clf.fit(X_train, y_train)

# 5. 预测
y_pred = clf.predict(X_test)

# 6. 评估模型
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy}')

# 7. 预测新数据
new_data = np.array([[2.5, 2.5]])
prediction = clf.predict(new_data)
print(f'Prediction for new data: {prediction}')

代码解释:

  1. 导入必要的库:svm 用于创建 SVM 模型,train_test_split 用于划分数据集,accuracy_score 用于评估模型。
  2. 准备数据:X 是特征数据,y 是标签数据。这里使用了简单的二维数据作为示例。
  3. 划分数据集:将数据划分为训练集和测试集,用于训练和评估模型。
  4. 创建 SVM 模型:使用 svm.SVC() 创建 SVM 模型,kernel 参数指定核函数(这里使用 RBF 核),C 参数指定惩罚系数,gamma 参数指定 RBF 核的 gamma 值。gamma='scale' 建议从scikit-learn 0.22 开始使用, 它使用 1 / (n_features * X.var()) 作为gamma 的值,这样通常会获得更好的结果。
  5. 训练模型:使用 fit() 方法训练模型。
  6. 预测:使用 predict() 方法对测试集进行预测。
  7. 评估模型:使用 accuracy_score() 函数计算模型的准确率。
  8. 预测新数据:使用 predict() 方法对新的数据点进行预测。

实战避坑:SVM 参数调优与数据预处理

在使用 SVM 时,参数调优和数据预处理是非常重要的环节,它们直接影响模型的性能。

参数调优

  • 选择合适的核函数:不同的核函数适用于不同的数据。如果数据是线性可分的,可以使用线性核。如果数据是非线性可分的,可以尝试 RBF 核或多项式核。通常 RBF 核效果不错,但是要仔细调参数。
  • 调整 C 和 gammaCgamma 是 RBF 核的两个重要参数。可以使用网格搜索(Grid Search)或交叉验证(Cross-Validation)来找到最佳的参数组合。我通常用 GridSearchCV 配合交叉验证来寻找最优参数组合。GridSearchCV 可以自动遍历所有可能的参数组合,并选择性能最佳的组合。此外,还可以考虑使用贝叶斯优化等更高级的优化方法。
  • 考虑使用 PCA 降维:当特征维度很高时,SVM 的训练速度会非常慢。可以使用 PCA 等降维方法来降低特征维度,提高训练速度。当然降维也可能损失信息,需要权衡。

数据预处理

  • 特征缩放:SVM 对特征的尺度非常敏感。如果特征的尺度差异很大,可能会导致模型性能下降。可以使用标准化(StandardScaler)或归一化(MinMaxScaler)等方法对特征进行缩放。标准化将特征缩放到均值为 0,方差为 1,归一化将特征缩放到 0 到 1 之间。选择哪种方法取决于数据的分布情况。
  • 处理缺失值:SVM 不能直接处理缺失值。需要先对缺失值进行处理,例如填充缺失值或删除包含缺失值的样本。常用的填充方法包括使用均值、中位数或众数填充缺失值。更复杂的方法包括使用 KNN 算法预测缺失值。
  • 处理类别不平衡:如果不同类别的样本数量差异很大,可能会导致模型偏向于样本数量较多的类别。可以使用过采样(Oversampling)或欠采样(Undersampling)等方法来平衡不同类别的样本数量。例如,可以使用 SMOTE 算法生成新的少数类样本,或者随机删除一些多数类样本。

总结

支持向量机是一个强大且灵活的机器学习算法,通过吴恩达机器学习笔记(10)的学习,我们掌握了其基本原理。在实际应用中,需要根据具体问题选择合适的核函数,并进行参数调优和数据预处理。希望本文能够帮助你更好地理解和使用 SVM。

从线性到非线性:用 Python 玩转支持向量机 SVM

转载请注明出处: 半杯凉茶

本文的链接地址: http://m.acea4.store/blog/700104.SHTML

本文最后 发布于2026-04-23 22:41:02,已经过了3天没有更新,若内容或图片 失效,请留言反馈

()
您可能对以下文章感兴趣
评论
  • 格子衫青年 1 天前
    请问一下,如果我的数据量很大,比如几百万条,用 SVM 还能行吗?会不会太慢了?
  • 单身狗 4 天前
    收藏了!感谢分享。之前用 SVM 总是调不好参数,看了你的避坑经验,感觉很有帮助。尤其是 C 和 gamma 的调整,之前一直没搞明白。
  • 海王本王 4 天前
    收藏了!感谢分享。之前用 SVM 总是调不好参数,看了你的避坑经验,感觉很有帮助。尤其是 C 和 gamma 的调整,之前一直没搞明白。
  • 番茄炒蛋 8 小时前
    写得真好!SVM 的原理讲得很清楚,代码示例也很实用。最近在做一个文本分类的项目,正愁不知道该用什么算法,看了这篇文章感觉 SVM 是个不错的选择。
  • 咕咕咕 4 天前
    感觉作者对 SVM 理解很深刻啊,不过核函数的选择还是得根据实际情况来,没有哪个核函数是万能的。