机器学习实战-支持向量机原理、Python实现和可视化(分类)

支持向量机(SVM)广泛应用于模式分类和非线性回归领域。 SVM算法的原始形式由Vladimir N.Vapnik和Alexey Ya提出。自从那以后,SVM已经被巨大地改变以成功地用于许多现实世界问题。

1.什么是支持向量机(SVM)?

支持向量机是一种有监督的机器学习算法,可用于分类和回归问题。它遵循一种用核函数技巧来转换数据的技术,并且基于这些转换,它找到可能输出之间的最佳边界。简单来说,它做一些非常复杂的数据转换,以找出如何根据标签或输出定义的数据分离。本文我们将看到SVM分类算法如何通过python实现并可视化。

2.SVM的原理

寻找一个分离超平面,使得它到各分类的平均距离是最大的。

什么是分离超平面?

把数据划分为多个类别的一个图形,如线、面、超平面,我们统称为超平面。一个最简单的示例,即数据集位于2维平面中,一条线就可以把样本分成两类。但是支持向量机也可以用于一般的n维数据集,所以我们统称超平面。更正式地说,它是n维欧几里德空间的n-1维子空间。

所以一个

  • 1维数据集,单点表示超平面。
  • 2维数据集,线是超平面。
  • 3维数据集,平面是超平面。
  • 在更高的维度上,就被称为超平面。

SVM的目标是找到最佳分离超平面。那么什么时候分离超平面是最优的?让我们通过一组图来理解最佳超平面。有多个超平面,但其中哪一个是分离超平面? 可以很容易地看出,线B是比较好地分离这两个类的线,但我们如何计算出来最佳的超平面呢?

直观地,如果我们选择接近一个类的数据点的超平面,那么它可能不能很好地推广。因此,要选择尽可能远离每个类别的数据点的超平面。

在上图中,满足指定条件的最佳超平面为B。

因此,最大化每个类的最近点和超平面之间的距离就能找到最优分离超平面。这个距离称为边距,下图是边距的计算原理图。


SVM的目标是找到最佳超平面,因为它不仅分类现有数据集,而且有助于预测未知数据的类。最优超平面是边距最大的平面。

3、支持向量机的优缺点

每个分类算法都有自己的优点和缺点,它们根据正在分析的数据集发挥作用。

SVM的一些优点如下:

  • 凸优化方法的本质是保证最优性。该解决方案保证是全局最小值,而不是局部最小值
  • SVM是一种适用于线性和非线性可分离数据(使用核函数技巧)的算法。唯一要做的是找出正则化项C
  • SVM在低维和高维数据空间上工作良好。它能有效地对高维数据集工作,因为SVM中的训练数据集的复杂度通常由支持向量的数量而不是维度来表征。即使删除所有其他训练示例并重复训练,我们将获得相同的最佳分离超平面。
  • SVM可以在较小的训练数据集上工作,因为它们不依赖于整个数据。

SVM的缺点如下:

  • 它们不适合较大的数据集,因为在较大的数据集上使用SVM的训练时间可能很高,并且计算量更大。
  • 它们在具有重叠类的嘈杂数据集上效率较低。

4、Python实现

4.1 加载需要用到的模块

  1. import numpy as np
  2. from sklearn import datasets
  3. from sklearn.pipeline import Pipeline
  4. from sklearn.svm import SVC
  5. import seaborn as sns
  6. import pandas as pd
  7. from sklearn.model_selection import cross_val_score
  8. from sklearn.grid_search import GridSearchCV
  9. from sklearn.model_selection import train_test_split
  10. from sklearn.metrics import accuracy_score
  11. import matplotlib.pyplot as plt

4.2 初始化数据

从datasets数据集中加载iris数据,提取data中的两列作为特征值,提取target为分类值,并把特征值和分类值转换为pandas的DataFrame数据框,并合并到data中,重命名各特征为x1,x2和y。

找出x1和x2的最大值和最小值,生成满布坐标系的点,用于描绘超平面。

  1. iris = datasets.load_iris()
  2. X = iris['data'][:,[2,3]]
  3. y = iris['target']
  4. X = pd.DataFrame(X)
  5. y = pd.DataFrame(y)
  6. data = pd.merge(X,y,left_index=True,right_index=True,how='outer')
  7. data.columns=['x1','x2','y']
  8. h = 0.002
  9. x_min, x_max = data.x1.min() - 0.2, data.x1.max() + 0.2
  10. y_min, y_max = data.x2.min() - 0.2, data.x2.max() + 0.2
  11. xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
  12. np.arange(y_min, y_max, h))
  13. sns.scatterplot(data.x1, y=data.x2,hue=data.y)
  14. X = data[['x1','x2']]
  15. y = data.y

