如何创建具有多个分类特征的 SVM?
Posted
技术标签:
【中文标题】如何创建具有多个分类特征的 SVM?【英文标题】:How to create an SVM with multiple features for classification? 【发布时间】:2017-08-17 11:16:55 【问题描述】:我正在编写一段代码来使用 opencv 识别不同的 2D 形状。我从 2D 形状的每个图像中获取 4 组数据,这些数据存储在多维数组 featureVectors 中。
我正在尝试编写一个考虑从图像中获得的所有 4 个特征的 svm/svc。我已经能够使其仅使用 2 个功能,但是当我尝试所有 4 个功能时,我的图表看起来像这样。
My Graph which is incorrect
我对 featureVectors 的价值观是:
[[ 4.00000000e+00 1.74371349e-03 6.49705560e-01 9.07957236e+01]
[ 4.00000000e+00 4.60937436e-02 1.97642179e-01 9.02041472e+01]
[ 1.00000000e+00 1.18553450e-03 3.03491372e-01 6.03489082e+01]
[ 1.00000000e+00 1.54552898e-02 8.38091425e-01 1.09021207e+02]
[ 3.00000000e+00 1.69961646e-02 4.13691915e+01 1.36838300e+02]]
我的标签是:
[[2]
[2]
[0]
[0]
[1]]
这是我的 SVM 代码:
#Saving featureVectors to a csv file
values1 = featureVectors
header1 = ["Number of Sides", "Standard Deviation of Number of Sides/Perimeter",
"Standard Deviation of the Angles", "Largest Angle"]
my_df = pd.DataFrame(featureVectors)
my_df.to_csv('featureVectors.csv', index=True, header=header1)
#Saving labels to a csv file
values2 = labels
header2 = ["Label"]
my_df = pd.DataFrame(labels)
my_df.to_csv('labels.csv', index=True, header=header2)
#Writing the SVM
def Build_Data_Set(features = header1, features1 = header2):
data_df = pd.DataFrame.from_csv("featureVectors.csv")
#data_df = data_df[:250]
X = np.array(data_df[features].values)
data_df2 = pd.DataFrame.from_csv("labels.csv")
y = np.array(data_df2[features1].values)
#print(X)
#print(y)
return X,y
def Analysis():
X,y = Build_Data_Set()
clf = svm.SVC(kernel = 'linear', C = 1.0)
clf.fit(X, y)
w = clf.coef_[0]
a = -w[0] / w[1]
xx = np.linspace(0,5)
yy = np.linspace(0,185)
h0 = plt.plot(xx,yy, "k-", label="non weighted")
plt.scatter(X[:, 0],X[:, 1],c=y)
plt.ylabel("Maximum Angle (Degrees)")
plt.xlabel("Number Of Sides")
plt.title('Shapes')
plt.legend()
plt.show()
Analysis()
到目前为止,我只使用了 5 个数据集(形状),因为我知道它无法正常工作。
【问题讨论】:
您的 SVM 代码是正确的 - 我认为您的绘图代码是正确的。你为什么要绘制X[:, 0], X[:, ]
?你应该在绘制plt.scatter(X[:, 0], y)
。
@mprat 我发现的另一个示例(我无法再次找到链接)说要这样做,如果我将其更改为 plt.scatter(X[:, 0], y) 我会得到相同的图表但现在所有的点都是相同的颜色
好吧,至少该图现在正确地绘制了您的 y 坐标。如果您想更改颜色,请执行plt.scatter(X[:, 0], y, c=y)
。但回到你最初的问题 - 为什么你认为你的 SVM 没有正确训练?通常在机器学习中,你有一个测试集和一个训练集。您在测试集上训练您的 SVM,并在测试集上测量您的准确性(分析上,而不是视觉上)。你这里没有测试集,那你为什么认为你的模型做错了什么?
@mprat 老实说,我对机器学习非常陌生,对一般的编码也比较陌生。我希望这是它的工作原理,但显然不是。所有点的最大角度为 0,这是不正确的。所以你是说我的代码实际上是在查看所有四个特性,只是没有正确地绘制它们(或者我不认为它是)?
首先,你从来没有真正使用你的学习函数来预测任何事情。您只是在绘制一条与您的模型无关的线,以及一些取自您的训练特征但与您尝试预测的实际类无关的点。您永远不会在数据上运行模型来查看它实际预测的内容。为此,您需要在一些您知道正确结果应该是什么的数据上运行模型,并查看差异。这些数据应该是您没有用于训练的数据(即称为测试数据)。
【参考方案1】:
您的代码中的 SVM 部分实际上是正确的。它周围的绘图部分不是,鉴于代码我会尝试给你一些指示。
首先:
我发现的另一个示例(我无法再次找到链接)说要这样做
在不理解代码的情况下复制代码可能会导致比解决的问题更多的问题。鉴于您的代码,我假设您使用 this 示例作为入门。
plt.scatter(X[:, 0],X[:, 1],c=y)
在 sk-learn 示例中,此 sn-p 用于绘制数据点,并根据它们的标签对它们进行着色。这是可行的,因为在示例中我们正在处理二维数据,所以这很好。您正在处理的数据是 4 维的,因此您实际上只是在绘制前两个维度。
plt.scatter(X[:, 0], y, c=y)
另一方面是没有意义的。
xx = np.linspace(0,5)
yy = np.linspace(0,185)
h0 = plt.plot(xx,yy, "k-", label="non weighted")
您的决策边界实际上与实际决策边界无关。这只是坐标系中 y 在 x 上的图。 (除此之外,您正在处理多类数据,因此您将拥有与类一样多的决策边界。)
现在您的实际问题是数据维度。您正在尝试在 2d 图中绘制 4 维数据,这根本行不通。 一种可能的方法是执行降维以将您的 4d 数据映射到较低维空间,因此,如果您愿意,我建议您阅读例如the excellent sklearn documentation 介绍 SVM,另外 something about dimensionality reduction.
【讨论】:
以上是关于如何创建具有多个分类特征的 SVM?的主要内容,如果未能解决你的问题,请参考以下文章
在 CNN 提取特征之上使用 SVM - 如何进行多类分类?
如何在 sklearn.svm.libsvm.fit() 分类器中包含列表类型功能?