[Example of Sklearn] - SVM usge

reference : http://www.csdn.net/article/2012-12-28/2813275-Support-Vector-Machinegit

SVM是什麼?github

SVM是一種訓練機器學習的算法,能夠用於解決分類和迴歸問題,同時還使用了一種稱之爲kernel trick的技術進行數據的轉換,而後再根據這些轉換信息,在可能的輸出之中找到一個最優的邊界。簡單來講,就是作一些很是複雜的數據轉換工做,而後根據預約義的標籤或者輸出進而計算出如何分離用戶的數據。算法

是什麼讓它變得如此的強大?app

固然,對於SVM來講,徹底有能力實現分類以及迴歸。在這篇文章中,Greg Lamp主要關注如何使用SVM進行分類,特別是非線性的SVM或者SVM使用非線性內核。非線性SVM意味着該算法計算的邊界沒有必要是一條直線,這樣作的好處在於,能夠捕獲更多數據點集之間的複雜關係,而無需靠用戶本身來執行困難的轉換。其缺點就是因爲更多的運算量,訓練的時間要長不少。機器學習

什麼是kernel trick?學習

kernel trick對接收到的數據進行轉換:輸入一些你認爲比較明顯的特徵進行分類,輸出一些你徹底不認識的數據,這個過程就像解開一個DNA鏈。你開始是尋找數據的矢量,而後把它傳給kernel trick,再進行不斷的分解和重組直到造成一個更大的數據集,並且一般你看到的這些數據很是的難以理解。這就是神奇之處,擴展的數據集擁有更明顯的邊界,SVM算法也可以計算一個更加優化的超平面。優化

其次,假設你是一個農場主,如今你有一個問題——你須要搭建一個籬笆來防止狼對牛羣形成傷害。可是籬笆應該建在哪裏呢?若是你是一個以數據爲驅動的農場主,那麼你就須要在你的牧場上,依據牛羣和狼羣的位置創建一個「分類器」,比較這幾種(以下圖所示)不一樣的分類器,咱們能夠看到SVM完成了一個很完美的解決方案。Greg Lamp認爲這個故事漂亮的說明了使用非線性分類器的優點。顯而易見,邏輯模式以及決策樹模式都是使用了直線方法。this

實現代碼以下:farmer.py  Python spa

 

import numpy as np 
import pylab as pl 
from sklearn import svm 
from sklearn import linear_model 
from sklearn import tree 
import pandas as pd 
  
  
def plot_results_with_hyperplane(clf, clf_name, df, plt_nmbr): 
    x_min, x_max = df.x.min() - .5, df.x.max() + .5 
    y_min, y_max = df.y.min() - .5, df.y.max() + .5 
  
    # step between points. i.e. [0, 0.02, 0.04, ...] 
    step = .02 
    # to plot the boundary, we're going to create a matrix of every possible point 
    # then label each point as a wolf or cow using our classifier 
    xx, yy = np.meshgrid(np.arange(x_min, x_max, step),
np.arange(y_min, y_max, step)) 
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]) 
    # this gets our predictions back into a matrix 
    ZZ = Z.reshape(xx.shape) 
  
    # create a subplot (we're going to have more than 1 plot on a given image) 
    pl.subplot(2, 2, plt_nmbr) 
    # plot the boundaries 
    pl.pcolormesh(xx, yy, Z, cmap=pl.cm.Paired) 
  
    # plot the wolves and cows 
    for animal in df.animal.unique(): 
        pl.scatter(df[df.animal==animal].x, 
                   df[df.animal==animal].y, 
                   marker=animal, 
                   label="cows" if animal=="x" else "wolves", 
                   color='black', 
                   c=df.animal_type, cmap=pl.cm.Paired) 
    pl.title(clf_name) 
    pl.legend(loc="best") 
  
  
data = open("cows_and_wolves.txt").read() 
data = [row.split('\t') for row in data.strip().split('\n')] 
  
animals = [] 
for y, row in enumerate(data): 
    for x, item in enumerate(row): 
        # x's are cows, o's are wolves 
        if item in ['o', 'x']: 
            animals.append([x, y, item]) 
  
df = pd.DataFrame(animals, columns=["x", "y", "animal"]) 
df['animal_type'] = df.animal.apply(lambda x: 0 if x=="x" else 1) 
  
# train using the x and y position coordiantes 
train_cols = ["x", "y"] 
  
clfs = { 
    "SVM": svm.SVC(), 
    "Logistic" : linear_model.LogisticRegression(), 
    "Decision Tree": tree.DecisionTreeClassifier(), 
} 
  
plt_nmbr = 1 
for clf_name, clf in clfs.iteritems(): 
    clf.fit(df[train_cols], df.animal_type) 
    plot_results_with_hyperplane(clf, clf_name, df, plt_nmbr) 
    plt_nmbr += 1 
pl.show() 
 

 

讓SVM作一些更難的工做吧!.net

誠然,若是自變量和因變量之間的關係是非線性的,是很難接近SVM的準確性。若是仍是難以理解的話,能夠看看下面的例子:假設咱們有一組數據集,它包含了綠色以及紅色的點集。咱們首先標繪一下它們的座標,這些點集構成了一個具體的形狀——擁有着紅色的輪廓,周圍充斥着綠色(看起來就像孟加拉國的國旗)。若是由於某些緣由,咱們丟失了數據集當中1/3的部分,那麼在咱們恢復的時候,咱們就但願尋找一種方法,最大程度地實現這丟失1/3部分的輪廓。

