[Example of Sklearn] - SVM usge

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

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

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做一些更难的工作吧!

诚然,如果自变量和因变量之间的关系是非线性的,是很难接近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模型刚好相反,它们很容易进行理解。

时间: 2024-10-31 17:17:03

[Example of Sklearn] - SVM usge的相关文章

sklearn系列之 sklearn.svm.SVC详解

首先我们应该对SVM的参数有一个详细的认知: sklearn.svm.SVC 参数说明: 本身这个函数也是基于libsvm实现的,所以在参数设置上有很多相似的地方.(PS: libsvm中的二次规划问题的解决算法是SMO). sklearn.svm.SVC(C=1.0, kernel='rbf', degree=3, gamma='auto', coef0=0.0, shrinking=True, probability=False, tol=0.001, cache_size=200, cla

支持向量机 人脸识别(SVM)SKLearn

#!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as np import pylab as pl from sklearn import svm # we create 40 separable points np.random.seed(0)#每次运行结果不变 X = np.r_[np.random.randn(20, 2) - [2, 2], np.random.randn(20, 2) + [2, 2]] #randn2

利用Python sklearn的SVM对AT&amp;T人脸数据进行人脸识别

要求:使用10-fold交叉验证方法实现SVM的对人脸库识别,列出不同核函数参数对识别结果的影响,要求画对比曲线. 使用Python完成,主要参考文献[4],其中遇到不懂的功能函数一个一个的查官方文档和相关资料.其中包含了使用Python画图,遍历文件,读取图片,PCA降维,SVM,交叉验证等知识. 0.数据说明预处理 下载AT&T人脸数据(http://www.cl.cam.ac.uk/research/dtg/attarchive/facedatabase.html),解压缩后为40个文件夹

Python 之 sklearn 计算 SVM 隶属度

python中的sklean已经集成SVM算法,其中包含fit(), predict()等,我们只要输入训练样本和标记,以及模型参数,就可得到分类的结果. 关于这个的代码实现已有很多,SVC 参数详见: 详址:http://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html#sklearn.svm.SVC 但对于libsvm之中实现的隶属度计算仍未找到相似讲解与示例,先给出源码如下. import numpy Data_S

sklearn中SVM调参说明

写在前面 之前只停留在理论上,没有实际沉下心去调参,实际去做了后,发现调参是个大工程(玄学).于是这篇来总结一下sklearn中svm的参数说明以及调参经验.方便以后查询和回忆. 常用核函数 1.linear核函数: K(xi,xj)=xTixjK(xi,xj)=xiTxj 2.polynomial核函数: K(xi,xj)=(γxTixj+r)d,d>1K(xi,xj)=(γxiTxj+r)d,d>1 3.RBF核函数(高斯核函数): K(xi,xj)=exp(−γ||xi−xj||2),γ

sklearn中的SVM

scikit-learn中SVM的算法库分为两类,一类是分类的算法库,包括SVC, NuSVC,和LinearSVC 3个类.另一类是回归算法库,包括SVR, NuSVR,和LinearSVR 3个类.相关的类都包裹在sklearn.svm模块之中. 对于SVC, NuSVC,和LinearSVC 3个分类的类,SVC和 NuSVC差不多,区别仅仅在于对损失的度量方式不同,而LinearSVC从名字就可以看出,他是线性分类,也就是不支持各种低维到高维的核函数,仅仅支持线性核函数,对线性不可分的数

基于sklearn进行线性回归、logistic回归、svm等的简单操作总结

基于sklearn的一些AI算法基本操作 sklearn中的一些相关的库 分别导入这些相关算法的库 import pandas as pd #导入一个用于读取csv数据的容器 from sklearn.model_selection import train_test_split #用于数据集划分的模块 from sklearn.model_selection import GridSearchCV #用于交叉验证的模块 from sklearn.neighbors import KNeighb

sklearn调用SVM算法

1.支撑向量机SVM是一种非常重要和广泛的机器学习算法,它的算法出发点是尽可能找到最优的决策边界,使得模型的泛化能力尽可能地好,因此SVM对未来数据的预测也是更加准确的. 2.SVM既可以解决分类问题,又可以解决回归问题,原理整体相似,不过也稍有不同. 在sklearn章调用SVM算法的代码实现如下所示: #(一)sklearn中利用SVM算法解决分类问题 import numpy as npimport matplotlib.pyplot as pltfrom sklearn import d

sklearn集成支持向量机svm.SVC参数说明

经常用到sklearn中的SVC函数,这里把文档中的参数翻译了一些,以备不时之需. 本身这个函数也是基于libsvm实现的,所以在参数设置上有很多相似的地方.(PS: libsvm中的二次规划问题的解决算法是SMO).sklearn.svm.SVC(C=1.0, kernel='rbf', degree=3, gamma='auto', coef0=0.0, shrinking=True, probability=False, tol=0.001, cache_size=200, class_w