了解scikit learn的OVO SVC模型的多个超平面

2023-01-27 03:02 503 阅读 ID:731
磐创AI
磐创AI

在我最近的帖子中,我向你展示了如何为二进制分类问题解释拟合SVC模型的coef和intercept_属性,以及如何绘制决策平面。如果你还没有读过,我建议你在读这篇文章之前先看看。下面是它的链接:

https://towardsdatascience.com/understanding-the-hyperplane-of-scikit-learns-svc-model-f8515a109222

注意:因为前一篇文章围绕着一个二分类问题,所以它基本上是我们使用的SVM。

在这篇文章中,我们实际上使用了SVC,我们将利用SVC的功能。SVM和SVC的主要区别在于,SVC本质上只是多个SVM的组合,因此允许我们使用多个超平面对多个类进行分类。

本文的主题有点复杂,但我会尽我所能使它易于理解。

创建一些虚拟数据

首先,让我们创建一些数据来使用和可视化。

下面的代码段可以做到这一点:

import numpy as np
import matplotlib.pyplot as plt

X = np.array([
[1.5, 1  ], [1.5, 2  ], [ 2,  1  ], [ 2,  2  ], #upper right (Green)
[1,  -1  ], [1,  -2  ], [ 2, -1  ], [ 2, -2  ], #lower right (Blue)
[-1, -1.5], [-1, -2.5], [-2, -1.5], [-2, -2.5], #lower left (Red)
[-1,  1  ], [-1,  2  ], [-2,  1  ], [-2,  2  ], #upper left (Yellow)
])

y = np.array([
'green','green','green','green',
'blue','blue','blue','blue',
'red','red','red','red',
'yellow','yellow','yellow','yellow',
])

plt.scatter(X[:, 0], X[:, 1], c=y)
plt.show()

这应产生以下曲线:

正如你所见,这些数据显然是线性可分离的,所以线性SVC应该能很好地处理它,而且因为有两个以上的类,我们将需要一个以上的超平面,(直觉应该很容易理解。想象一下,必须画一条直线来分隔四个不同的类。你根本无法做到)。

在数据上拟合SVC

下一步是使用scikit-learn的库在我们的数据上拟合。这可以简单地这样做:

from sklearn.svm import SVC

clf = SVC(kernel='linear')
clf.fit(X, y)

就SVC而言,存在两种创建超平面的方法。一种叫做一对一(OVO),另一种叫做一对剩余(OVR)。我现在将不再详细讨论这个问题,因为这是另一篇文章的主题。

现在,你只需要知道我们将创建一个OVO SVC。简言之,这意味着我们将把每个类与其他类进行比较,并且每个比较都会有一个对应的超平面。

我们可以查看拟合的SVC的coef和intercept_属性,就像我们在上一篇文章中所做的那样。

print('coef_\n', clf.coef_)
print('intercept_', clf.intercept_)

>> coef_
   [[ 0.00000000e+00 -1.00000000e+00]
    [ 9.99532404e-01  2.22044605e-16]
    [ 5.00000000e-01 -5.00000000e-01]
    [ 4.00000000e-01  4.00000000e-01]
    [ 8.00000000e-01  0.00000000e+00]
    [ 0.00000000e+00 -8.00000000e-01]]

>> intercept_
   [ 1.45716772e-16
     4.30211422e-16
     0.00000000e+00
     0.00000000e+00
    -2.00000000e-01
    -2.00000000e-01]

好吧,显然我们得到了6个coef属性的向量和6个intercept_属性的值。这些是我们将用来绘制超平面的值,也用于对新数据点进行分类。

为什么你会问数字6?为了回答这个问题,让我们看看SVC的scikit学习文档:

我们现在可以看到,值6来自以下等式:

在我们的例子中,我们有4个类,因此等式如下:

希望这一点现在已经清楚了。然而,这给我们留下了一个后续问题:哪个coef_vector和intercept_value对应于哪个标签?如上所述,OVO方法将每个类相互比较。这意味着我们比较

标签1对标签2

标签1对标签3

标签1对标签4

标签2对标签3

以此类推……直到所有标签相互比较,(我将在后面的文章中进一步详细介绍如何对新数据点进行分类)

我们的每一个coef_向量都表示这样的比较。但是,我们如何知道哪个向量对应于哪个比较。

为了解决这个问题,我们可以使用以下代码来获得数据和超平面的可视化表示:

line_colors = {0:'red', 1:'blue', 2:'green', 3:'yellow', 4:'black', 5:'gray'}

number_of_coefficients = len(clf.coef_)

