1,线性可分:
SVM的推导过程的基本是对线性可分的样本空间的推导,后面的核函数是对线性不可分样本空间的推广,而松弛变量的引进是为了解决噪声(Outliers,异常值)的问题。所以这片文章着重对线性可分情形进行公式推导,后面有空闲时间在对核函数和松弛变量部分进行公式推导的补充。
下边贴上笔者的手推笔记,因为敲公式实在是费时费力的一件事情,后面有时间再补充吧。
2,线性不可分:核函数
核函数的价值在于它虽然也是讲特征进行从低维到高维的转换,但核函数绝就绝在它事先在低维上进行计算,而将实质上的分类效果表现在了高维上,也就如上文所说的避免了直接在高维空间中的复杂计算。
核函数就是SVM 使用非线性分类器的优势,而 Logistic 模式以及决策树模式都是使用了直线方法。
3,松弛变量(噪声,Outliers):
当不是因为数据本身是非线性结构的,而只是因为数据有噪声。对于这种
偏离正常位置很远的数据点,我们称之为outlier ,在我们原来的SVM 模型里,outlier的存在有可能造成很大的影响,因为超平面本身就是只有少数几个support vector 组成的,如果这些support vector 里又存在outlier 的话,其影响就很大了。
如上图所示,黑圈标记的蓝点就是噪声(Outlier),实际上他也是一个支持向量,对SVM模型参数的估计起了很大的作用。
其中 C 是一个参数,用于控制目标函数中两项(“寻找margin 最大的超平面”和 “保证数据点偏差量最小”)之间的权重。注意,其中 ξ 是需要优化的变量(之一),而C 是一个事先确定好的常量。
因此,最终的拉格朗日形式为:
4,优化算法:SMO算法:
支持向量机学习的是凸二次规划问题,可以使用SMO算法快速求解。
5,code:
code:1),加载数据;2),模型训练;3),画图。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.svm import SVC
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import time
# from yuan.utils.plots import chinese_setting # 让matplotlib正常显示中文
# chinese_setting()
plt.rcParams['font.sans-serif'] = [u'SimHei'] # 画图正常显示中文
plt.rcParams['axes.unicode_minus'] = False
# 1,加载数据:
iris_feature = u'花萼长度', u'花萼宽度', u'花瓣长度', u'花瓣宽度' # 'sepal length', 'sepal width', 'petal length', 'petal width'
data = pd.read_csv('../DataSets/iris.data', header=None)
x, y = data[list(range(4))], data[4]
y = pd.Categorical(y).codes
x = x[[0, 1]]
x_train, x_test, y_train, y_test = train_test_split(x, y, random_state=28, train_size=0.6)
# 2,模型训练:
svm = SVC(C=1, kernel='sigmoid') # C:松弛变量权重;kernel:核函数
start = time.time()
svm.fit(x_train, y_train)
end = time.time()
svm_score = accuracy_score(y_train, svm.predict(x_train))
print('cost time: ', end-start, 'score: ', svm_score)
# 3,画图:
N = 500
x1_min, x2_min = x.min()
x1_max, x2_max = x.max()
t1 = np.linspace(x1_min, x1_max, N)
t2 = np.linspace(x2_min, x2_max, N)
x1, x2 = np.meshgrid(t1, t2) # 生成网格采样点
grid_show = np.dstack((x1.flat, x2.flat))[0] # 测试点
svm_grid_hat = svm.predict(grid_show) # 获取测试值
svm_grid_hat = svm_grid_hat.reshape(x1.shape) # 使之与输入的形状相同
cm_light = matplotlib.colors.ListedColormap(['#A0FFA0', '#FFA0A0', '#A0A0FF'])
cm_dark = matplotlib.colors.ListedColormap(['g', 'r', 'b'])
plt.figure(facecolor='w', figsize=(14,7))
plt.pcolormesh(x1, x2, svm_grid_hat, cmap=cm_light)
plt.scatter(x[0], x[1], c=y, edgecolors='k', s=50, cmap=cm_dark) # 样本
plt.scatter(x_test[0], x_test[1], s=120, facecolors='none', zorder=10) # 圈中测试集样本
plt.xlabel(iris_feature[0], fontsize=13) # lable列表
plt.ylabel(iris_feature[1], fontsize=13)
plt.xlim(x1_min, x1_max)
plt.ylim(x2_min, x2_max)
plt.title(u'鸢尾花SVM特征分类', fontsize=16)
plt.grid(b=True, ls=':')
plt.tight_layout(pad=1.5)
plt.show()
本文分享自 MiningAlgorithms 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!