0#07 SVM 支持向量机

0x00 数据准备

为了简单起见我就开始自己造数据,开始分类

线性可分
(x  ,y)     label
(-1 ,0)     0
(0  ,1)     1
(1  ,0)     1
补充数据:
(-2,-3)     0
(1  ,1)     1
线性不可分
(x  ,y)     label
(0  ,0)     0
(1  ,0)     0
(0  ,1)     0
(-1 ,0)     0
(0  ,-1)    0

(0  ,2)     1
(1  ,2)     1
(2  ,2)     1
(2  ,1)     1
(2  ,0)     1
(2  ,-1)    1
(2  ,-2)    1
(1  ,-2)    1
(0  ,-2)    1
(-1 ,-2)    1
(-2 ,-2)    1
(-2 ,-1)    1
(-2 ,0)     1
(-2 ,1)     1
(-2 ,2)     1
(-1 ,2)     1

因为SVM支持向量机非常强大,所以能做的事情非常多,实例中我们会以fetch_lfw_people作为例子


0x01 笔算机器学习

我们先将点的坐标画出来


非SCV区分的方法.png

发现如果用我们已知的方法用一条直线区分,这条直线有很多条,但是很明显有些直线是毫无用处的,只要数据增加就会被修改.

于是我们就会想,是不是根据这些点,我们可以找到最适合的那条直线,

那什么是最适合的直线呢?
于是SVM定义,距离这条直线最近的点,与直线距离最大,也就是边界最大化.
比如说这个


边界最大化.png

于是我们把在边界上的点称为支持向量
比如这里的(-1,0),(0,1),(1,0)
如果删除或增加不是支持向量的点,不会影响结果.
但是我们这个例子是属于线性可分的例子.

还有一些情况是先行不可分,
比如
第二组数据

非线性可分.png

很明显正常的分发是化成圆圈,不能用一条直线进行区分
于是我们想办法把该坐标投射到3维度中去
比如使第三维度z=(x12+x22)
或者z=np.exp(-(x12+x22))
投影之后,就是一个线性可分的3维图形
区分非线性可分.png

代码如下

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

x=np.array([[0  ,0],[1  ,0],[0  ,1],[-1 ,0],[0  ,-1],[0  ,2],[1  ,2],[2  ,2],[2  ,1],[2  ,0],[2  ,-1],[2  ,-2],[1  ,-2],[0  ,-2],[-1 ,-2],[-2 ,-2],[-2 ,-1],[-2 ,0],[-2 ,1],[-2 ,2],[-1 ,2]])
y=np.array([0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1])

plt.figure(figsize=(6,6))
plt.scatter(x[:,0],x[:,1],c=y,cmap='autumn',s=500)

z=np.exp(-(x**2).sum(1))
from mpl_toolkits import mplot3d
from ipywidgets import interact,fixed
def plot_3D(elev=30,azim=30,x=x,y=y):
    ax=plt.subplot(projection='3d')
    ax.scatter3D(x[:,0],x[:,1],z,c=y,s=50,cmap='autumn')
    ax.view_init(elev=elev,azim=azim)
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_zlabel('r')
    
from mpl_toolkits import mplot3d
def plot_3D(elev=30,azim=30,x=x,y=y):
    ax=plt.subplot(projection='3d')
    ax.scatter3D(x[:,0],x[:,1],r,c=y,s=50,cmap='autumn')
    ax.view_init(elev=elev,azim=azim)
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_zlabel('r')
    
interact(plot_3D,elev=(-90,90),azim=(-180,180),x=fixed(x),y=fixed(y));

0x03 使用支持向量机

我们开始使用 SVM 进行区分

from sklearn.datasets import fetch_lfw_people
"""
下载的过程非常缓慢,所以提前下载更加合适
图片地址:
https://ndownloader.figshare.com/files/5976018 #lfw.tgz
https://ndownloader.figshare.com/files/5976015 #lfw-funneled.tgz
https://ndownloader.figshare.com/files/5976012 #pairsDevTrain.txt
https://ndownloader.figshare.com/files/5976009 #pairsDevTest.txt
https://ndownloader.figshare.com/files/5976006 #pairs.txt
保存到 ~/scikit_learn_data/lfw_home
然后将lfw.tgz与lfw-funneled.tgz解压
"""
faces = fetch_lfw_people(min_faces_per_person=60,download_if_missing=True)
print(faces.target_names)
print(faces.images.shape)