那麼咱們如何推測這丟失1/3的部分最接近什麼形狀?一種方式就是創建一種模型,使用剩下接近80%的數據信息做爲一個「訓練集」。Greg Lamp選擇三種不一樣的數據模型分別作了嘗試:

  • 邏輯模型(GLM)
  • 決策樹模型(DT)
  • SVM 

Greg Lamp對每種數據模型都進行了訓練,而後再利用這些模型推測丟失1/3部分的數據集。咱們能夠看看這些不一樣模型的推測結果:

實現代碼以下:svmflag.py Python

  1.  1 import numpy as np 
     2 import pylab as pl 
     3 import pandas as pd 
     4   
     5 from sklearn import svm 
     6 from sklearn import linear_model 
     7 from sklearn import tree 
     8   
     9 from sklearn.metrics import confusion_matrix 
    10   
    11 x_min, x_max = 0, 15 
    12 y_min, y_max = 0, 10 
    13 step = .1 
    14 # to plot the boundary, we're going to create a matrix of every possible point 
    15 # then label each point as a wolf or cow using our classifier 
    16 xx, yy = np.meshgrid(np.arange(x_min, x_max, step), np.arange(y_min, y_max, step)) 
    17   
    18 df = pd.DataFrame(data={'x': xx.ravel(), 'y': yy.ravel()}) 
    19   
    20 df['color_gauge'] = (df.x-7.5)**2 + (df.y-5)**2 
    21 df['color'] = df.color_gauge.apply(lambda x: "red" if x <= 15 else "green") 
    22 df['color_as_int'] = df.color.apply(lambda x: 0 if x=="red" else 1) 
    23   
    24 print "Points on flag:" 
    25 print df.groupby('color').size() 
    26 print 
    27   
    28 figure = 1 
    29   
    30 # plot a figure for the entire dataset 
    31 for color in df.color.unique(): 
    32     idx = df.color==color 
    33     pl.subplot(2, 2, figure) 
    34     pl.scatter(df[idx].x, df[idx].y, colorcolor=color) 
    35     pl.title('Actual') 
    36   
    37   
    38 train_idx = df.x < 10 
    39   
    40 train = df[train_idx] 
    41 test = df[-train_idx] 
    42   
    43   
    44 print "Training Set Size: %d" % len(train) 
    45 print "Test Set Size: %d" % len(test) 
    46   
    47 # train using the x and y position coordiantes 
    48 cols = ["x", "y"] 
    49   
    50 clfs = { 
    51     "SVM": svm.SVC(degree=0.5), 
    52     "Logistic" : linear_model.LogisticRegression(), 
    53     "Decision Tree": tree.DecisionTreeClassifier() 
    54 } 
    55   
    56   
    57 # racehorse different classifiers and plot the results 
    58 for clf_name, clf in clfs.iteritems(): 
    59     figure += 1 
    60   
    61     # train the classifier 
    62     clf.fit(train[cols], train.color_as_int) 
    63   
    64     # get the predicted values from the test set 
    65     test['predicted_color_as_int'] = clf.predict(test[cols]) 
    66     test['pred_color'] 
    67 = test.predicted_color_as_int.apply(lambda x: "red" if x==0 else "green") 
    68      
    69     # create a new subplot on the plot 
    70     pl.subplot(2, 2, figure) 
    71     # plot each predicted color 
    72     for color in test.pred_color.unique(): 
    73         # plot only rows where pred_color is equal to color 
    74         idx = test.pred_color==color 
    75         pl.scatter(test[idx].x, test[idx].y, colorcolor=color) 
    76   
    77     # plot the training set as well 
    78     for color in train.color.unique(): 
    79         idx = train.color==color 
    80         pl.scatter(train[idx].x, train[idx].y, colorcolor=color) 
    81   
    82     # add a dotted line to show the boundary between the training and test set 
    83     # (everything to the right of the line is in the test set) 
    84     #this plots a vertical line 
    85     train_line_y = np.linspace(y_min, y_max) #evenly spaced array from 0 to 10 
    86     train_line_x = np.repeat(10, len(train_line_y))
    87  #repeat 10 (threshold for traininset) n times 
    88     # add a black, dotted line to the subplot 
    89     pl.plot(train_line_x, train_line_y, 'k--', color="black") 
    90      
    91     pl.title(clf_name) 
    92   
    93     print "Confusion Matrix for %s:" % clf_name 
    94     print confusion_matrix(test.color, test.pred_color) 
    95 pl.show()  

     

結論:

從這些實驗結果來看,毫無疑問,SVM是絕對的優勝者。可是究其緣由咱們不妨看一下DT模型和GLM模型。很明顯,它們都是使用的直線邊界。Greg Lamp的輸入模型在計算非線性的x, y以及顏色之間的關係時,並無包含任何的轉換信息。假如Greg Lamp它們可以定義一些特定的轉換信息,可使GLM模型和DT模型可以輸出更好的效果,他們爲何要浪費時間呢?其實並無複雜的轉換或者壓縮,SVM僅僅分析錯了117/5000個點集(高達98%的準確率,對比而言,DT模型是51%,而GLM模型只有12%!)

侷限性在哪裏?

不少人都有疑問,既然SVM這麼強大,可是爲何不能對一切使用SVM呢?很不幸,SVM最神奇的地方剛好也是它最大的軟肋!複雜的數據轉換信息和邊界的產生結果都難以進行闡述。這也是它經常被稱之爲「black box」的緣由,而GLM模型和DT模型恰好相反,它們很容易進行理解。

相關文章
相關標籤/搜索