内容简介:支持向量机已经成为一种非常流行的算法。在本文中,我试图对其工作原理给出一个简单的解释,并给出几个使用Python scikit库的示例。支持向量机是一种有监督的机器学习算法,可以用于分类或回归问题。它使用一种称为支持向量机既能进行分类又能进行回归。在本文中,我将重点介绍如何使用SVM进行分类。我将特别关注非线性支持向量机,或者说是使用非线性核的支持向量机。非线性支持向量机意味着算法计算的边界不一定是直线。好处是您可以捕获数据点之间更复杂的关系,而不必自己做困难的转换。缺点是训练时间更长,因为它需要更多的计
支持向量机已经成为一种非常流行的算法。在本文中,我试图对其工作原理给出一个简单的解释,并给出几个使用Python scikit库的示例。
支持向量机是什么?
支持向量机是一种有监督的机器学习算法,可以用于分类或回归问题。它使用一种称为 核技巧 的技术来转换数据,然后根据这些转换在可能的输出之间找到一个最佳边界。简单地说,它做一些非常复杂的数据转换,然后根据定义的标签或输出来划分数据。
那么是什么让它如此伟大呢?
支持向量机既能进行分类又能进行回归。在本文中,我将重点介绍如何使用SVM进行分类。我将特别关注非线性支持向量机,或者说是使用非线性核的支持向量机。非线性支持向量机意味着算法计算的边界不一定是直线。好处是您可以捕获数据点之间更复杂的关系,而不必自己做困难的转换。缺点是训练时间更长,因为它需要更多的计算。
那么核技巧是什么?
核技巧对你获得的数据进行转换。有一些很好的特性,你认为可以用来做一个很好的分类器,然后出来一些你不再认识的数据。这有点像解开一条DNA链。你从这个看起来很难看的数据向量开始,在通过 核技巧 之后,它会被解开并自我复合,直到它现在是一个更大的数据集,通过查看电子表格无法理解。 但是这里有魔力,在扩展数据集时,你的类之间现在有更明显的界限,SVM算法能够计算出更加优化的超平面。
接下来,假设你是一个农民,你有一个问题 - 你需要设置一个围栏,以保护你的奶牛免受狼的攻击。 但是你在哪里建造篱笆? 好吧,如果你是一个真正的 数据驱动农民 ,你可以做的一件事就是建立一个基于你牧场中奶牛和狼的位置的分类器。 通过几种不同类型的分类器,我们看到SVM在从狼群中分离你的奶牛方面做得很好。 我认为这些图也很好地说明了使用非线性分类器的好处。 您可以看到逻辑和决策树模型都只使用直线。
想要重新创建分析
想为自己创造这些图吗?您可以在您的终端或您选择的IDE中运行代码,但是,令人惊讶的是,我推荐Rodeo。它有一个非常棒的弹出式图特性,对于这种类型的分析非常有用。它还附带了已经包含在Windows机器中的Python。
下载Rodeo之后,需要保存来自我的github的原始 cows_and_wolves.txt文件 。确保将工作目录设置为保存文件的位置。
好的,现在只需将下面的代码复制粘贴到Rodeo中,并按行或整个脚本运行它。不要忘记,您可以弹出您的plot选项卡,在窗口中移动,或者调整它们的大小。
# Data driven farmer goes to the Rodeo
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
Z = 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')
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那样准确。 在变量(log(x),(x ^ 2))之间进行转换变得不那么重要了,因为它将在算法中加以考虑。 如果你仍然遇到麻烦,看看你是否可以按照这个例子。
假设我们有一个由绿点和红点组成的数据集。 当用它们的坐标绘制时,这些点形成一个带有绿色轮廓的红色圆圈(看起来很像孟加拉国的旗帜)。
如果以某种方式我们丢失了1/3的数据会发生什么。 如果我们无法恢复它并且我们想找到一种方法来估计缺少的1/3看起来是什么样的。
那么我们如何找出丢失的1/3看起来像什么? 一种方法可能是使用我们拥有的80%数据作为训练集来构建模型。 但是我们使用什么类型的模型? 我们试试以下内容:
- 逻辑模型
- 决策树
- SVM
我对每个模型进行了训练,然后使用每个模型对缺失的1/3数据进行预测。 让我们来看看我们预测的形状是什么样的......
这是用于比较逻辑模型,决策树和SVM的代码。
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()
print
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, color=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, color=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, color=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是赢家,为什么? 那么如果你看一下决策树和GLM模型的预测形状,你会注意到什么? 直线边界。 我们的输入模型不包括任何转换来解释x,y和颜色之间的非线性关系。 鉴于一系列特定的转换,我们绝对可以使GLM和DT表现更好,但为什么要浪费时间? 由于没有复杂的变换或缩放,SVM只错误分类了117/5000点(准确率为98%而DT-51%和GLM-12%!),所有错误分类的点都是红色 - 因此略有凸起。
何时不使用它
那么为什么不将SVM用于一切呢? 不幸的是,SVM的神奇之处也是最大的缺点。 复杂的数据变换和产生的边界平面很难解释 。 这就是为什么它通常被称为黑匣子。 相反,GLM和决策树恰恰相反。 很容易理解DT和GLM究竟是什么和为什么会以牺牲性能为代价的。
更多资源
想进一步了解SVM? 这是我遇到的一些好资源:
- SVM新手教程 :麻省理工学院的Zoya Gavrilov教授的一些基础知识
- 初学者SVM算法的工作原理 :ThalesSehnKörting的视频
- 来自纽约大学和范德比尔特生物医学的 中级支持向量机介绍
原文链接: https://www.kdnuggets.com/2017/02/yhat-support-vector-machine.html
版权声明: 作者保留权利。文章为作者独立观点,不代表数据人网立场。严禁修改,转载请注明原文链接:http://shujuren.org/article/790.html
数据人网: 数据人学习,交流和分享的平台,诚邀您创造和分享数据知识,共建和共享数据智库。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。