C-支持向量分类理解

Posted

技术标签:

【中文标题】C-支持向量分类理解【英文标题】:C-Support Vector Classification Comprehension 【发布时间】:2017-11-30 13:00:09 【问题描述】:

我有一个关于我在一本书中找到的代码被剪断的问题。 作者创建了两类样本点。接下来,作者学习了一个模型并将 SVC 模型绘制到“斑点”上。 这是截取的代码:

# create 50 separable points
X, y = make_blobs(n_samples=50, centers=2,
                  random_state=0, cluster_std=0.60)

# fit the support vector classifier model
clf = SVC(kernel='linear')
clf.fit(X, y)

# plot the data
fig, ax = plt.subplots(figsize=(8, 6))
point_style = dict(cmap='Paired', s=50)
ax.scatter(X[:, 0], X[:, 1], c=y, **point_style)

# format plot
format_plot(ax, 'Input Data')
ax.axis([-1, 4, -2, 7])


# Get contours describing the model
xx = np.linspace(-1, 4, 10)
yy = np.linspace(-2, 7, 10)
xy1, xy2 = np.meshgrid(xx, yy)
Z = np.array([clf.decision_function([t])
              for t in zip(xy1.flat, xy2.flat)]).reshape(xy1.shape)

line_style = dict(levels = [-1.0, 0.0, 1.0],
                  linestyles = ['dashed', 'solid', 'dashed'],
                  colors = 'gray', linewidths=1)

ax.contour(xy1, xy2, Z, **line_style)

结果如下:

我现在的问题是,为什么我们要创建“xx”和“yy”以及“xy1”和“xy2”?因为实际上我们想要显示 X 和 y 数据的 SVC“函数”,如果我们将 xy1 和 xy2 以及 Z(也是用 xy1 和 xy2 创建的)传递给 meshgrid 函数来绘制网格网格,则没有连接到学习 SVC 模型的数据...不是吗?

谁能给我解释一下,或者推荐一个如何更容易解决这个问题的建议?

感谢您的回答

【问题讨论】:

你查看contour的文档了吗?这是等高线图的常见输入。线条不是手动绘制的,轮廓在这里需要注意,因此这种设置。 @sascha,谢谢。是的,我已经检查了轮廓的文档。但是为什么我们使用 xx 和 xy 分别使用 xy1 和 xy2 而不是 X 和 y?我的意思是 xy1 和 xy2 是从以下创建的人工数组: xx = np.linspace(-1, 4, 10) yy = np.linspace(-2, 7, 10) xy1, xy2 = np.meshgrid(xx, yy) 但是这个数字与我们从中创建“blob”的数据没有任何共同之处。那么我们为什么要使用它们呢? 【参考方案1】:

我将从简短的广泛答案开始。 ax.contour() 只是绘制分离超平面及其“平行”平面的一种方法。你当然可以通过计算平面来绘制它,比如this example。

为了回答您的最后一个问题,在我看来,绘制模型已经是一种相对简单(在数学和逻辑方面)且容易(在编码方面)的方式。当您的分离超平面在数学上不容易描述时(例如用于非线性分离的多项式和 RBF 内核),它尤其有用,例如 this example。

要解决您的第二个问题和 cmets,并回答您的第一个问题,是的,您是对的,xxyyxy1xy2Z 与您的连接都非常有限(模拟斑点)数据。它们用于绘制超平面来描述您的模型。

这应该可以回答您的问题。但是请允许我在这里提供更多详细信息,以防其他人像您一样不熟悉该主题。您的数据与xxyyxy1xy2Z 之间的唯一联系是:

    xxyyxy1xy2 对模拟数据周围的区域进行采样。具体来说,模拟数据以 2 为中心。xx(-1, 4) 之间设置了一个限制,yy(-2, 7) 之间设置了一个限制。可以通过ax.scatter(xy1, xy2)查看“网格”。 Z 是对“网格”中所有样本点的计算。它计算从样本点到分离超平面的归一化距离。 Z 是等高线图上的水平。

ax.contour 然后使用“网格”和Z 绘制等高线。以下是一些关键点:

    xy1xy2 都是二维的,指定表面的 (x, y) 坐标。他们逐行列出该区域中的样本点。 Z 是一个与xy1xy2 形状相同的二维数组。它定义了每个点的级别,以便程序可以“理解” 3 维曲面的形状。 levels = [-1.0, 0.0, 1.0] 表示在相应的层级上有 3 条曲线(本例中为线)要绘制。与 SVC 相关,level 0 是分离超平面;级别 -1 和 1 非常接近(相差一个ζi)到分离超平面的最大边距。 linestyles = ['dashed', 'solid', 'dashed'] 表示分离超平面绘制为实线,两侧的两个平面绘制为虚线。

编辑(回应评论):

如您所说,从数学上讲,决策函数应该是一个符号函数,它告诉我们一个点是 0 级还是 1 级。但是,当您检查Z 中的值时,您会发现它们是连续数据。 decision_function(X) 的工作方式是值的符号表示分类,而绝对值是“样本 X 到分离超平面的距离”,它反映了(某种)预测分类的置信度/显着性。这对模型图至关重要。如果Z 是分类的,则您将拥有使区域像网格而不是单个轮廓线的轮廓线。就像the example 中的颜色网格一样;但您不会在 ax.contour() 中看到这一点,因为它不是等高线图的正确行为。

【讨论】:

非常感谢。但是要完全理解它,对我来说仍然缺少一件事。您说:“[...]xx、yy、xy1、xy2 和 Z 与您的(模拟 blob)数据的连接都非常有限。[...]”。我是对的吗: 1. 我的数据和超平面之间的唯一“连接”是 Z 与:Z = np.array([clf.decision_function([t]) for t in zip(xy1.flat, xy2.flat )]).reshape(xy1.shape) ? 2. Z 为“网格”中的每个点返回,无论该点的级别为 0 还是 1 --> Z 可以这样做,因为 clf “知道”哪个点是 0,哪个点是 1。 关于你的两个想法:1)是的,你是对的。 Z 包含从您的数据中“学习”的超平面的标准化距离。 2) 部分正确。我想说Z 中的值有两条信息,分类和置信度。我的解释对于 cmets 来说太长了。我把它放在我更新的答案中。

以上是关于C-支持向量分类理解的主要内容,如果未能解决你的问题,请参考以下文章

支持向量机算法的理解

SVM(支持向量机)的一点理解

支持向量机通俗导论(理解SVM的三层境界)

机器学习:通俗理解支持向量机SVM及代码实践

006:支持向量机

机器学习基础:通俗理解支持向量机SVM及代码实践