我的问题是我有3个功能,但我只想绘制2D图形,同时使用2个功能并显示所有可能的组合。
问题是我做了classifier.fit(X_train, Y_train)
所以它希望训练有3个功能,而不仅仅是2. X_train
是大小(70,3),即(n_samples,n_features)。
到目前为止,我调整了原始代码以添加z_min
和z_max
,因为我需要有第三个功能,我需要能够使用classifier.predict()
。
我在plt.contourf
指令中遇到的错误是Input z must be a 2D array.
import matplotlib as pl
import matplotlib.colors as colors
import matplotlib.cm as cmx
x_min, x_max = X_train[:, 0].min() - 1, X_train[:, 0].max() + 1
y_min, y_max = X_train[:, 1].min() - 1, X_train[:, 1].max() + 1
z_min, z_max = X_train[:, 2].min() - 1, X_train[:, 2].max() + 1
xx, yy, zz = np.meshgrid(np.arange(x_min, x_max, 0.1),
np.arange(y_min, y_max, 0.1),
np.arange(z_min, z_max, 0.1))
fig, ax = plt.subplots()
# here "model" is your model's prediction (classification) function
Z = classifier.predict(np.c_[np.c_[xx.ravel(), yy.ravel()], zz.ravel()])
# Put the result into a color plot
Z = Z.reshape(len(Z.shape), 2)
plt.contourf(xx, yy, Z, cmap=pl.cm.Paired)
plt.axis('off')
# Plot also the training points
plt.scatter(X[:, 0], X[:, 1], c=Y, cmap=pl.cm.Paired)
print(z.shape)
= (4612640,)
print(xx.shape)
= (20, 454, 508)
如何绘制具有3个特征的2D阵列+火车,但仅绘制2个特征并保持阵列Z
的正确形状?如何才能使Z
达到合适的尺寸?
到目前为止我尝试了什么:
我想要这样的东西,总线而不是我有2个功能,我只能预测2个值,而不是像示例那样3个。
但是我所看到的所有例子中,他们只训练了2个特征,所以他们很好地从我的理解中解脱出来,他们并没有面对我Z
形状不正确的问题。
是否也可以使用3D图形将其可视化,以便我们可以看到3个功能?
答案 0 :(得分:0)
我不认为形状/大小是这里的主要问题。在为3D要素空间绘制2D决策曲面(contourf
)之前,必须先进行一些计算。正确的等高线图要求每对Z
都有一个定义的值((X, Y)
)。举个例子,看看xx
和yy
:
import pandas as pd
df = pd.DataFrame({'x': xx.ravel(),
'y': yy.ravel(),
'Class': Z.ravel()})
xy_summ = df.groupby(['x', 'y']).agg(lambda x: x.value_counts().to_dict())
xy_summ = (xy_summ.drop('Class', axis=1)
.reset_index()
.join(pd.DataFrame(list(xy_summ.Class)))
.fillna(0))
xy_summ[[0, 1, 2]] = xy_summ[[0, 1, 2]].astype(np.int)
xy_summ.head()
您会发现,对于每对xx
和yy
,您将获得2或3个可能的课程,具体取决于zz
的位置:
xx yy 0 1 2
0 3.3 1.0 25 15 39
1 3.3 1.1 25 15 39
2 3.3 1.2 25 15 39
3 3.3 1.3 25 15 39
4 3.3 1.4 25 15 39
因此,要使2D contourf
工作,您必须决定从2种或3种可能性中调用的Z。例如,您可以进行加权类调用,如:
xy_summ['weighed_class'] = (xy_summ[1] + 2 * xy_summ[2]) / xy_summ[[0, 1, 2]].sum(1)
这将允许您绘制成功的2D图:
import itertools
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
iris = load_iris()
X = iris.data[:, 0:3]
Y = iris.target
clf = DecisionTreeClassifier().fit(X, Y)
plot_step = 0.1
a, b, c = np.hsplit(X, 3)
ar = np.arange(a.min()-1, a.max()+1, plot_step)
br = np.arange(b.min()-1, b.max()+1, plot_step)
cr = np.arange(c.min()-1, c.max()+1, plot_step)
aa, bb, cc = np.meshgrid(ar, br, cr)
Z = clf.predict(np.c_[aa.ravel(), bb.ravel(), cc.ravel()])
datasets = [[0, len(ar), aa],
[1, len(br), bb],
[2, len(cr), cc]]
for i, (xsets, ysets) in enumerate(itertools.combinations(datasets, 2)):
xi, xl, xx = xsets
yi, yl, yy = ysets
df = pd.DataFrame({'x': xx.ravel(),
'y': yy.ravel(),
'Class': Z.ravel()})
xy_summ = df.groupby(['x', 'y']).agg(lambda x: x.value_counts().to_dict())
xy_summ = (xy_summ.drop('Class', axis=1)
.reset_index()
.join(pd.DataFrame(list(xy_summ.Class)))
.fillna(0))
xy_summ['weighed_class'] = (xy_summ[1] + 2 * xy_summ[2]) / xy_summ[[0, 1, 2]].sum(1)
xyz = (xy_summ.x.values.reshape(xl, yl),
xy_summ.y.values.reshape(xl, yl),
xy_summ.weighed_class.values.reshape(xl, yl))
ax = plt.subplot(1, 3, i + 1)
ax.contourf(*xyz, cmap=mpl.cm.Paired)
ax.scatter(X[:, xi], X[:, yi], c=Y, cmap=mpl.cm.Paired, edgecolor='black')
ax.set_xlabel(iris.feature_names[xi])
ax.set_ylabel(iris.feature_names[yi])
plt.show()
如果我理解正确的话,"用3D图形可视化这个"将是困难的。您不仅拥有3个功能,可以实现3D功能,还可以进行课堂通话。最后,您实际上必须使用4D数据,或像3D空间中的数据密度一样。我想这可能就是为什么3D决策空间(不再是真正的表面)图形不常见的原因。