我们用seaborn的scatterplot把x1和x2用散点图描绘出来,如下图。

在这个图中我们看到有三个分类,接下来我们用SVM支持向量机为这些训练数据建立一个模型。

4.3 线性SVM模型

  1. X_train,X_val,y_train,y_val = train_test_split(X,y,test_size=0.2) #80%和20%划分X和y
  2. clf = SVC(C=0.1,kernel='linear')
  3. clf.fit(X_train,y_train)
  4. y_pre = clf.predict(X)
  5. Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
  6. Z = Z.reshape(xx.shape)
  7. sns.scatterplot(data.x1, y=data.x2,hue=y_pre)
  8. plt.contourf(xx, yy, Z, cmap=plt.cm.ocean, alpha=0.2)
  9. accuracy_score(data.y,y_pre)

用数据集合的80%作为训练集,建立一个C=0.1的线性SVM模型,并用data的所有x1和x2用这个SVM模型去预测y,预测的y和原来的y计算准确率。

  1. accuracy_score(data.y,y_pre)

结果0.95333333333333337,即约95.33%的准确率,可以和上面第一个图进行精细对比是哪个点分类错了。

4.4 寻找最好的模型

我们通过网格搜索,寻找一个最好的模型。GridSearchCV可以配置一个参数列表(超参数)、模型,在这个超参数中自动寻找最好的模型。GridSearchCV已经自动按照cv=5把样本分成5等分进行训练和验证的了。

  1. params = {'C':np.arange(0.1,1,0.1),'kernel':['linear', 'poly', 'rbf', 'sigmoid']}
  2. gsearch = GridSearchCV(estimator = SVC(kernel='linear'),
  3. param_grid = params, scoring='accuracy',iid=False, cv=5)
  4. gsearch.fit(X,data.y)
  5. gsearch.grid_scores_, gsearch.best_params_, gsearch.best_score_

结果如下:

自动寻找到上面的红色框的模型参数,准确率是96.67%。

从上表可以看出来核函数rbf的拟合比较好。那么我们再用GridSearchCV去变量rbf的degree看看能不能有进一步优化的空间。

  1. params = {'C':np.arange(0.1,1,0.1),'degree':np.arange(1,5,1)}
  2. gsearch = GridSearchCV(estimator = SVC(kernel='poly'),
  3. param_grid = params, scoring='accuracy',iid=False, cv=5)
  4. gsearch.fit(X,data.y)
  5. gsearch.grid_scores_, gsearch.best_params_, gsearch.best_score_

最好的结果是:

{‘C’: 0.10000000000000001, ‘degree’: 2},

0.9666666666666668)

没有得到进一步优化。

接下来我们就用rbf核函数c=0.1去重新建立模型并看看可视化的效果。

4.5 最优模型

我们直接用全集去拟合这个c=0.1,核函数rbf的SVM模型。我们看看可视化的结果。

  1. clf = SVC(C=0.2,kernel='rbf')

  2. clf.fit(X,y)

  3. y_pre = clf.predict(X)

  4. Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])

  5. Z = Z.reshape(xx.shape)

  6. ax = sns.scatterplot(data.x1, y=data.x2,hue=y_pre)

  7. ax.legend(loc="lower right")

  8. plt.contourf(xx, yy, Z, cmap=plt.cm.ocean, alpha=0.2)

  1. accuracy_score(data.y,y_pre)

准确率为0.96666666666666667,即96.67%

4.6 学习曲线

接下来我们就用这个模型看看样本的学习曲线

  1. scores = []
  2. for m in range(2,X_train.size):#循环2-79
  3. clf.fit(X_train[:m],y_train[:m])
  4. y_train_predict = clf.predict(X_train[:m])
  5. y_val_predict = clf.predict(X_val)
  6. scores.append(accuracy_score(y_train_predict,y_train[:m]))
  7. plt.plot(range(2,X_train.size),scores,c='green', alpha=0.6)

可以看出来,样本引入50个后,模型的准确率已经稳定下来了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,175评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,674评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,151评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,597评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,505评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,969评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,455评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,118评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,227评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,213评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,214评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,928评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,512评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,616评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,848评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,228评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,772评论 2 339

推荐阅读更多精彩内容