У меня 100% точность на тестовом наборе, неужели что-то не так?

Вопрос или проблема

Я получил 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]]

Может быть несколько причин, почему это происходит.

  1. Прежде всего, проверьте свой код. 100% точности кажется маловероятным в любом окружении. Сколько тестовых данных у вас есть? На сколько тренировочных данных вы обучали свою модель? Вы могли сделать ошибку в коде и сравнить два одинаковых списка.

  2. Вы использовали другой тестовый набор для тестирования? Высокая точность может быть связана с удачей – попробуйте использовать некоторые из доступных библиотек KFoldCrossValidation.

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

Лучшие модели:

  1. высокая точность на обучающих данных
  2. и равно высокая точность на тестовых данных
  3. и где оба метрики точности не отличаются более чем на 5~10% друг от друга, что, вероятно, показывает стабильность модели. Чем меньше разница, тем лучше, как мне кажется.

Бутстрэппинг и k-fold кросс-валидация обычно должны давать более надежные показатели производительности.

Также проверьте, является ли один из ваших предикторов производной признаков от переменной-цели. Вы можете сделать это, проверив value_counts на вашей переменной-цели и также на переменных, где вы видите слишком много сходства. Не следует использовать производные признаки от переменной-цели в качестве предикторов.

  1. Как уже упоминалось здесь, деревья решений легко переобучаются с параметрами по умолчанию. Поэтому случайные леса обычно являются лучшим выбором по сравнению с деревьями решений. Рассматривайте их как более обобщенные.
  2. Почему точности различаются? Случайный лес постоянно использует случайные переменные для использования в алгоритме (для одного дерева), тогда как дерево решений использует все. У вас есть ряд признаков (небольшое количество, я полагаю), которые имеют очень большое влияние на переменную-цель в целом наборе данных. Почему так? Определите, что это за признаки и исследуйте их глубже.
  3. Теперь, можем ли мы сказать, что дерево решений более стабильно для этой конкретной задачи, чем случайный лес? Я бы сказал, что нет, поскольку ситуация может измениться. Если ваш алгоритм дерева решений зависит от 1-3 важных признаков, вы не можете быть уверены, что эти признаки будут играть такую же значимую роль в будущем.
  4. Вы можете использовать дерево решений, но имейте в виду, что вам придется постоянно переобучать модель. И сравнивать результаты с случайным лесом.

Итак, мой совет:

  • реализуйте важность признаков (вы можете использовать модель случайного леса, чтобы получить их) и используйте только важные;
  • используйте какое-либо KFold или StratifiedKFold здесь – это даст вам лучшие результаты;
  • пока у вас дисбалансированный набор данных – внедрите class_weight – это должно улучшить результаты случайного леса;
  • реализуйте GridSearchCV – это также поможет вам избежать переобучения (и 1000 деревьев – это слишком много, также склонно к переобучению);
  • постоянно получайте и оценки на обучающих данных;
  • исследуйте важные признаки.

Ответ или решение

Получение 100% точности на тестовом наборе данных всегда вызывает подозрения и требует дополнительной проверки. Ваш случай, где алгоритм дерева решений показывает идеальную точность, а случайный лес — только 85%, может указывать на несколько возможных проблем.

Возможные причины и решения:

  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)
  2. Проверка баланса классов:
    Проверьте, сбалансированы ли ваши классы. Если 99% ваших данных принадлежат одному классу, модель может просто предсказывать этот класс в большинстве случаев, что приведет к высокой точности. Рассмотрите возможность использования метрик, таких как AUC-ROC, и примените методы балансировки, такие как oversampling или undersampling.

  3. Переобучение дерева решений:
    Деревья решений по умолчанию склонны к переобучению, если параметры не настроены должным образом (например, max_depth=None). Это может привести к ситуации, когда модель идеально запоминает обучающие данные, но плохо обобщает на новые данные. Попробуйте использовать параметры для ограничения глубины дерева и минимального количества образцов на листе.

  4. Использование перекрестной проверки:
    Рекомендуется использовать кросс-валидацию (например, KFold или StratifiedKFold), чтобы получить более надежные оценки производительности вашей модели и снизить влияние удачного распределения тестовых данных.

  5. Ошибка с использованием тестового набора:
    Убедитесь, что вы не использовали ваши тестовые данные для обучения модели. Это распространенная ошибка, которая может привести к завышенной оценке точности.

  6. Анализ важности признаков:
    Постарайтесь определить, какие признаки имеют наибольшее влияние на целевую переменную. Вы можете использовать алгоритм случайного леса для оценки важности признаков и использования только наиболее значимых.

Заключение:

Модель дерева решений может дать хорошую точность на определенных наборах данных за счет переобучения, но это не свидетельствует о ее надежности. Рекомендуется использовать более стабильные алгоритмы, такие как случайный лес, и дополнительно настраивать их гиперпараметры. Обязательно проверяйте и анализируйте данные, включая количество классов и дубликатов, чтобы избежать ошибок и получить правильное представление о производительности ваших моделей.

Оцените материал
Добавить комментарий

Капча загружается...