一、什么是支持向量机

        支持向量机(Support Vector Machine, SVM)是一种强大的机器学习算法,可用于解决数据分类(二分类)和回归问题。在分类问题上,SVM的核心思想是在特征空间中找到一个最优的超平面,这个超平面能够最大化地分开不同类别的数据点,即最大化两类数据点之间的间隔;而在回归问题中,支持向量机的目标是找到一个函数,该函数在给定的数据点上有最小的预测误差,与分类问题中最大化两类数据点之间的间隔不同,回归问题关注的是找到一个合适的函数,使得实际值和预测值之间的差异最小。支持向量机与其他机器学习/深度学习不一样的地方在于,其他方法往往通过降维解决问题(比如神经网络每一层神经元数量的递减设置),而支持向量机是通过升维直至维度高到足以满足分类/回归要求来解决问题的。

二、支持向量机的原理

1、最优超平面

        SVM的目标是找到一个超平面,使得不同类别的数据点之间的间隔(margin)最大化。间隔定义为从超平面到最近的数据点(支持向量)的最短距离。对于线性可分的情况,SVM的优化问题可以表示为:

min_{w,b}\frac{1}{2}||w||^{2}

        受以下约束条件,对于所有的i,有:

y_{i}(wx_{i}+b)\geqslant 1

        其中,w是超平面的法向量,b是超平面的偏置项,x_{i}是数据点,y_{i}是数据点的标签,取值为 +1 或 -1,wx_{i}+b是数据点到超平面的距离。

2、软间隔

        在现实世界中,数据往往不是完全线性可分的。为了处理这种情况,SVM引入了软间隔(soft margin)的概念,允许一些数据点违反间隔规则。软间隔SVM的优化问题可以表示为:

min_{w,b,\varepsilon }\frac{1}{2}||w||^{2}+C\sum_{i=1}^{n}\varepsilon _{i}

        受以下条件约束,对于所有的i,有:

y_{i}(wx_{i}+b)\geqslant 1-\varepsilon _{i}

\varepsilon _{i}\geqslant 0

        其中,\varepsilon _{i}是松弛变量,用于处理间隔违规,C是惩罚参数,控制间隔违规的严重性。

3、核技巧

        当数据不是线性可分时,SVM可以使用核技巧将数据映射到高维空间,在这个空间中寻找线性分割,这就是我们前面说到的通过升维解决问题。核函数的选择取决于数据的特性和问题的需求,常见的核函数包括:

        (1)线性核

K(x_{i},x_{j}) = x_{i}x_{j}

        这里,x_{i}x_{j}是数据集中的两个特征向量,取两向量的点积(内积)。线性核相当于假设数据在原始空间中已经是线性可分的,因此不需要映射到高维空间。

        (2)径向基函数RBF核

        径向基函数(Radial Basis Function, RBF)核,也称为高斯核,是支持向量机(SVM)中常用的核函数之一。它在机器学习中的作用是将原始数据映射到高维空间,使得在原始空间中线性不可分的数据在高维空间中变得线性可分:

K(x_{i},x_{j}) = exp(-\gamma ||x_{i}-x_{j}||^{2})

        其中,x_{i}x_{j}是输入空间中的两个样本;\gamma是核函数的参数,它决定了单个训练样本的影响范围,通常需要通过交叉验证来选择;||x_{i}-x_{j}||是样本之间的欧几里得距离。

        (3)多项式核

        多项式核(Polynomial Kernel)是支持向量机中的一种核函数,它允许SVM在高维空间中处理非线性问题。多项式核通过将原始特征映射到一个更高维的空间,使得数据在这个新空间中变得线性可分:

K(x_{i},x_{j}) = (\gamma x_{i}x_{j}+r)^d

        其中,x_{i}x_{j}是数据集中的两个特征向量;\gamma是核函数的参数,也称为缩放系数或核函数的系数;r是一个常数,为偏置项;dd 是多项式的度数,它决定了多项式的阶数。

