程序员训练机器学习 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
- 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
- import numpy as np
- import pylab as pl
- import pandas as pd
- from sklearn import svm
- from sklearn import linear_model
- from sklearn import tree
- from sklearn.metrics import confusion_matrix
- x_min, x_max = 0, 15
- y_min, y_max = 0, 10
- step = .1
- # 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))
- df = pd.DataFrame(data={'x': xx.ravel(), 'y': yy.ravel()})
- df['color_gauge'] = (df.x-7.5)**2 + (df.y-5)**2
- df['color'] = df.color_gauge.apply(lambda x: "red" if x <= 15 else "green")
- df['color_as_int'] = df.color.apply(lambda x: 0 if x=="red" else 1)
- print "Points on flag:"
- print df.groupby('color').size()
- figure = 1
- # plot a figure for the entire dataset
- for color in df.color.unique():
- idx = df.color==color
- pl.subplot(2, 2, figure)
- pl.scatter(df[idx].x, df[idx].y, colorcolor=color)
- pl.title('Actual')
- train_idx = df.x < 10
- train = df[train_idx]
- test = df[-train_idx]
- print "Training Set Size: %d" % len(train)
- print "Test Set Size: %d" % len(test)
- # train using the x and y position coordiantes
- cols = ["x", "y"]
- clfs = {
- "SVM": svm.SVC(degree=0.5),
- "Logistic" : linear_model.LogisticRegression(),
- "Decision Tree": tree.DecisionTreeClassifier()
- }
- # racehorse different classifiers and plot the results
- for clf_name, clf in clfs.iteritems():
- figure += 1
- # train the classifier
- clf.fit(train[cols], train.color_as_int)
- # get the predicted values from the test set
- test['predicted_color_as_int'] = clf.predict(test[cols])
- test['pred_color']
- = test.predicted_color_as_int.apply(lambda x: "red" if x==0 else "green")
- # create a new subplot on the plot
- pl.subplot(2, 2, figure)
- # plot each predicted color
- for color in test.pred_color.unique():
- # plot only rows where pred_color is equal to color
- idx = test.pred_color==color
- pl.scatter(test[idx].x, test[idx].y, colorcolor=color)
- # plot the training set as well
- for color in train.color.unique():
- idx = train.color==color
- pl.scatter(train[idx].x, train[idx].y, colorcolor=color)
- # add a dotted line to show the boundary between the training and test set
- # (everything to the right of the line is in the test set)
- #this plots a vertical line
- train_line_y = np.linspace(y_min, y_max) #evenly spaced array from 0 to 10
- train_line_x = np.repeat(10, len(train_line_y))
- #repeat 10 (threshold for traininset) n times
- # add a black, dotted line to the subplot
- pl.plot(train_line_x, train_line_y, 'k--', color="black")
- pl.title(clf_name)
- print "Confusion Matrix for %s:" % clf_name
- print confusion_matrix(test.color, test.pred_color)
- 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
程序员训练机器学习 SVM算法分享的更多相关文章
- PHP 程序员学数据结构与算法之《栈》
“要成高手,必练此功”. 要成为优秀的程序员,数据结构和算法是必修的内容.而现在的Web程序员使用传统算法和数据结构都比较少,因为很多算法都是包装好的,不用我们去操心具体的实现细节,如PHP的取栈 ...
- 程序员Y先生投保案例分享
大家好,我是闲鱼君.我在2018年底搞了个副业,做了保险经纪人.保险经纪人是为用户服务的第三方机构,找经纪人买保险省钱.省力.保险一次就买对,而且还能提供后续理赔服务,具体可以看我的文章<201 ...
- 移动端开发语言的未来的猜想#华为云·寻找黑马程序员#【华为云技术分享】
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...
- 写给程序员的机器学习入门 (二) - pytorch 与矩阵计算入门
pytorch 简介 pytorch 是目前世界上最流行的两个机器学习框架的其中之一,与 tensoflow 并峙双雄.它提供了很多方便的功能,例如根据损失自动微分计算应该怎样调整参数,提供了一系列的 ...
- 写给程序员的机器学习入门 (九) - 对象识别 RCNN 与 Fast-RCNN
因为这几个月饭店生意恢复,加上研究 Faster-RCNN 用掉了很多时间,就没有更新博客了.这篇开始会介绍对象识别的模型与实现方法,首先会介绍最简单的 RCNN 与 Fast-RCNN 模型,下一篇 ...
- 写给程序员的机器学习入门 (十) - 对象识别 Faster-RCNN - 识别人脸位置与是否戴口罩
每次看到大数据人脸识别抓逃犯的新闻我都会感叹技术发展的太快了,国家治安水平也越来越好了
- 程序员用于机器学习编程的Python 数据处理库 pandas 进阶教程
数据访问 在入门教程中,我们已经使用过访问数据的方法.这里我们再集中看一下. 注:这里的数据访问方法既适用于Series,也适用于DataFrame. **基础方法:[]和. 这是两种最直观的方法,任 ...
- 程序员用于机器学习编程的Python 数据处理库 pandas 入门教程
入门介绍 pandas适合于许多不同类型的数据,包括: · 具有异构类型列的表格数据,例如SQL表格或Excel数据 · 有序和无序(不一定是固定频率)时间序列数据. · 具有行列标签的任意矩阵数据( ...
- 写给程序员的机器学习入门 (八 补充) - 使用 GPU 训练模型
在之前的文章中我训练模型都是使用的 CPU,因为家中黄脸婆不允许我浪费钱买电脑.终于的,附近一个废品回收站的朋友转让给我一台破烂旧电脑,所以我现在可以体验使用 GPU 训练模型了
随机推荐
- Xcode6 iOS7模拟器和Xcode7 iOS8模拟器离线下载
Xcode6 只支持iOS7和iOS8的模拟器 Xcode7 只支持iOS9和iOS8的模拟器 Xcode 并不会识别 SDKs 目录下的模拟器,我经过一些尝试以后,发现要放在这个目录下: /Libr ...
- MongoDB简单使用 —— 驱动
C#中可以通过官方的驱动MongoDB.Drvier来使用,使用Nuget安装即可. Install-Package MongoDB.Driver Bson文档操作: using MongoDB.Bs ...
- Linux 下smi/mdio总线通信
Linux 下smi/mdio总线通信 韩大卫@吉林师范大学 下面代码描述了在用户层访问smi/mdio总线, 读写phy芯片寄存器的通用代码.Linux内核2.6以上通用. 将下面代码编译后,将可执 ...
- socket recv阻塞与非阻塞error总结
recv是socket编程中最常用的函数之一,在阻塞状态的recv有时候会返回不同的值,而对于错误值也有相应的错误码,分别对应不同的状态,下面是我针对常见的几种网络状态的简单总结. 首先阻塞接收的re ...
- Hadoop: the definitive guide 第三版 拾遗 第四章
第四章中提到了通过CompressionCodec对streams进行压缩和解压缩,并提供了示例程序: 输入:标准输入流 输出:压缩后的标准输出流 // cc StreamCompressor A p ...
- 用Qemu搭建x86_64学习环境
作者信息 作者:彭东林 邮箱:pengdonglin137@163.com QQ:405728433 软件平台 主机: Ubuntu14.04 64位版本 模拟器:Qemu-2.8.0 Linux内核 ...
- AngularJS自定义Directive初体验
通常我们这样定义个module并随之定义一个controller. var app = angular.module('myApp', []); app.controller('CustomersCo ...
- 在Visual Studio中使用层关系图描述系统架构、技术栈
当需要描述项目的架构或技术栈的时候,可以考虑使用层关系图. 在解决方案下添加一个名称为"TailspinToys.DesignModel"的建模项目. 在新建的建模项目下添加一个名 ...
- SQLServer2008:在查看表记录或者修改存储过程时出现错误。错误消息为: 目录名无效
登陆数据库后,右键打开表提示:目录名无效,执行SQL语句也提示有错误,本来想重装的这个肯定能解决,但是这个方法真的不视为上上策啊,于是在网上找到了这个解决办法,还真是立即见效啊!分享给大家,希望有帮助 ...
- source insight设置tab键为4个空格
首先通过路径(Options->Document Options)进入以下界面: step 1:将 Visible tabs 打勾. step 2 :将 Expand Tabs 打勾. step ...