支持向量机SVM在Python中的实践应用

发布于:2025-07-12 ⋅ 阅读:(16) ⋅ 点赞:(0)

一、支持向量机基础理论

1. 基本概念与原理

支持向量机(Support Vector Machine,SVM)是一种基于统计学习理论的监督学习算法,旨在寻找一个最优的超平面来对数据进行分类。对于线性可分的数据,SVM通过最大化两类数据之间的间隔来确定这个超平面。具体来说,它寻找一个超平面,使得距离该超平面最近的数据点(即支持向量)到超平面的距离最大。

数学上,假设有一个训练数据集{(xi,yi)}i=1n\{(x_i, y_i)\}_{i=1}^{n}{(xi,yi)}i=1n,其中xix_ixi是输入特征向量,yi∈{−1,1}y_i \in \{-1, 1\}yi{1,1}是类别标签。对于线性SVM,需要找到一个超平面w⋅x+b=0w \cdot x + b = 0wx+b=0,满足以下条件:

  • 对于所有yi=1y_i = 1yi=1的样本,有w⋅xi+b≥1w \cdot x_i + b \geq 1wxi+b1
  • 对于所有yi=−1y_i = -1yi=1的样本,有w⋅xi+b≤−1w \cdot x_i + b \leq -1wxi+b1

同时,要最大化间隔2∥w∥\frac{2}{\|w\|}w2,这等价于最小化∥w∥2\|w\|^2w2。通过拉格朗日乘数法可以将其转化为一个凸二次规划问题求解。

2. 核函数的作用

当数据在原始空间中线性不可分时,SVM通过核函数(Kernel Function)将数据映射到高维特征空间,使其变得线性可分。核函数的基本思想是在高维空间中计算内积,而不需要显式地进行维度转换,从而避免了维度灾难。

常见的核函数包括:

  • 线性核(Linear Kernel)K(x,z)=x⋅zK(x, z) = x \cdot zK(x,z)=xz,适用于线性可分的数据。
  • 多项式核(Polynomial Kernel)K(x,z)=(αx⋅z+c)dK(x, z) = (\alpha x \cdot z + c)^dK(x,z)=(αxz+c)d,可以将数据映射到多项式特征空间。
  • 高斯核(Gaussian Kernel)K(x,z)=exp⁡(−∥x−z∥22σ2)K(x, z) = \exp(-\frac{\|x - z\|^2}{2\sigma^2})K(x,z)=exp(2σ2xz2),也称为径向基函数(RBF),是一种常用的非线性核函数,能够处理复杂的非线性关系。

选择合适的核函数对于SVM的性能至关重要,不同的核函数适用于不同类型的数据和问题。

二、Python中的支持向量机实现

1. 使用Scikit-Learn库

Scikit-Learn是一个广泛使用的Python机器学习库,提供了简单易用的SVM实现。以下是使用Scikit-Learn实现SVM的基本步骤:

from sklearn import datasets
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.metrics import classification_report, accuracy_score

# 加载示例数据集(以鸢尾花数据集为例)
iris = datasets.load_iris()
X = iris.data
y = iris.target

# 只选取前两类数据进行二分类任务
X = X[y != 2]
y = y[y != 2]

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

# 特征标准化
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

# 创建SVM模型(使用线性核)
svm_model = SVC(kernel='linear', C=1.0)

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

# 在测试集上进行预测
y_pred = svm_model.predict(X_test)

# 评估模型性能
print("Accuracy:", accuracy_score(y_test, y_pred))
print(classification_report(y_test, y_pred))

在上述代码中,首先加载了鸢尾花数据集,并选取了前两类数据进行二分类任务。然后,将数据集划分为训练集和测试集,并对特征进行了标准化处理。接着,创建了一个使用线性核的SVM模型,并在训练集上进行了训练。在测试集上进行了预测,并评估了模型的性能。

2. 参数调整与优化

SVM模型的性能受到多个参数的影响,其中最重要的参数是正则化参数CCC和核函数参数(如高斯核中的σ\sigmaσ)。CCC参数控制了模型对误分类的惩罚程度,较大的CCC值会使模型更严格地分类训练数据,但可能会导致过拟合;较小的CCC值则会使模型更宽松,但可能会欠拟合。

from sklearn.model_selection import GridSearchCV

# 定义参数范围
param_grid = {'C': [0.1, 1, 10, 100], 'kernel': ['linear', 'rbf']}

# 创建GridSearchCV对象
grid_search = GridSearchCV(SVC(), param_grid, cv=5, scoring='accuracy')

# 在训练集上进行网格搜索
grid_search.fit(X_train, y_train)

# 输出最佳参数组合
print("Best parameters:", grid_search.best_params_)

# 使用最佳参数组合创建SVM模型
best_svm_model = grid_search.best_estimator_

# 在测试集上进行预测
y_pred_best = best_svm_model.predict(X_test)

# 评估模型性能
print("Best Accuracy:", accuracy_score(y_test, y_pred_best))
print(classification_report(y_test, y_pred_best))

在这段代码中,使用GridSearchCV进行了网格搜索,以找到最佳的参数组合。通过交叉验证的方式,在训练集上尝试了不同的CCC值和核函数类型,并选择了准确率最高的参数组合。然后,使用最佳参数组合创建了SVM模型,并在测试集上进行了预测和评估。

三、多分类问题的支持向量机应用

1. 一对一策略(One-vs-One)