figure, axis = plt.subplots(3, 2)
row = 0
col = 0

for j in range(number_of_coefficients):
  for i in range(j+1):
     w = clf.coef_[i]
     w = [w[0], w[1] + 0.0001] #adding 0.0001 just to make sure we       
                               #don't devide by 0
     a = -w[0] / w[1]
     xx = np.linspace(-4,4)
     yy = a * xx - clf.intercept_[i] / w[1]
     axis[row, col].plot(xx, yy, label=f'h{i}', c=line_colors[i])

  axis[row, col].set_xlim([-4, 4])
  axis[row, col].set_ylim([-4, 4])
  axis[row, col].scatter(X[:, 0], X[:, 1], c = y)

  row = row + 1 if col == 1 else row
  col = col + 1 if col != 1 else 0

plt.show()

(为了避免文章太长,我没有对代码片段进行解释,请注意,它用于使用coef_和intercept_值创建绘图)

这将生成以下绘图:

这里发生了很多事情,所以让我们仔细看看。

每个子图都会添加一个额外的超平面。这样,我们可以通过检查刚刚添加的超平面的位置,了解哪些超平面对应于哪个比较。以下是超平面的描述:

  1. 红线将蓝色类与绿色类进行比较。
  2. 蓝线将蓝色类与红色类进行比较。
  3. 绿线将蓝色类与黄色类进行比较。
  4. 黄线将绿色类与红色类进行比较。
  5. 黑线将绿色类与黄色类进行比较。
  6. 灰色线将红色类与黄色类进行比较。

当对新数据点进行分类时,将针对每个超平面测量该点。每次比较后,我们都会注意到它被归类为哪个标签,并将其添加到该标签的累积分数中。最后,新的数据点被简单地标记为得分最高的类。

每个超平面按以下方式对新数据点进行分类:如果该点位于超平面的右侧,则该超平面将该点分类为其比较中的第一个标签。相反,如果点在平面的左侧,则它被标记为超平面比较的第二类。

快速示例:以红线为例,它的第一个标签是蓝色类,第二个标签是绿色类。如果给定的数据指向直线的右侧,则此超平面将其分类为蓝色。

注:为了获得超平面的“右”或“左”,它们需要有一个方向。在这种情况下,红色和灰色线指向右侧,蓝色和黑色线指向上方,黄色线指向左侧,绿色线指向右侧。

新点示例

让我们看一个例子。我们可以画出一个新的点[1.5,-2.5](图中的棕色点),我们预计它将被归类为蓝色点。下面是一个使其更明显的图:

逐个比较(超平面):

  1. 红线将其归类为蓝色
  2. 蓝线将其归类为蓝色
  3. 绿线将其归类为蓝色
  4. 黄线将其归类为红色
  5. 黑线将其归类为绿色
  6. 灰色线条将其归类为红色

新点分为蓝色3次、红色2次和绿色1次。因此,我们用蓝色标签对点进行分类。

如果我们使用拟合模型进行预测,我们应该得到相同的结果。可以通过以下方式完成:

new_point = np.array([[1.5, -2.5]])
print(clf.predict(new_point))

>> ['blue']

我们得到了预期的蓝色标签。

如何确定比较顺序

我希望上面的例子对你来说很容易理解,并且你理解我们是如何得出结论的,关于哪些超平面对应于哪些比较。

然而,这是一个简单的实验,数据很容易分离。这使得我们能够通过目视检查来确定超平面和coef_属性之间的关系。然而,现实世界的数据很可能不那么容易处理。因此,你可能会想,是否有一个系统来确定比较的顺序?

换句话说,我们能确定由coef_[0]表示的超平面总是将蓝色类与绿色类分开的超平面吗?

我得出的结论是,排序是通过对标签进行排序来确定的。

在这个标签是单词的情况下,我注意到前三个超平面coef_[0]、coef_[1]和coef_[2]都与蓝色标签有关。这支持了我的理论,因为蓝色词典(按字母顺序)将作为第一个标签排序。以下两个标签coef_[3]和coef_[4]涉及绿色标签,因为“g”在“b”之后、“r”之前和“y”之前排序。

这可能有点棘手,但仔细想想,这对你来说很有意义。

有了这些关于模型超平面如何工作的信息,你将更好地了解幕后发生的事情。你还可以使用文章中的代码片段绘制超平面。

感谢阅读!

免责声明:作者保留权利,不代表本站立场。如想了解更多和作者有关的信息可以查看页面右侧作者信息卡片。
反馈
to-top--btn