0#07 SVM 支持向量機

0x00 數(shù)據(jù)準備

為了簡單起見我就開始自己造數(shù)據(jù),開始分類

線性可分
(x  ,y)     label
(-1 ,0)     0
(0  ,1)     1
(1  ,0)     1
補充數(shù)據(jù):
(-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 筆算機器學(xué)習(xí)

我們先將點的坐標畫出來


非SCV區(qū)分的方法.png

發(fā)現(xiàn)如果用我們已知的方法用一條直線區(qū)分,這條直線有很多條,但是很明顯有些直線是毫無用處的,只要數(shù)據(jù)增加就會被修改.

于是我們就會想,是不是根據(jù)這些點,我們可以找到最適合的那條直線,

那什么是最適合的直線呢?
于是SVM定義,距離這條直線最近的點,與直線距離最大,也就是邊界最大化.
比如說這個


邊界最大化.png

于是我們把在邊界上的點稱為支持向量
比如這里的(-1,0),(0,1),(1,0)
如果刪除或增加不是支持向量的點,不會影響結(jié)果.
但是我們這個例子是屬于線性可分的例子.

還有一些情況是先行不可分,
比如
第二組數(shù)據(jù)

非線性可分.png

很明顯正常的分發(fā)是化成圓圈,不能用一條直線進行區(qū)分
于是我們想辦法把該坐標投射到3維度中去
比如使第三維度z=(x12+x22)
或者z=np.exp(-(x12+x22))
投影之后,就是一個線性可分的3維圖形
區(qū)分非線性可分.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 進行區(qū)分

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]])

"""
這一步是提取特征值,我們還沒有基礎(chǔ),所以只需要知道,這一部試講原本的近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:懲罰參數(shù)C(越大,邊界越硬)
kernel:內(nèi)核類型。 
        'linear':線性
        'poly':表示算法使用多項式核函數(shù)
        'rbf':表示算法使用高斯核函數(shù),分類非線性可分的樣本的分類
        'sigmoid':
        'precomputed'
degree:  多項式核函數(shù)的次數(shù)('poly')外厂。 被所有其他內(nèi)核忽略冕象。
gamma:  'rbf','poly'和'sigmoid'的核系數(shù)汁蝶。 如果gamma是'auto'渐扮,那么將使用1 / n_features。
"""
svc = SVC(kernel='rbf',class_weight = 'balanced')
model=make_pipeline(pca,svc)

"""
分割訓(xùn)練集和測試集合
"""
from sklearn.cross_validation import train_test_split
xtrain,xtest,ytrain,ytest=train_test_split(faces.data,faces.target,random_state=0)

"""
使用網(wǎng)格法,找出最適合的參數(shù)
注意參數(shù)格式:
scv__C
函數(shù)名稱 2*下劃線 函數(shù)的變量名稱
"""
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_
兩個邊分別含有的支持向量的個數(shù)
model.n_support_
賦予特征的權(quán)重(原始問題中的系數(shù))掖棉。 這僅適用于線性內(nèi)核墓律。
model.coef_

0x04 一些想法

  1. 支持向量機是深度學(xué)習(xí)之前最成功的算法
  2. 支持向量機不僅能解決線性分類問題,還能解決非線性分類問題.
  3. 訓(xùn)練好的模型的復(fù)雜度,由支持向量個數(shù)決定,而不是數(shù)據(jù)的維度決定的
  4. SVM不太容易過擬合,因為處理支持向量的點,其他點都不重要
  5. 對于一些超參數(shù),比如核函數(shù)
    如果線性可分,我們使用'linear'
    如果線性不可分,我們使用'rbf'
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市幔亥,隨后出現(xiàn)的幾起案子耻讽,更是在濱河造成了極大的恐慌,老刑警劉巖帕棉,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件针肥,死亡現(xiàn)場離奇詭異,居然都是意外死亡香伴,警方通過查閱死者的電腦和手機慰枕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來即纲,“玉大人具帮,你說我怎么就攤上這事〉驼” “怎么了蜂厅?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長膊畴。 經(jīng)常有香客問我掘猿,道長,這世上最難降的妖魔是什么唇跨? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任稠通,我火速辦了婚禮礁遵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘采记。我一直安慰自己,他們只是感情好政勃,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布唧龄。 她就那樣靜靜地躺著,像睡著了一般奸远。 火紅的嫁衣襯著肌膚如雪既棺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天懒叛,我揣著相機與錄音丸冕,去河邊找鬼。 笑死薛窥,一個胖子當(dāng)著我的面吹牛胖烛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播诅迷,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼佩番,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了罢杉?” 一聲冷哼從身側(cè)響起趟畏,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎滩租,沒想到半個月后赋秀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡律想,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年猎莲,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜘欲。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡益眉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出姥份,到底是詐尸還是另有隱情郭脂,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布澈歉,位于F島的核電站展鸡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏埃难。R本人自食惡果不足惜莹弊,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一涤久、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧忍弛,春花似錦响迂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至疯兼,卻和暖如春然遏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背吧彪。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工待侵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人姨裸。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓秧倾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親啦扬。 傳聞我的和親對象是個殘疾皇子中狂,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容

  • "清明時節(jié)雨紛紛,路上行人欲斷魂扑毡。"這是古詩里的清明節(jié)胃榕。 "囡囡,乖瞄摊,過來勋又,給祖宗跪下。先三拜三鞠躬换帜,再三跪九叩頭...
    艾七的時光閱讀 131評論 0 1
  • 一楔壤、自定義View需要繼承UIView 注意的幾點問題: 1.initWithFrame init和initWit...
    宙斯YY閱讀 1,651評論 0 1
  • 今天我們完成了老大指定的任務(wù)29分提前完成,我們很高興惯驼,大家也很給力蹲嚣,一天7分的好成績?yōu)槲覀兊娜蝿?wù)化了一個完美的句...
    LK_245a閱讀 121評論 0 0