import matplotlib.pyplot as plt
fig,ax = plt.subplots(3,5,)
for i, axi in enumerate(ax.flat):
    axi.imshow(faces.images[i],cmap='bone')
    axi.set(xticks=[],yticks=[],xlabel=faces.target_names[faces.target[i]])

"""
这一步是提取特征值,我们还没有基础,所以只需要知道,这一部试讲原本的近3000个像素点,提取其中的150个
"""

from sklearn.svm import SVC
from sklearn.decomposition import RandomizedPCA
from sklearn.pipeline import make_pipeline

pca = RandomizedPCA(n_components=150,whiten=True,random_state=0)
"""
C:惩罚参数C(越大,边界越硬)
kernel:内核类型。 
        'linear':线性
        'poly':表示算法使用多项式核函数
        'rbf':表示算法使用高斯核函数,分类非线性可分的样本的分类
        'sigmoid':
        'precomputed'
degree:  多项式核函数的次数('poly')。 被所有其他内核忽略。
gamma:  'rbf','poly'和'sigmoid'的核系数。 如果gamma是'auto',那么将使用1 / n_features。
"""
svc = SVC(kernel='rbf',class_weight = 'balanced')
model=make_pipeline(pca,svc)

"""
分割训练集和测试集合
"""
from sklearn.cross_validation import train_test_split
xtrain,xtest,ytrain,ytest=train_test_split(faces.data,faces.target,random_state=0)

"""
使用网格法,找出最适合的参数
注意参数格式:
scv__C
函数名称 2*下划线 函数的变量名称
"""
from sklearn.grid_search import GridSearchCV
param_grid ={
    'svc__C':[1,5,10,50],
    'svc__gamma':[0.0001,0.0005,0.001,0.005]}
grid = GridSearchCV(model,param_grid)

grid.fit(xtrain,ytrain)
print(grid.best_params_)

model = grid.best_estimator_
yfit = model.predict(xtest)

"""
制作文字报告
比如:

                   precision    recall  f1-score   support

     Ariel Sharon       0.92      0.69      0.79        16
     Colin Powell       0.84      0.87      0.85        61
  Donald Rumsfeld       0.75      0.69      0.72        35
    George W Bush       0.78      0.97      0.86       125
Gerhard Schroeder       0.90      0.66      0.76        29
      Hugo Chavez       1.00      0.63      0.77        19
Junichiro Koizumi       1.00      0.76      0.87        17
       Tony Blair       0.96      0.77      0.86        35

      avg / total       0.85      0.83      0.83       337
"""
from sklearn.metrics import classification_report
print(classification_report(ytest,yfit,target_names=faces.target_names))

值得一提的是,对于sklearn的支持向量机
我们可以用方法将支持向量显示出来
一些方法:
支持向量的下标
model.support_
支持向量具体的坐标
model.support_vectors_
两个边分别含有的支持向量的个数
model.n_support_
赋予特征的权重(原始问题中的系数)。 这仅适用于线性内核。
model.coef_

0x04 一些想法

  1. 支持向量机是深度学习之前最成功的算法
  2. 支持向量机不仅能解决线性分类问题,还能解决非线性分类问题.
  3. 训练好的模型的复杂度,由支持向量个数决定,而不是数据的维度决定的
  4. SVM不太容易过拟合,因为处理支持向量的点,其他点都不重要
  5. 对于一些超参数,比如核函数
    如果线性可分,我们使用'linear'
    如果线性不可分,我们使用'rbf'
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,084评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,623评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,450评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,322评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,370评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,274评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,126评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,980评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,414评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,599评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,773评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,470评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,080评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,713评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,852评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,865评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,689评论 2 354

推荐阅读更多精彩内容

  • "清明时节雨纷纷,路上行人欲断魂。"这是古诗里的清明节。 "囡囡,乖,过来,给祖宗跪下。先三拜三鞠躬,再三跪九叩头...
    艾七的时光阅读 131评论 0 1
  • 一、自定义View需要继承UIView 注意的几点问题: 1.initWithFrame init和initWit...
    宙斯YY阅读 1,647评论 0 1
  • 今天我们完成了老大指定的任务29分提前完成,我们很高兴,大家也很给力,一天7分的好成绩为我们的任务化了一个完美的句...
    LK_245a阅读 119评论 0 0