Scikit-learn与数据可视化:为什么我用predict的时候一定要用ravel?
Scikit-learn and data visusalisation: Why do I have to use ravel when I use predict?
我这里有一个函数可以可视化某个分类器(如逻辑回归或简单的感知器模型)所做的分类。但我没有得到几件事:
X 有 n 个示例,只有 2 个特征。
- 为什么我必须使用 xx1.ravel() 和 xx2.ravel() 然后将整个数组转置为 classifier.predict?为什么我不能简单地使用原始维度来预测结果?
2.Why 是否需要将 Z 重塑回原来的 xx1 形状?
为什么需要创建网格来绘制散点图? meshgrid 中的特定点是否像 'pixels' 一样代表网格上的某个点?为什么需要这个?
idx中的idx值是多少,枚举中的cl是多少(np.unique(y)),当我使用unique时得到的只是结果的唯一id?
散点函数中的c = cmap(idx)有什么用?为什么cmap可以接受参数?
后面的问题可能与题目不符,敬请见谅。
代码取自 Python 机器学习一书。
def plot_decision_regions(X, y, classifier, test_idx = None, resolution = 0.002):
#Setup marker generator and color map
markers = ('s', 'x', 'o', '^', 'v')
colors = ('red','blue','green','gray','cyan')
cmap = ListedColormap(colors[:len(np.unique(y))])
#MESHGRID - plot decision surface
x1_min, x1_max = X[:, 0].min(), X[:, 0].max()
x2_min, x2_max = X[:, 1].min(), X[:, 1].max()
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution), np.arange(x2_min, x2_max, resolution))
# print 'meshgrid:', xx1, xx2
#CLASSIFIER PREDICT
Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
Z = Z.reshape(xx1.shape)
plt.contourf(xx1, xx2, Z, alpha = 0.4, cmap=cmap)
plt.xlim(xx1.min(), xx1.max())
plt.ylim(xx2.min(), xx2.max())
for idx, cl in enumerate(np.unique(y)):
plt.scatter(x = X[y == cl, 0], y = X[y == cl, 1], alpha = 0.8, c = cmap(idx), marker = markers[idx], label =cl)
#highlight test samples
if test_idx:
XTest, yTest = X[test_idx, :], y[test_idx]
plt.scatter(XTest[:,0], XTest[:,1], c = '', alpha = 1.0, linewidth = 1, marker = 'o', s = 55, label = 'test set')
这个与 meshgrid 和 ravel 的业务只是一种获取坐标范围的笛卡尔乘积的方法,以获得一组表示区域中各个点的 (x, y) 坐标对。
classifier 期望其输入为 Nx2 数组,其中 N 是样本数(即,您要预测其 class 的案例)。它需要两列,因为有两个特征。
Meshgrid 生成两个数组,一个包含指定矩形区域中点的 X 坐标,另一个包含这些点的 Y 坐标。通过使用 .ravel()
,您可以将这些数组展开到坐标列表中。这只是获取所需坐标范围的笛卡尔积的一种有点令人困惑的方法。换句话说,这个:
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution), np.arange(x2_min, x2_max, resolution))
coord1, coord2 = xx1.ravel(), xx2.ravel()
实际上与此相同:
coord1, coord2 = zip(*itertools.product(np.arange(x1_min, x1_max, resolution), np.arange(x2_min, x2_max, resolution)))
你可以通过一个简单的例子看到这一点:
>>> xx1, xx2 = np.meshgrid(np.arange(3), np.arange(2))
>>> coord1, coord2 = xx1.ravel(), xx2.ravel()
>>> coord1
array([0, 1, 2, 0, 1, 2])
>>> coord2
array([0, 0, 0, 1, 1, 1])
>>> coord1, coord2 = zip(*itertools.product(np.arange(3), np.arange(2)))
>>> coord1
(0, 0, 1, 1, 2, 2)
>>> coord2
(0, 1, 0, 1, 0, 1)
您可以看到那里生成了相同的 x/y 对(尽管它们以不同的顺序生成)。
这里选择 meshgrid 方法可能是因为 contourf 需要它。 contourf
本质上采用 "XY plane" 作为输入(由 X 和 Y 坐标数组组成)以及该平面中每个点的 Z 值数组。
结果是 classifier 和等高线图需要不同格式的输入。 classifier 接受两个单独的值(两个输入特征)和 returns 单个值(它预测的 class)。 contourf
需要点的矩形网格。换句话说,笼统地说,predict
一次要一个X坐标和一个Y坐标,但是contourf
要先所有X坐标,然后再所有Y坐标。您发布的代码正在进行一些重塑以在这两种格式之间进行转换。您以 contourf
想要的格式生成 X 和 Y,并将其重塑为 predict
想要的格式,以便您可以将其传递给 predict
。 predict
为您提供 predict
喜欢的形状的 Z 数据,然后您将其重新整形为 contourf
想要的格式。
我这里有一个函数可以可视化某个分类器(如逻辑回归或简单的感知器模型)所做的分类。但我没有得到几件事:
X 有 n 个示例,只有 2 个特征。
- 为什么我必须使用 xx1.ravel() 和 xx2.ravel() 然后将整个数组转置为 classifier.predict?为什么我不能简单地使用原始维度来预测结果?
2.Why 是否需要将 Z 重塑回原来的 xx1 形状?
为什么需要创建网格来绘制散点图? meshgrid 中的特定点是否像 'pixels' 一样代表网格上的某个点?为什么需要这个?
idx中的idx值是多少,枚举中的cl是多少(np.unique(y)),当我使用unique时得到的只是结果的唯一id?
散点函数中的c = cmap(idx)有什么用?为什么cmap可以接受参数?
后面的问题可能与题目不符,敬请见谅。 代码取自 Python 机器学习一书。
def plot_decision_regions(X, y, classifier, test_idx = None, resolution = 0.002):
#Setup marker generator and color map
markers = ('s', 'x', 'o', '^', 'v')
colors = ('red','blue','green','gray','cyan')
cmap = ListedColormap(colors[:len(np.unique(y))])
#MESHGRID - plot decision surface
x1_min, x1_max = X[:, 0].min(), X[:, 0].max()
x2_min, x2_max = X[:, 1].min(), X[:, 1].max()
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution), np.arange(x2_min, x2_max, resolution))
# print 'meshgrid:', xx1, xx2
#CLASSIFIER PREDICT
Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
Z = Z.reshape(xx1.shape)
plt.contourf(xx1, xx2, Z, alpha = 0.4, cmap=cmap)
plt.xlim(xx1.min(), xx1.max())
plt.ylim(xx2.min(), xx2.max())
for idx, cl in enumerate(np.unique(y)):
plt.scatter(x = X[y == cl, 0], y = X[y == cl, 1], alpha = 0.8, c = cmap(idx), marker = markers[idx], label =cl)
#highlight test samples
if test_idx:
XTest, yTest = X[test_idx, :], y[test_idx]
plt.scatter(XTest[:,0], XTest[:,1], c = '', alpha = 1.0, linewidth = 1, marker = 'o', s = 55, label = 'test set')
这个与 meshgrid 和 ravel 的业务只是一种获取坐标范围的笛卡尔乘积的方法,以获得一组表示区域中各个点的 (x, y) 坐标对。
classifier 期望其输入为 Nx2 数组,其中 N 是样本数(即,您要预测其 class 的案例)。它需要两列,因为有两个特征。
Meshgrid 生成两个数组,一个包含指定矩形区域中点的 X 坐标,另一个包含这些点的 Y 坐标。通过使用 .ravel()
,您可以将这些数组展开到坐标列表中。这只是获取所需坐标范围的笛卡尔积的一种有点令人困惑的方法。换句话说,这个:
xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution), np.arange(x2_min, x2_max, resolution))
coord1, coord2 = xx1.ravel(), xx2.ravel()
实际上与此相同:
coord1, coord2 = zip(*itertools.product(np.arange(x1_min, x1_max, resolution), np.arange(x2_min, x2_max, resolution)))
你可以通过一个简单的例子看到这一点:
>>> xx1, xx2 = np.meshgrid(np.arange(3), np.arange(2))
>>> coord1, coord2 = xx1.ravel(), xx2.ravel()
>>> coord1
array([0, 1, 2, 0, 1, 2])
>>> coord2
array([0, 0, 0, 1, 1, 1])
>>> coord1, coord2 = zip(*itertools.product(np.arange(3), np.arange(2)))
>>> coord1
(0, 0, 1, 1, 2, 2)
>>> coord2
(0, 1, 0, 1, 0, 1)
您可以看到那里生成了相同的 x/y 对(尽管它们以不同的顺序生成)。
这里选择 meshgrid 方法可能是因为 contourf 需要它。 contourf
本质上采用 "XY plane" 作为输入(由 X 和 Y 坐标数组组成)以及该平面中每个点的 Z 值数组。
结果是 classifier 和等高线图需要不同格式的输入。 classifier 接受两个单独的值(两个输入特征)和 returns 单个值(它预测的 class)。 contourf
需要点的矩形网格。换句话说,笼统地说,predict
一次要一个X坐标和一个Y坐标,但是contourf
要先所有X坐标,然后再所有Y坐标。您发布的代码正在进行一些重塑以在这两种格式之间进行转换。您以 contourf
想要的格式生成 X 和 Y,并将其重塑为 predict
想要的格式,以便您可以将其传递给 predict
。 predict
为您提供 predict
喜欢的形状的 Z 数据,然后您将其重新整形为 contourf
想要的格式。