一.支持向量机概述
支持向量机(SVM)是一类按监督学习方式对数据进行二元分类的分类器,其决策边界是对学习样本求解的最大边距超平面,可以将问题化为一个求解凸二次规划的问题。
具体来说就是在线性可分时,在原空间寻找两类样本的最优分类超平面。在线性不可分时,加入松弛变量并通过使用非线性映射将低维度输入空间的样本映射到高维度空间使其变为线性可分,这样就可以在该特征空间中寻找最优分类超平面。
二.超平面
由于数据点都在二维平面上,所以此时分隔超平面就只是一条直线。但是,如果所给的数据集是三维的,那么此时用来分隔数据的就是一个平面。显而易见,更高维的情况可以依此类推。当数据集是N维时,需要一个N-1维的某某对象来对数据进行分隔。N-1维的该对象被称为超平面(hyperplane),也就是分类的决策边界。 分布在超平面一侧的所有数据都属于某个类别,而分布在另一侧的所有数据则属于另一个类别。
三.支持向量机类型
3.1硬间隔
- 指在训练数据集中找到一个超平面,使得该超平面能够将不同类别的样本完全分开,并且使得所有样本点到该超平面的距离都大于等于一个确定的值,这个确定的值就是硬间隔。
- 硬间隔的目标是找到一个最大化间隔的超平面,以确保对新样本的分类具有很好的泛化能力。
- 完全可分
3.2软间隔
- 软间隔:指在支持向量机中允许一些训练样本点出现在超平面的错误一侧,即允许一些样本点出现在间隔边界内部,而不是严格地要求所有样本点都要被正确分类。
- 软间隔的目的:为了提高模型的鲁棒性,使得支持向量机能够更好地处理一些噪声或异常点的情况。
- 在软间隔的情况下,支持向量机的目标是找到一个最大化间隔的超平面,并且最小化分类错误和间隔边界内部的样本点。
- 通过引入惩罚项来平衡间隔的最大化和分类错误的最小化,从而实现对软间隔的优化。
更详细的在后面优化会提到
四.最大间隔
要想分类器更优,应使这个间隔越大越好,就是找出最大间隔
找到目标:就是求width的极大值,即寻找参数w和b , 使得下述公式最大
也就是找下面公式的极小值:
上述这些都是在一些前提条件成立的情况下才可以,即
怎么求呢?用拉格朗日乘子法去求
拉格朗日乘子法的要求是,在某些前提条件下,求极值,刚好满足
五.对偶问题
5.1KKT
5.2拉格朗日乘子法
具体举个例子,更好理解一下
5.3SVM求解具体实例
比如,现有数据:3个点,其中正例 X1(3,3) ,X2(4,3) ,负例X3(1,1)
求解:
将数据代入:
在边界上,意味着值为0,当a1为0时 ,a2<0,不满足
当a2 = 0时,a1 = 0.25 满足
前提条件有 a3 = a1+a2 ,所以求出a3 = 0.25
即,这三个点中x1和x3是支持向量
所求的a不为0的向量称为支持向量!
5.4SMO
核心思想就是两两一组判断是否是支持向量
六.核函数
常用的核函数:
七.软间隔优化
求解和之前一样,只是目标函数改了一点
八.用SVM完成垃圾邮件分类
先导入依赖
线性SVM
结果展示:
C=1时
C=100时
非线性SVM
#测试一下
x1 = np.array([1, 2, 3])
x2 = np.array([2, 0, 1])
sigma = 2
gaussian_kernel(x1, x2, sigma)
df = sio.loadmat(r'C:\Users\86158\Desktop\机器学习\第七讲 支持向量机\svm_data\data\ex6data2.mat')
data = pd.DataFrame(df['X'], columns=['X1', 'X2'])
data['y'] = df['y']
data
fig = plt.subplots(figsize=(8,6))
plt.scatter(data['X1'], data['X2'], s=30, c=data['y'], cmap='Spectral')
plt.xlabel('X1')
plt.ylabel('X2')
plt.show()
#用内置的高斯核函数求解
svc = svm.SVC(C=100, gamma=10, probability=True)
svc.fit(data[['X1', 'X2']], data['y'])
svc.score(data[['X1', 'X2']], data['y'])
网络搜索寻找最优参数
#读取训练集和验证集
df = sio.loadmat(r'C:\Users\86158\Desktop\机器学习\第七讲 支持向量机\svm_data\data\ex6data3.mat')
df.keys()
X = df['X']
Xval = df['Xval']
y = df['y']
yval = df['yval']
candidate = [0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100]
gamma_values = [0.01, 0.03, 0.1, 0.3, 1, 3, 10, 30, 100]
best_score = 0
best_params = {'C': None, 'gamma': None}
for C in candidate:
for gamma in gamma_values:
svc = svm.SVC(C=C, gamma=gamma)
svc.fit(X, y)
score = svc.score(Xval, yval)
if score > best_score:
best_score = score
best_params['C'] = C
best_params['gamma'] = gamma
best_score, best_params
实现垃圾邮件过滤
train = sio.loadmat(r'C:\Users\86158\Desktop\机器学习\第七讲 支持向量机\svm_data\data\spamTrain.mat')
test = sio.loadmat(r'C:\Users\86158\Desktop\机器学习\第七讲 支持向量机\svm_data\data\spamTest.mat')
train.keys(),test.keys()
#X是一个二进制向量,1表示邮件中存在该单词,0表示不存在
X = train['X']
y = train['y'].ravel()
Xtest = test['Xtest']
ytest = test['ytest'].ravel()
svc = svm.SVC()
svc.fit(X, y)
svc.score(Xtest, ytest)
九.总结
1)准确率98.7%,还不错
2)支持向量机(SVM)是一种强大的机器学习算法,用于分类和回归问题。以下是我们的实验总结:
- SVM在处理线性可分的数据集时表现出色,能够很好地将两个不同类别的数据分开。
- 对于非线性可分的数据集,SVM可以通过使用核函数来将数据映射到高维空间,从而实现更好的分类效果。
- SVM对于小样本数据集的表现较好,能够有效地处理少量训练数据。
- 在处理大规模数据集时,SVM可能会面临计算复杂度和内存消耗的问题,需要对数据进行降维或者使用其他方法来加速计算。
- 在实际应用中,选择合适的核函数以及调整SVM的超参数对模型的性能影响很大,需要进行反复实验和调优。