Вопрос или проблема
Я получил 100% точности на своем тестовом наборе, используя алгоритм дерева решений, но только 85% точности с использованием случайного леса.
Есть ли что-то не так с моей моделью или дерево решений наиболее подходит для предоставленного набора данных?
Код:
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.20)
#Случайный лес
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_estimators = 1000, random_state = 42)
rf.fit(x_train, y_train);
predictions = rf.predict(x_test)
cm = sklearn.metrics.confusion_matrix(y_test,predictions)
print(cm)
#Дерево решений
from sklearn import tree
clf = tree.DecisionTreeClassifier()
clf = clf.fit(x_train, y_train)
predictions = clf.predict(x_test)
cm = sklearn.metrics.confusion_matrix(y_test,predictions)
Матрица путаницы:
Случайный лес:
[[19937 1]
[ 8 52]]
Дерево решений:
[[19938 0]
[ 0 60]]
Может быть несколько причин, почему это происходит.
-
Прежде всего, проверьте свой код. 100% точности кажется маловероятным в любом окружении. Сколько тестовых данных у вас есть? На сколько тренировочных данных вы обучали свою модель? Вы могли сделать ошибку в коде и сравнить два одинаковых списка.
-
Вы использовали другой тестовый набор для тестирования? Высокая точность может быть связана с удачей – попробуйте использовать некоторые из доступных библиотек KFoldCrossValidation.
-
Вы можете визуализировать ваше дерево решений, чтобы понять, что происходит. Если оно имеет 100% точность на тестовом наборе, имеет ли оно 100% на обучающем наборе?
Параметры по умолчанию для DecisionTreeClassifier
позволяют ему переобучаться на ваших обучающих данных.
По умолчанию min_samples_leaf
равен 1
. По умолчанию max_depth
равен None
. Эта комбинация позволяет вашему DecisionTreeClassifier
расти до тех пор, пока в каждом листе не останется одна точка данных.
Поскольку у вас $100\%$ точности, я предполагаю, что у вас есть дубликаты в ваших разбивках train
и test
. Это не имеет никакого отношения к тому, как вы разбили данные, а скорее к тому, как вы очистили ваши данные.
Можете проверить, есть ли у вас дубликаты данных?
x = [[1, 2, 3],
[4, 5, 6],
[1, 2, 3]]
y = [1,
2,
1]
initial_number_of_data_points = len(x)
def get_unique(X_matrix, y_vector):
Xy = list(set(list(zip([tuple(x) for x in X_matrix], y_vector))))
X_matrix = [list(l[0]) for l in Xy]
y_vector = [l[1] for l in Xy]
return X_matrix, y_vector
x, y = get_unique(x, y)
data_points_removed = initial_number_of_data_points - len(x)
print("Количество удаленных дубликатов:", data_points_removed )
Если у вас есть дубликаты в ваших разбивках train
и test
, это может привести к высоким показателям точности.
Я полагаю, проблема, с которой вы сталкиваетесь, заключается в проблеме дисбаланса классов. У вас 99% данных принадлежит одному классу. Может быть, тестовые данные, которые у вас есть, могут принадлежать только этому классу. Поскольку 99% данных принадлежат одному классу, есть высокая вероятность, что ваша модель предскажет все ваши тестовые данные как этот класс. Чтобы справиться с дисбалансом данных, вам следует использовать AUROC вместо точности. И вы можете использовать такие методы, как оверсэмплинг и андерсэмплинг, чтобы сделать набор данных сбалансированным.
У меня была аналогичная проблема, но я понял, что включил переменную-цель при прогнозировании результатов теста.
ошибка:
predict(object = model_nb, test[,])
без ошибки:
predict(object = model_nb, test[,-16])
где 16-й столбец был для зависимой переменной.
Пожалуйста, проверьте, использовали ли вы свой тестовый набор для построения модели. Это распространенный сценарий, как:
Случайный лес классификатор дает очень высокую точность на тестовом наборе – переобучение?
Если это так, всё становится понятным. Случайный лес пытался не переобучить вашу модель, в то время как дерево решений просто запомнит ваши данные в виде дерева.
Согласен с c zl, по моему опыту это не звучит как стабильная модель и указывает на случайный удачный срез данных. Но что-то, что будет испытывать трудности с обеспечением аналогичных результатов на невидимых данных.
Лучшие модели:
- высокая точность на обучающих данных
- и равно высокая точность на тестовых данных
- и где оба метрики точности не отличаются более чем на 5~10% друг от друга, что, вероятно, показывает стабильность модели. Чем меньше разница, тем лучше, как мне кажется.
Бутстрэппинг и k-fold кросс-валидация обычно должны давать более надежные показатели производительности.
Также проверьте, является ли один из ваших предикторов производной признаков от переменной-цели. Вы можете сделать это, проверив value_counts на вашей переменной-цели и также на переменных, где вы видите слишком много сходства. Не следует использовать производные признаки от переменной-цели в качестве предикторов.
- Как уже упоминалось здесь, деревья решений легко переобучаются с параметрами по умолчанию. Поэтому случайные леса обычно являются лучшим выбором по сравнению с деревьями решений. Рассматривайте их как более обобщенные.
- Почему точности различаются? Случайный лес постоянно использует случайные переменные для использования в алгоритме (для одного дерева), тогда как дерево решений использует все. У вас есть ряд признаков (небольшое количество, я полагаю), которые имеют очень большое влияние на переменную-цель в целом наборе данных. Почему так? Определите, что это за признаки и исследуйте их глубже.
- Теперь, можем ли мы сказать, что дерево решений более стабильно для этой конкретной задачи, чем случайный лес? Я бы сказал, что нет, поскольку ситуация может измениться. Если ваш алгоритм дерева решений зависит от 1-3 важных признаков, вы не можете быть уверены, что эти признаки будут играть такую же значимую роль в будущем.
- Вы можете использовать дерево решений, но имейте в виду, что вам придется постоянно переобучать модель. И сравнивать результаты с случайным лесом.
Итак, мой совет:
- реализуйте важность признаков (вы можете использовать модель случайного леса, чтобы получить их) и используйте только важные;
- используйте какое-либо KFold или StratifiedKFold здесь – это даст вам лучшие результаты;
- пока у вас дисбалансированный набор данных – внедрите class_weight – это должно улучшить результаты случайного леса;
- реализуйте GridSearchCV – это также поможет вам избежать переобучения (и 1000 деревьев – это слишком много, также склонно к переобучению);
- постоянно получайте и оценки на обучающих данных;
- исследуйте важные признаки.
Ответ или решение
Получение 100% точности на тестовом наборе данных всегда вызывает подозрения и требует дополнительной проверки. Ваш случай, где алгоритм дерева решений показывает идеальную точность, а случайный лес — только 85%, может указывать на несколько возможных проблем.
Возможные причины и решения:
-
Проверка на дублирование данных:
Одна из наиболее распространенных причин высокой точности — наличие дублирующихся данных в обучающем и тестовом наборах. Вам следует проверить, есть ли дубликаты в ваших данных. Используйте функции для удаления дубликатов, например:initial_number_of_data_points = len(x) def get_unique(X_matrix, y_vector): Xy = list(set(list(zip([tuple(x) for x in X_matrix], y_vector)))) X_matrix = [list(l[0]) for l in Xy] y_vector = [l[1] for l in Xy] return X_matrix, y_vector x, y = get_unique(x, y) data_points_removed = initial_number_of_data_points - len(x) print("Количество удаленных дубликатов:", data_points_removed)
-
Проверка баланса классов:
Проверьте, сбалансированы ли ваши классы. Если 99% ваших данных принадлежат одному классу, модель может просто предсказывать этот класс в большинстве случаев, что приведет к высокой точности. Рассмотрите возможность использования метрик, таких как AUC-ROC, и примените методы балансировки, такие как oversampling или undersampling. -
Переобучение дерева решений:
Деревья решений по умолчанию склонны к переобучению, если параметры не настроены должным образом (например,max_depth=None
). Это может привести к ситуации, когда модель идеально запоминает обучающие данные, но плохо обобщает на новые данные. Попробуйте использовать параметры для ограничения глубины дерева и минимального количества образцов на листе. -
Использование перекрестной проверки:
Рекомендуется использовать кросс-валидацию (например, KFold или StratifiedKFold), чтобы получить более надежные оценки производительности вашей модели и снизить влияние удачного распределения тестовых данных. -
Ошибка с использованием тестового набора:
Убедитесь, что вы не использовали ваши тестовые данные для обучения модели. Это распространенная ошибка, которая может привести к завышенной оценке точности. -
Анализ важности признаков:
Постарайтесь определить, какие признаки имеют наибольшее влияние на целевую переменную. Вы можете использовать алгоритм случайного леса для оценки важности признаков и использования только наиболее значимых.
Заключение:
Модель дерева решений может дать хорошую точность на определенных наборах данных за счет переобучения, но это не свидетельствует о ее надежности. Рекомендуется использовать более стабильные алгоритмы, такие как случайный лес, и дополнительно настраивать их гиперпараметры. Обязательно проверяйте и анализируйте данные, включая количество классов и дубликатов, чтобы избежать ошибок и получить правильное представление о производительности ваших моделей.