zoukankan      html  css  js  c++  java
  • 程序员训练机器学习 SVM算法分享

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

    摘要:支持向量机(SVM)已经成为一种非常受欢迎的算法。本文主要阐述了SVM是如何进行工作的,同时也给出了使用Python Scikits库的几个示例。SVM作为一种训练机器学习的算法,可以用于解决分类和回归问题,还使用了kernel trick技术进行数据的转换,再根据转换信息在可能的输出之中找到一个最优的边界。

    【CSDN报道】支持向量机(Support Vector Machine)已经成为一种非常受欢迎的算法。在这篇文章里,Greg Lamp简单解释了它是如何进行工作的,同时他也给出了使用Python Scikits库的几个示例。所有代码在Github上都是可用的,Greg Lamp以后还会对使用Scikits以及Sklearn的细节问题进行更深一步的阐述。CSDN对本篇技术性文章进行了编译整理:

    SVM是什么?

    SVM是一种训练机器学习的算法,可以用于解决分类和回归问题,同时还使用了一种称之为kernel trick的技术进行数据的转换,然后再根据这些转换信息,在可能的输出之中找到一个最优的边界。简单来说,就是做一些非常复杂的数据转换工作,然后根据预定义的标签或者输出进而计算出如何分离用户的数据。

    是什么让它变得如此的强大?

    当然,对于SVM来说,完全有能力实现分类以及回归。在这篇文章中,Greg Lamp主要关注如何使用SVM进行分类,特别是非线性的SVM或者SVM使用非线性内核。非线性SVM意味着该算法计算的边界没有必要是一条直线,这样做的好处在于,可以捕获更多数据点集之间的复杂关系,而无需靠用户自己来执行困难的转换。其缺点就是由于更多的运算量,训练的时间要长很多。

    什么是kernel trick?

    kernel trick对接收到的数据进行转换:输入一些你认为比较明显的特征进行分类,输出一些你完全不认识的数据,这个过程就像解开一个DNA链。你开始是寻找数据的矢量,然后把它传给kernel trick,再进行不断的分解和重组直到形成一个更大的数据集,而且通常你看到的这些数据非常的难以理解。这就是神奇之处,扩展的数据集拥有更明显的边界,SVM算法也能够计算一个更加优化的超平面。

    其次,假设你是一个农场主,现在你有一个问题——你需要搭建一个篱笆来防止狼对牛群造成伤害。但是篱笆应该建在哪里呢?如果你是一个以数据为驱动的农场主,那么你就需要在你的牧场上,依据牛群和狼群的位置建立一个“分类器”,比较这几种(如下图所示)不同的分类器,我们可以看到SVM完成了一个很完美的解决方案。Greg Lamp认为这个故事漂亮的说明了使用非线性分类器的优势。显而易见,逻辑模式以及决策树模式都是使用了直线方法。

    实现代码如下:farmer.py  Python 

    1. import numpy as np 
    2. import pylab as pl 
    3. from sklearn import svm 
    4. from sklearn import linear_model 
    5. from sklearn import tree 
    6. import pandas as pd 
    7.   
    8.   
    9. def plot_results_with_hyperplane(clf, clf_name, df, plt_nmbr): 
    10.     x_min, x_max = df.x.min() - .5, df.x.max() + .5 
    11.     y_min, y_max = df.y.min() - .5, df.y.max() + .5 
    12.   
    13.     # step between points. i.e. [0, 0.02, 0.04, ...] 
    14.     step = .02 
    15.     # to plot the boundary, we're going to create a matrix of every possible point 
    16.     # then label each point as a wolf or cow using our classifier 
    17.     xx, yy = np.meshgrid(np.arange(x_min, x_max, step),
    18. np.arange(y_min, y_max, step)) 
    19.     Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]) 
    20.     # this gets our predictions back into a matrix 
    21.     ZZ = Z.reshape(xx.shape) 
    22.   
    23.     # create a subplot (we're going to have more than 1 plot on a given image) 
    24.     pl.subplot(2, 2, plt_nmbr) 
    25.     # plot the boundaries 
    26.     pl.pcolormesh(xx, yy, Z, cmap=pl.cm.Paired) 
    27.   
    28.     # plot the wolves and cows 
    29.     for animal in df.animal.unique(): 
    30.         pl.scatter(df[df.animal==animal].x, 
    31.                    df[df.animal==animal].y, 
    32.                    marker=animal, 
    33.                    label="cows" if animal=="x" else "wolves", 
    34.                    color='black', 
    35.                    c=df.animal_type, cmap=pl.cm.Paired) 
    36.     pl.title(clf_name) 
    37.     pl.legend(loc="best") 
    38.   
    39.   
    40. data = open("cows_and_wolves.txt").read() 
    41. data = [row.split(' ') for row in data.strip().split(' ')] 
    42.   
    43. animals = [] 
    44. for y, row in enumerate(data): 
    45.     for x, item in enumerate(row): 
    46.         # x's are cows, o's are wolves 
    47.         if item in ['o', 'x']: 
    48.             animals.append([x, y, item]) 
    49.   
    50. df = pd.DataFrame(animals, columns=["x", "y", "animal"]) 
    51. df['animal_type'] = df.animal.apply(lambda x: 0 if x=="x" else 1) 
    52.   
    53. # train using the x and y position coordiantes 
    54. train_cols = ["x", "y"] 
    55.   
    56. clfs = { 
    57.     "SVM": svm.SVC(), 
    58.     "Logistic" : linear_model.LogisticRegression(), 
    59.     "Decision Tree": tree.DecisionTreeClassifier(), 
    60.   
    61. plt_nmbr = 
    62. for clf_name, clf in clfs.iteritems(): 
    63.     clf.fit(df[train_cols], df.animal_type) 
    64.     plot_results_with_hyperplane(clf, clf_name, df, plt_nmbr) 
    65.     plt_nmbr += 1 
    66. pl.show() 
    67.  

    让SVM做一些更难的工作吧!

    诚然,如果自变量和因变量之间的关系是非线性的,是很难接近SVM的准确性。如果还是难以理解的话,可以看看下面的例子:假设我们有一组数据集,它包含了绿色以及红色的点集。我们首先标绘一下它们的坐标,这些点集构成了一个具体的形状——拥有着红色的轮廓,周围充斥着绿色(看起来就像孟加拉国的国旗)。如果因为某些原因,我们丢失了数据集当中1/3的部分,那么在我们恢复的时候,我们就希望寻找一种方法,最大程度地实现这丢失1/3部分的轮廓。

    那么我们如何推测这丢失1/3的部分最接近什么形状?一种方式就是建立一种模型,使用剩下接近80%的数据信息作为一个“训练集”。Greg Lamp选择三种不同的数据模型分别做了尝试:

    • 逻辑模型(GLM)
    • 决策树模型(DT)
    • SVM 

    Greg Lamp对每种数据模型都进行了训练,然后再利用这些模型推测丢失1/3部分的数据集。我们可以看看这些不同模型的推测结果:

    实现代码如下:svmflag.py Python

    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 = 
    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. # racehorse different classifiers and plot the results 
    57. for clf_name, clf in clfs.iteritems(): 
    58.     figure += 1 
    59.   
    60.     # train the classifier 
    61.     clf.fit(train[cols], train.color_as_int) 
    62.   
    63.     # get the predicted values from the test set 
    64.     test['predicted_color_as_int'] = clf.predict(test[cols]) 
    65.     test['pred_color'] 
    66. = test.predicted_color_as_int.apply(lambda x: "red" if x==0 else "green") 
    67.      
    68.     # create a new subplot on the plot 
    69.     pl.subplot(2, 2, figure) 
    70.     # plot each predicted color 
    71.     for color in test.pred_color.unique(): 
    72.         # plot only rows where pred_color is equal to color 
    73.         idx = test.pred_color==color 
    74.         pl.scatter(test[idx].x, test[idx].y, colorcolor=color) 
    75.   
    76.     # plot the training set as well 
    77.     for color in train.color.unique(): 
    78.         idx = train.color==color 
    79.         pl.scatter(train[idx].x, train[idx].y, colorcolor=color) 
    80.   
    81.     # add a dotted line to show the boundary between the training and test set 
    82.     # (everything to the right of the line is in the test set) 
    83.     #this plots a vertical line 
    84.     train_line_y = np.linspace(y_min, y_max) #evenly spaced array from 0 to 10 
    85.     train_line_x = np.repeat(10, len(train_line_y))
    86.  #repeat 10 (threshold for traininset) n times 
    87.     # add a black, dotted line to the subplot 
    88.     pl.plot(train_line_x, train_line_y, 'k--', color="black") 
    89.      
    90.     pl.title(clf_name) 
    91.   
    92.     print "Confusion Matrix for %s:" % clf_name 
    93.     print confusion_matrix(test.color, test.pred_color) 
    94. 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模型刚好相反,它们很容易进行理解。(编译/@CSDN王鹏,审校/仲浩)

    本文为CSDN编译整理,未经允许不得转载。如需转载请联系market@csdn.net

  • 相关阅读:
    0309. Best Time to Buy and Sell Stock with Cooldown (M)
    0621. Task Scheduler (M)
    0106. Construct Binary Tree from Inorder and Postorder Traversal (M)
    0258. Add Digits (E)
    0154. Find Minimum in Rotated Sorted Array II (H)
    0797. All Paths From Source to Target (M)
    0260. Single Number III (M)
    0072. Edit Distance (H)
    0103. Binary Tree Zigzag Level Order Traversal (M)
    0312. Burst Balloons (H)
  • 原文地址:https://www.cnblogs.com/DjangoBlog/p/4206921.html
Copyright © 2011-2022 走看看