Почему DecisionTreeClassifier (0.23.1 sklearn) дает разные результаты в зависимости от порядка столбцов входных данных? - PullRequest
1 голос
/ 26 мая 2020

При изменении порядка столбцов ввода для sklearn DecisionTreeClassifier точность, похоже, меняется. Так быть не должно. Что я делаю не так?

from sklearn.datasets import load_iris
import numpy as np

iris = load_iris()

X = iris['data']
y = iris['target']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.90, random_state=0)


clf = DecisionTreeClassifier(random_state=0)
clf.fit(X_train, y_train)
print(clf.score(X_test, y_test))

clf = DecisionTreeClassifier(random_state=0)
clf.fit(np.hstack((X_train[:,1:], X_train[:,:1])), y_train)
print(clf.score(X_test, y_test))

clf = DecisionTreeClassifier(random_state=0)
clf.fit(np.hstack((X_train[:,2:], X_train[:,:2])), y_train)
print(clf.score(X_test, y_test))

clf = DecisionTreeClassifier(random_state=0)
clf.fit(np.hstack((X_train[:,3:], X_train[:,:3])), y_train)
print(clf.score(X_test, y_test))

Выполнение этого кода приводит к следующему выводу:

0.9407407407407408
0.22962962962962963
0.34074074074074073
0.3333333333333333

Это задавалось 3 года go, но опрошенный был отклонен, потому что нет код был предоставлен. Влияет ли порядок функций на алгоритм дерева решений в sklearn?


Edit

В приведенном выше коде я забыл применить изменение порядка столбцов к тестовые данные.

Я обнаружил, что разные результаты сохраняются и при применении переупорядочения ко всему набору данных.

Сначала я импортирую данные и превращаю их в pandas фрейм данных.

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
import numpy as np

iris = load_iris()
y = iris['target']
iris_features = iris['feature_names']
iris = pd.DataFrame(iris['data'], columns=iris['feature_names'])

Затем я выбираю все данные, используя исходные упорядоченные имена функций. Я тренирую и оцениваю модель.

X = iris[iris_features].values
print(X.shape[1], iris_features)
# 4 ['petal length (cm)', 'petal width (cm)', 'sepal length (cm)', 'sepal width (cm)']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.95, random_state=0)

clf = DecisionTreeClassifier(random_state=0)
clf.fit(X_train, y_train)
pred = clf.predict(X_test)

print(np.mean(y_test == pred))
# 0.7062937062937062

Почему я все равно получаю разные результаты? Затем я выбираю другой порядок тех же столбцов для обучения и оценки модели.

X = iris[iris_features[2:]+iris_features[:2]].values
print(X.shape[1], iris_features[2:]+iris_features[:2])
# 4 ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.95, random_state=0)

clf = DecisionTreeClassifier(random_state=0)
clf.fit(X_train, y_train)
pred = clf.predict(X_test)

print(np.mean(y_test == pred))
# 0.8881118881118881

1 Ответ

3 голосов
/ 26 мая 2020

Вы пропустили применение столбца упорядочивания в тестовых данных (X_test). Если вы сделаете то же самое с данными теста, вы получите такой же балл.

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
import numpy as np

iris = load_iris()

X = iris['data']
y = iris['target']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.90, random_state=0)


def shuffle_data(data, n):
    return np.hstack((data[:,n:], data[:,:n]))

clf = DecisionTreeClassifier(random_state=0)
clf.fit(X_train, y_train)
print(clf.score(X_test, y_test))
# 0.9407407407407408

clf = DecisionTreeClassifier(random_state=0)
clf.fit(shuffle_data(X_train,1), y_train)
print(clf.score(shuffle_data(X_test,1), y_test))
# 0.9407407407407408

clf = DecisionTreeClassifier(random_state=0)
clf.fit(shuffle_data(X_train,2), y_train)
print(clf.score(shuffle_data(X_test,2), y_test))
# 0.9407407407407408

clf = DecisionTreeClassifier(random_state=0)
clf.fit(shuffle_data(X_train,3), y_train)
print(clf.score(shuffle_data(X_test,3), y_test))
# 0.9407407407407408

Обновление:

Во втором примере вы устанавливаете test_size равным 0,95, в результате чего у вас остается только 7 точек данных, а их классы - array([0, 0, 0, 2, 1, 2, 0]).

Если вы измеряете оценку обучения дерева решений в обоих случаях, это 1.0. Это говорит нам о том, что модель нашла оптимальное разделение в обоих сценариях ios.

Простой ответ - да, результаты будут отличаться при изменении порядка столбцов, при различной комбинации правил (другое условие разделения) может привести к идеальному разделению точек данных (точность 100%).

Используя plot_tree, мы можем визуализировать дерево. Здесь нам нужно разобраться в реализации DecisionTree. Этот ответ цитирует важный момент из документации:

Известно, что проблема изучения дерева оптимальных решений является NP-полной с точки зрения нескольких аспектов оптимальности и даже для простых концепций. . Следовательно, практические алгоритмы обучения дереву решений основаны на эвристических алгоритмах c, таких как жадный алгоритм, в котором локально оптимальные решения принимаются в каждом узле. Такие алгоритмы не могут гарантировать получение глобально оптимального дерева решений. Это можно смягчить путем обучения нескольких деревьев в учащемся ансамбля, где функции и образцы выбираются случайным образом с заменой.

image image

Точка, которая нам нужна Сконцентрируемся здесь на том, что practical decision-tree learning algorithms are based on heuristic algorithms such as the greedy algorithm where locally optimal decisions are made at each node при использовании жадного алгоритма изменение порядка столбцов может повлиять на его результаты.

В то же время, когда в вашем наборе данных больше точек данных (когда их нет в вашем примере), маловероятно, что вы получите разные результаты при изменении порядка столбцов.

Даже в этом примере, когда установлено test_size=0.90, мы можем получить такое же количество очков, как 0.9407407407407408.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...