Построить поверхность принятия решения для дерева классификационных решений с 3 элементами на двухмерном графике - PullRequest
0 голосов
/ 26 мая 2018

Моя проблема в том, что у меня есть 3 объекта, но я хочу только построить двухмерную графику, используя одновременно 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)

Как я могу построить 2D массив + поезд с 3 объектами, но только 2 объекта и сохранить правильную форму для своего массива Z?Как я могу получить Z до нужного размера?

Что я пробовал до сих пор:

Я хочу что-то вроде этого, вместо шины у меня есть 2 функции, и я могу предсказать только 2 значения, а не 3, как в примере.

Но опять же все примеры, которые я вижу, онитолько тренировка с двумя функциями, так что они хороши, насколько я понимаю, они не сталкиваются с моей проблемой с неправильной формой Z.

Можно ли визуализировать это с помощью 3Dграфический, чтобы мы могли видеть 3 функции?

1 Ответ

0 голосов
/ 26 мая 2018

Я не думаю, что форма / размер - главная проблема здесь.Вы должны выполнить некоторые вычисления, прежде чем сможете построить 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 работать, вам нужно решить, какую Z вы бы хотели назвать из 2 или 3 возможностей.Например, у вас может быть вызов взвешенного класса, например:

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()

enter image description here

Если я правильно понимаю, «визуализировать это с помощью трехмерного графика» будет сложно.У вас есть не только 3 функции, которые делают его 3D, но и вызов класса.В конце концов, вам действительно нужно работать с данными 4D или с плотностью данных в 3D пространстве.Я полагаю, что это может быть причиной того, что трехмерный график пространства принятия решений (уже не поверхностный) не совсем обычен.

...