对于多分类问题,SVM可以通过一对一策略来解决。一对一策略的基本思想是将多分类问题分解为多个二分类问题,每两个类别之间训练一个SVM模型。对于KKK个类别,总共需要训练K(K−1)2\frac{K(K - 1)}{2}2K(K1)个模型。在预测时,将测试样本代入每个模型进行预测,然后采用投票策略确定最终的类别。

from sklearn.multiclass import OneVsOneClassifier

# 创建One-vs-One分类器
ovo_classifier = OneVsOneClassifier(SVC(kernel='linear', C=1.0))

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

# 在测试集上进行预测
y_pred_ovo = ovo_classifier.predict(X_test)

# 评估模型性能
print("One-vs-One Accuracy:", accuracy_score(y_test, y_pred_ovo))
print(classification_report(y_test, y_pred_ovo))

在上述代码中,使用了OneVsOneClassifier来实现一对一策略。首先创建了一个OneVsOneClassifier对象,并传入了一个使用线性核的SVM模型作为基模型。然后,在训练集上进行了训练,并在测试集上进行了预测和评估。

2. 一对多策略(One-vs-All)

一对多策略是另一种解决多分类问题的方法。它的基本思想是将每个类别与其他所有类别进行比较,训练KKK个二分类模型。对于第iii个模型,将第iii个类别的样本标记为正类,其他类别的样本标记为负类。在预测时,将测试样本代入每个模型进行预测,选择置信度最高的类别作为最终结果。

from sklearn.multiclass import OneVsRestClassifier

# 创建One-vs-All分类器
ova_classifier = OneVsRestClassifier(SVC(kernel='linear', C=1.0))

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

# 在测试集上进行预测
y_pred_ova = ova_classifier.predict(X_test)

# 评估模型性能
print("One-vs-All Accuracy:", accuracy_score(y_test, y_pred_ova))
print(classification_report(y_test, y_pred_ova))

在这段代码中,使用了OneVsRestClassifier来实现一对多策略。同样,先创建了一个OneVsRestClassifier对象,并传入了一个使用线性核的SVM模型作为基模型。接着,在训练集上进行了训练,并在测试集上进行了预测和评估。

四、非线性支持向量机应用实例

1. 使用高斯核处理非线性数据

当数据在原始空间中线性不可分时,可以使用高斯核(RBF)将数据映射到高维空间,使其变得线性可分。以下是一个简单的例子:

import numpy as np
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from sklearn.datasets import make_moons

# 生成非线性可分的数据集(月亮形状)
X, y = make_moons(n_samples=100, noise=0.2)

# 创建使用高斯核的SVM模型
svm_model = SVC(kernel='rbf', C=1.0, gamma='scale')

# 训练模型
svm_model.fit(X, y)

# 绘制决策边界
h = 0.02
x_min, x_max = X[:, 0].min() - 0.5, X[:, 0].max() + 0.5
y_min, y_max = X[:, 1].min() - 0.5, X[:, 1].max() + 0.5
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
Z = svm_model.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)

plt.contourf(xx, yy, Z, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', marker='o')
plt.title('SVM with RBF Kernel')
plt.show()

在这段代码中,首先使用make_moons函数生成了一个非线性可分的数据集(呈现月亮形状)。然后,创建了一个使用高斯核的SVM模型,并在训练集上进行了训练。绘制了决策边界和数据点,展示了SVM在处理非线性数据时的效果。

2. 多项式核的应用示例

多项式核可以将数据映射到多项式特征空间,从而处理一些具有多项式关系的非线性数据。以下是一个例子:

from sklearn.datasets import make_circles

# 生成圆形数据集(非线性可分)
X, y = make_circles(n_samples=100, factor=0.5, noise=0.1)

# 创建使用多项式核的SVM模型(度数为3)
svm_model = SVC(kernel='poly', degree=3, C=1.0, coef0=1)

# 训练模型
svm_model.fit(X, y)

# 绘制决策边界
h = 0.02
x_min, x_max = X[:, 0].min() - 0.5, X[:, 0].max() + 0.5
y_min, y_max = X[:, 1].min() - 0.5, X[:, 1].max() + 0.5
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
Z = svm_model.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)

plt.contourf(xx, yy, Z, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors='k', marker='o')
plt.title('SVM with Polynomial Kernel (degree=3)')
plt.show()

在这个例子中,使用make_circles函数生成了一个圆形数据集(非线性可分)。然后,创建了一个使用多项式核(度数为3)的SVM模型,并在训练集上进行了训练。绘制了决策边界和数据点,展示了SVM在处理这种非线性数据时的能力。

五、支持向量机在回归问题中的应用

1. 支持向量回归(SVR)原理

支持向量回归(Support Vector Regression,SVR)是SVM在回归问题中的扩展。与SVM用于分类不同,SVR用于拟合一个函数,使得所有训练数据点到该函数的距离不超过一个给定的阈值ϵ\epsilonϵ,并且尽可能使函数平坦。

在SVR中,试图找到一个函数f(x)f(x)f(x),满足以下条件:

  • 对于所有训练样本(xi,yi)(x_i, y_i)(xi,yi),有∣yi−f(xi)∣≤ϵ|y_i - f(x_i)| \leq \epsilonyif(xi)ϵ
  • 同时,要最小化12∥w∥2\frac{1}{2}\|w\|^221w2,其中www是函数的权重向量。

通过引入松弛变量ξi\xi_iξiξi∗\xi_i^*ξi,可以将上述问题转化为一个凸二次规划问题求解。

2. Python实现SVR示例
from sklearn.svm import SVR
from sklearn.datasets import make_regression
import numpy as np
import matplotlib.pyplot as plt


网站公告

今日签到

点亮在社区的每一天
去签到