【机器学习实战(三)】sklearn包中SVM算法库的使用

目录

    1. SVM相关知识点回顾
      1.1. SVM与SVR
      1.2. 核函数
    1. sklearn中SVM相关库的简介
    • 2.1. 分类库与回归库
    • 2.2. 高斯核调参
      • 2.2.1. 需要调节的参数
      • 2.2.2. 调参方法:网格搜索
    1. 编程实现

这是《西瓜书带学训练营·实战任务》系列的第三篇笔记

1. SVM相关知识点回顾

1.1. SVM与SVR

  • SVM分类算法

    其原始形式是:

    其中m为样本个数,我们的样本为(x1,y1),(x2,y2),...,(xm,ym)。w,b是我们的分离超平面的w∙ϕ(xi)+b=0系数, ξi为第i个样本的松弛系数, C为惩罚系数。ϕ(xi)为低维到高维的映射函数

    通过拉格朗日函数以及对偶化后的形式为:

  • SVR回归算法

    其中m为样本个数,我们的样本为(x1,y1),(x2,y2),...,(xm,ym)。w,b是我们的回归超平面的w∙xi+b=0系数, ξi,ξi为第i个样本的松弛系数, C为惩罚系数,ϵ为损失边界,到超平面距离小于ϵ的训练集的点没有损失。ϕ(xi)为低维到高维的映射函数。

1.2. 核函数

在scikit-learn中,内置的核函数一共有4种:

  • 线性核函数(Linear Kernel)表达式为:K(x,z)=x∙z,就是普通的内积

  • 多项式核函数(Polynomial Kernel)是线性不可分SVM常用的核函数之一,表达式为:K(x,z)=(γx∙z+r)d ,其中,γ,r,d都需要自己调参定义

  • 高斯核函数(Gaussian Kernel),在SVM中也称为径向基核函数(Radial Basis Function,RBF),它是 libsvm 默认的核函数,当然也是 scikit-learn 默认的核函数。表达式为:K(x,z)=exp(−γ||x−z||2), 其中,γ大于0,需要自己调参定义

  • Sigmoid核函数(Sigmoid Kernel)也是线性不可分SVM常用的核函数之一,表达式为:K(x,z)=tanh(γx∙z+r), 其中,γ,r都需要自己调参定义

一般情况下,对非线性数据使用默认的高斯核函数会有比较好的效果,如果你不是SVM调参高手的话,建议使用高斯核来做数据分析。

2. sklearn中SVM相关库的简介

scikit-learn SVM算法库封装了libsvm 和 liblinear 的实现,仅仅重写了算法了接口部分

2.1. 分类库与回归库

  • 分类算法库

    包括SVC, NuSVC,和LinearSVC 3个类

    对于SVC, NuSVC,和LinearSVC 3个分类的类,SVC和 NuSVC差不多,区别仅仅在于对损失的度量方式不同,而LinearSVC从名字就可以看出,他是线性分类,也就是不支持各种低维到高维的核函数,仅仅支持线性核函数,对线性不可分的数据不能使用

  • 回归算法库

    包括SVR, NuSVR,和LinearSVR 3个类

    同样的,对于SVR, NuSVR,和LinearSVR 3个回归的类, SVR和NuSVR差不多,区别也仅仅在于对损失的度量方式不同。LinearSVR是线性回归,只能使用线性核函数

2.2. 高斯核调参

2.2.1. 需要调节的参数

  • SVM分类模型

    如果是SVM分类模型,这两个超参数分别是惩罚系数CRBF核函数的系数γ

    惩罚系数C

    它在优化函数里主要是平衡支持向量的复杂度和误分类率这两者之间的关系,可以理解为正则化系数

    • 当C比较大时,我们的损失函数也会越大,这意味着我们不愿意放弃比较远的离群点。这样我们会有更加多的支持向量,也就是说支持向量和超平面的模型也会变得越复杂,也容易过拟合

    • 当C比较小时,意味我们不想理那些离群点,会选择较少的样本来做支持向量,最终的支持向量和超平面的模型也会简单

    scikit-learn中默认值是1

    C越大,泛化能力越差,易出现过拟合现象;C越小,泛化能力越好,易出现过欠拟合现象

    BF核函数的参数γ

    RBF 核函数K(x,z)=exp(−γ||x−z||2) γ>0

    γ主要定义了单个样本对整个分类超平面的影响

    • 当γ比较小时,单个样本对整个分类超平面的影响比较小,不容易被选择为支持向量

    • 当γ比较大时,单个样本对整个分类超平面的影响比较大,更容易被选择为支持向量,或者说整个模型的支持向量也会多

    scikit-learn中默认值是 1/样本特征数

    γ越大,训练集拟合越好,泛化能力越差,易出现过拟合现象

    如果把惩罚系数C和RBF核函数的系数γ一起看,当C比较大, γ比较大时,我们会有更多的支持向量,我们的模型会比较复杂,容易过拟合一些。如果C比较小 , γ比较小时,模型会变得简单,支持向量的个数会少

  • SVM回归模型

    SVM回归模型的RBF核比分类模型要复杂一点,因为此时我们除了惩罚系数C和RBF核函数的系数γ之外,还多了一个损失距离度量ϵ

    对于损失距离度量ϵ,它决定了样本点到超平面的距离损失

    • 当 ϵ 比较大时,损失较小,更多的点在损失距离范围之内,而没有损失,模型较简单

    • 当 ϵ 比较小时,损失函数会较大,模型也会变得复杂

    scikit-learn中默认值是0.1

    如果把惩罚系数C,RBF核函数的系数γ和损失距离度量ϵ一起看,当C比较大, γ比较大,ϵ比较小时,我们会有更多的支持向量,我们的模型会比较复杂,容易过拟合一些。如果C比较小 , γ比较小,ϵ比较大时,模型会变得简单,支持向量的个数会少

