SVM实战:从线性可分到高维映射再到实战演练
在支持向量机的分类模型中,我们会遇到两大类模型,一类是线性可分的模型,还有一类是非线性可分的。非线性可分模型是基于线性可分的基础上来处理的。支持向量机比较适合小样本的训练。
线性可分
如下图所示,有紫色和黑色两类,可以用一条直线对数据进行完全分类。这样叫做线性可分
由上图我们可以看出,这两类点可以由无限根直线给分割开,那么我们该怎么找出最好的那一根呢?我们该怎么衡量最好的呢?我们该怎么用数学表达式来表述出这个最好的那个数学表达式呢?
具体做法
光凭感觉,我们可以知道,上图中的红线最好,可能从两方面想到,红线的数据的权重相对于黄线考虑到的更多,更重要的是红线对数据误差的容忍度更高,因为红线刚好处于中间数据万一由于错误偏移一点,也是可以分类正确的。我们该怎么量化这个呢?
找最优
上图中,两条蓝线是经过红线平移,平移到恰好与黑点或者紫点相交的位置。要求最好,所以我们要让这两条线之间的距离d最大,这样也就确定了斜率值,但是在这两条蓝线中存在无数条红线,我们要确定红线我们还要让d/2最大,这样也就确定了截距。这样我们就语言描述出最好是什么样的了,下面我们来用数学公式表达出。(蓝线刚好要碰到的点就是支持向量)
定义
在我们进行数学公式表达之前,我们先对需要的进行定义。
1 训练数据及标签
这里我们假设数据为二维的(其实一样的,二维的我们建立的是一条线,如果是三维的,我们就建立一个最优平面,如果是高维的我们就建立一个最优的超平面,所用公式一样。)
这里标签我们就假设为 +1 和 -1(方面后面计算,对结果没影响)
2 训练模型
这里是W和X是相同维度的
3 线性可分
必要知识
1
后面虽然乘a,但对这个线或者超平面是不会发生改变的。
2 点到线距离公式(向量到超平面距离公式)
特征缩放
(a>0)
我们进行这一操作,对超平面的几何位置不会产生任何改变。
根据这个我们可以写出,肯定会存在一个a使得
这里等于1只是为了方便计算,意思就是使得支持向量 X0 到超平面的函数间隔等于 1。
缩放后,支持向量满足 ∣w⋅X0+b∣=1,此时所有其他样本点满足 ∣w⋅Xi+b∣≥1
这样上面d的公式就变为了
我们要求d的最大值,也就是求分母W的最小值。
优化问题
最小化
限制条件
线性不可分
这类又存在两种情况,一种是
上面这类情况,和我们上面差不多,我们可以用直线给分隔开,但是代价太高了,所有我们可以加上一个松弛变量
目标函数(最小化)
高维映射
上面对非线性的处理还是不够的,因为有可能会存在下面一种情况。
对于上面,我们不可能用一条线给分开了,这个时候我们要把低维向量映射到高维中,这样就可分了。在一个平面上取若干点,不同类,如果我们维度函数转化为无限维,这样我们可以分类所有的分类的问题。下面我举一个特别简单的小例子
简单示例
在这样一个数据中,不存在一条线能完全把红蓝两类点分开。
其中
我们想着是不是可以把这个映射到高维中,然后就可以用一个超平面来分隔
我们假设一个法则
转化为:
于是我们可以构造一个超平面
可以把他们分割
高维映射的优化式子
求最优W和b
SVM中的API接口
SVC( C=1.0, kernel='rbf', degree=3, gamma='scale', coef0=0.0, shrinking=True, probability=False, tol=0.001,
cache_size=200, class_weight=None, verbose=False, max_iter=- 1, decision_function_shape='ovr',
break_ties=False, random_state=None)
上面全是默认参数值
以下是 SVC(支持向量分类器)中最关键的参数及其简明解析,基于专业实践和文档总结
:
参数名 | 默认值 | 作用机制 | 影响效果 | 典型设置建议 |
---|---|---|---|---|
C * | 1.0 | 控制分类错误的惩罚强度 | - 值大:严格惩罚误分类 → 边界复杂,易过拟合 ↑ - 值小:容忍更多错误 → 边界平滑,泛化性强 ↓ | 网格搜索(如 [0.01, 0.1, 1, 10, 100] ) |
kernel | 'rbf' | 定义数据映射到高维空间的方式 | - linear :线性可分数据(高效)- rbf :非线性数据(默认首选)- poly /sigmoid :特定场景适用 | 优先尝试 rbf ,线性数据用 linear |
gamma | 'scale' | 控制样本影响力范围(RBF/Poly/Sigmoid核有效) | - 值大:样本影响范围小 → 决策边界复杂,易过拟合 ↑ - 值小:样本影响范围大 → 边界平滑,易欠拟合 ↓ | 'scale' (自动计算)或网格搜索(如 [0.001, 0.01, 0.1] ) |
degree | 3 | 多项式核的阶数(仅 kernel='poly' 有效) | - 阶数高:拟合复杂模式,但易过拟合 ↑ - 阶数低:模型简单,可能欠拟合 ↓ | 通常取 2~5 ,需配合调 C 和 gamma |
class_weight | None | 调整类别权重(应对样本不平衡) | - None :所有类权重相等- 'balanced' :按类别频率自动加权 | 样本不均衡时必选 'balanced' |
decision_function_shape | 'ovr' | 多分类策略选择 | - 'ovr' :一对其余(速度快)- 'ovo' :一对一(精度高,计算量大) | 默认 'ovr' 即可,类别多时考虑 'ovo' |
代码实战
import pandas as pd
data=pd.read_csv('iris.csv')
print(data.head())
X=data.iloc[:,[1,3]]
y=data.iloc[:,5]
from sklearn.model_selection import train_test_split
# X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)from sklearn.svm import SVC
model = SVC(kernel='linear', C=float('inf'))
# model = SVC(kernel='linear', C=1)
model.fit(X, y)
# y_pred = model.predict(X_test)a=model.coef_[0]
b=model.intercept_[0]print(a,b)from sklearn import metrics
print(metrics.classification_report(y,model.predict(X)))import matplotlib.pyplot as plt
import numpy as npX1=data[data.iloc[:,5]==1].iloc[:,[1,3]]
X0=data[data.iloc[:,5]==0].iloc[:,[1,3]]plt.scatter(X1.iloc[:,0],X1.iloc[:,1],c='red')
plt.scatter(X0.iloc[:,0],X0.iloc[:,1],c='blue')x1=np.linspace(0,7,100)
x2=(x1*a[0]-b)/a[1] #-b!!!并且这里
x3=(x1*a[0]-b+1)/a[1]
x4=(x1*a[0]-b-1)/a[1]
plt.plot(x1,x2)
plt.plot(x1,x3)
plt.plot(x1,x4)
plt.show()
下面是对其中两个特征进行划分的结果图。可以看出准确率特别高。
总结
1 float('inf')表示无限大
2 绘图的时候注意是WX+b=0,要把一个x作为纵坐标要稍加处理
3 这个如果训练的时候对数据做切分处理了,可能有未被计算的点离我们的超平面距离小于1。