三、支持向量机求解

        SVM的优化问题通常通过拉格朗日乘子法(知道名字就行,面试官都不一定记得公式推导。。)来求解,转化为对偶问题

max_{\alpha }\sum_{i=1}^{n}\alpha _{i}-\frac{1}{2}\sum_{i,j=1}^{n}y_{i}y_{j}\alpha _{i}\alpha_{j}K(x_{i},x_{j})

        受以下约束条件,对于所有i,有:

\sum_{i=1}^{n}\alpha _{i}y_{i} = 0

0\leqslant \alpha _{i}\leqslant C

        其中,\alpha _{i}是拉格朗日乘子,K(x_{i},x_{j})是核函数。最终,模型参数w和b可以通过\alpha计算得到:

w = \sum_{i=1}^{n}\alpha_{i}y_{i}x_{i}

b = y_{i}-\sum_{j=1}^{n}\alpha_{j}y_{j}K(x_{i},x_{j})

四、支持向量机应用

1、分类

        虽然SVM是二分类模型,但是诸如scikit-learn之类的第三方库已经构建了一整套完整的代码使得我们可以直接使用SVM进行多分类。

# 导入必要的库
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
from sklearn.preprocessing import StandardScaler

# 加载鸢尾花数据集
iris = load_iris()
X = iris.data
y = iris.target

# 数据预处理:标准化特征
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 划分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)

# 创建 SVM 分类器实例
# 可以选择不同的核函数,如 'linear', 'poly', 'rbf', 'sigmoid'
# 在scikit-learn中,SVC类提供了decision_function_shape参数,可以用来控制决策函数的形状,从而支持多分类。默认情况下,decision_function_shape='ovr',这意味着使用一对多策略。
svm_classifier = SVC(kernel='rbf', C=1.0)  # C 是正则化参数

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

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

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy:.2f}')

# 可打印支持向量
print("Support vectors:")
print(svm_classifier.support_vectors_)

2、回归

# 导入必要的库
from sklearn.datasets import load_boston
from sklearn.svm import SVR
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.preprocessing import StandardScaler

# 加载波士顿房价数据集
boston = load_boston()
X = boston.data
y = boston.target

# 数据预处理:标准化特征
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# 划分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)

# 创建 SVM 回归器实例
# 可以选择不同的核函数,如 'linear', 'poly', 'rbf'
svr = SVR(kernel='rbf', C=100, gamma=0.1, epsilon=0.1)

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

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

# 计算均方误差(MSE)
mse = mean_squared_error(y_test, y_pred)
print(f'Mean Squared Error: {mse:.2f}')

# 可计算决定系数 R^2
r2 = svr.score(X_test, y_test)
print(f'R^2 Score: {r2:.2f}')

五、总结

        支持向量机在实际业务中有诸多应用,对于特征量较大、特征关系呈现非线性或者内存有限的情况,支持向量机都是常用的解决方案。

1、优点

        (1)有效的分类性能:在许多实际应用中,SVM提供了非常有效的分类性能。

        (2)核技巧:SVM的核技巧允许它在高维空间中找到复杂的决策边界。

        (3)内存效率:SVM只与支持向量有关,这使得它在内存使用上非常高效。

        (4)鲁棒性:SVM对于数据中的噪声和异常值具有一定的鲁棒性。

        (5)适用于小样本数据:SVM在小样本数据集上也能表现良好。

2、缺点

        (1)计算复杂度:SVM的计算复杂度较高(因为要不断升维计算),尤其是在处理大规模数据集时。

        (2)参数选择:SVM的性能依赖于核函数和惩罚参数的选择,这需要大量的实验来确定最佳参数。

        (3)不支持在线学习:SVM不适用于在线学习或实时更新模型的场景。

        (4)解释性差:相比于决策树等模型,SVM的决策过程较难解释。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