2.2.2. 调参方法:网格搜索

对于SVM的RBF核,我们主要的调参方法都是交叉验证。具体在scikit-learn中,主要是使用网格搜索,即GridSearchCV类

from sklearn.model_selection import GridSearchCV
grid = GridSearchCV(SVC(), param_grid={"C":[0.1, 1, 10], "gamma": [1, 0.1, 0.01]}, cv=4)
grid.fit(X, y)

将GridSearchCV类用于SVM RBF调参时要注意的参数有:

  1. estimator:即我们的模型,此处我们就是带高斯核的SVC或者SVR

  2. param_grid:即我们要调参的参数列表。 比如我们用SVC分类模型的话,那么param_grid可以定义为{"C":[0.1, 1, 10], "gamma": [0.1, 0.2, 0.3]},这样我们就会有9种超参数的组合来进行网格搜索,选择一个拟合分数最好的超平面系数

  3. cv:S折交叉验证的折数,即将训练集分成多少份来进行交叉验证。默认是3。如果样本较多的话,可以适度增大cv的值

3. 编程实现

  1. 生成测试数据

    from sklearn.datasets import make_circles
    from sklearn.preprocessing import StandardScaler
    
    # 生成一些随机数据用于后续分类
    X, y = make_circles(noise=0.2, factor=0.5, random_state=1) # 生成时加入了一些噪声
    X = StandardScaler().fit_transform(X) # 把数据归一化
    
    

    生成的随机数据可视化结果如下:

  1. 调参

    接着采用网格搜索的策略进行RBF核函数参数搜索

    from sklearn.model_selection import GridSearchCV
    grid = GridSearchCV(SVC(), param_grid={"C":[0.1, 1, 10], "gamma": [1, 0.1, 0.01]}, cv=4) # 总共有9种参数组合的搜索空间
    grid.fit(X, y)
    print("The best parameters are %s with a score of %0.2f"
          % (grid.best_params_, grid.best_score_))
    
    输出为:
    The best parameters are {'C': 10, 'gamma': 0.1} with a score of 0.91
    

    可以对9种参数组合训练的结果进行可视化,观察分类的效果:

    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx, yy = np.meshgrid(np.arange(x_min, x_max,0.02),
                         np.arange(y_min, y_max, 0.02))
    
    for i, C in enumerate((0.1, 1, 10)):
        for j, gamma in enumerate((1, 0.1, 0.01)):
            plt.subplot()       
            clf = SVC(C=C, gamma=gamma)
            clf.fit(X,y)
            Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
    
            # Put the result into a color plot
            Z = Z.reshape(xx.shape)
            plt.contourf(xx, yy, Z, cmap=plt.cm.coolwarm, alpha=0.8)
    
            # Plot also the training points
            plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.coolwarm)
    
            plt.xlim(xx.min(), xx.max())
            plt.ylim(yy.min(), yy.max())
            plt.xticks(())
            plt.yticks(())
            plt.xlabel(" gamma=" + str(gamma) + " C=" + str(C))
            plt.show()
    
1.000 0.100 0.001
0.1
1
10

参考资料:

(1) 刘建平Pinard《scikit-learn 支持向量机算法库使用小结》

(2) 刘建平Pinard《支持向量机高斯核调参小结》

(3) loveliuzz《机器学习sklearn19.0——SVM算法》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容

  • 1. 回顾拉格朗日乘数法 为了找到曲线上的最低点,就从最低的等高线(0那条)开始网上数。数到第三条,等高线终于和曲...
    jiandanjinxin阅读 2,571评论 0 5
  • 本文是scikit-learn 支持向量机的翻译,原文地址:http://scikit-learn.org/sta...
    学以致用123阅读 2,963评论 0 4
  • 【概述】 SVM训练分类器的方法是寻找到超平面,使正负样本在超平面的两侧(分类正确性即“分得开”),且样本到超平面...
    sealaes阅读 10,984评论 0 7
  • 原文章为scikit-learn中"用户指南"-->"监督学习的第四节:Support Vector Machin...
    HabileBadger阅读 2,840评论 0 11
  • 昨天晚上,平安夜,吃完晚饭,来到银座商城,看看有什么便宜商品。来到银座商城,只见地下超市入口上方挂起来五颜六色的彩...
    山水缘阅读 283评论 0 3