Вопрос или проблема
Я пытаюсь построить модель дерева решений для прогнозирования исходной переменной (названной: Результаты) на основе предиктора. Действительно, я применил однократное кодирование к некоторым переменным с “>2 уровня”, чтобы немного увеличить количество предикторов. Сначала я исследовал данные, а затем разделил их на 80/20 и запустил модель, но модель, обученная на обучающем наборе данных, завершилась только одним узлом без ветвей, как показано на рисунке ниже.
Изучая похожие посты, я заметил, что мои данные несбалансированы, потому что при проверке пропорции классов (переменной Результаты) большинство относилось к негативным, а не к позитивным. Есть ли предложения по созданию корректного дерева на этих данных?
Вот мой код:
Разделение данных на тестовые и обучающие (80% обучающая и 20% тестовая выборка)
set.seed(1234)
pd <- sample(2, nrow(data_hum_mod), replace = TRUE, prob = c(0.8,0.2))
data_hum_train <- data_hum_mod[pd==1,]
data_hum_test<- data_hum_mod[pd==2,]
Исследование данных после разделения
Проверка размерности данных
dim(data_hum_train); dim(data_hum_test) #убедитесь, что разделенные данные имеют сбалансированные n каждого из классов исходов (т.е. позитивные/негативные токсоплазмоз)
prop.table(table(data_hum_train$Results)) * 100
prop.table(table(data_hum_test$Results)) *100
Это дало следующие результаты:
# (Обучающие)
Негативные Позитивные
75.75758 24.24242
# и (Тестовые)
Негативные Позитивные
54.54545 45.45455
# Проверка на пропущенные значения
anyNA(data_hum_mod)
#Убедитесь, что ни одна из переменных не имеет нулевой или почти нулевой дисперсии
nzv(data_hum_mod)
# Построение модели (с использованием пакета party)
install.packages('party')
library(party)
data_human_train_tree<- ctree(Results ~., data = data_hum_train,
controls = ctree_control(mincriterion = 0.1))
data_human_train_tree
plot(data_human_train_tree)
С помощью этого кода я получил этот рисунок.
Я получил те же результаты, используя другие пакеты, такие как C50 и rpart.
Не могли бы вы посоветовать что-нибудь по этому поводу? Я читал о подвыборке для класса большинства (здесь негативные Результаты), как это можно реализовать в R?
Основная проблема, вероятно, в том, что вы установили mincriterion
слишком высоким, так что ни одно разбиение его не превышает. Попробуйте удалить его или уменьшить значение.
Несбалансированность классов возможно, не является проблемой. Но несколько настораживает, что баланс вашего тестового набора значительно отличается от обучающего.
Кроме того, я бы предложил использовать “ординальное кодирование” (например, целыми числами 1, 2,… для любых порядковых переменных, таких как возрастные группы и образование).
Ответ или решение
Проблема, с которой вы столкнулись, заключается в том, что ваш решающий дерево выдало только один узел и не создало никаких разветвлений. Скорее всего, это связано с несколькими факторами, включая слишком высокий критерий остановки (mincriterion
), неправильную обработку несбалансированных данных и, возможно, особенности самой выборки.
Вот несколько рекомендаций, которые могут помочь вам создать более адекватное решающее дерево:
-
Снижение
mincriterion
: Параметрmincriterion
в функцииctree
задает порог для минимальной величины критерия, необходимого для выполнения разделения. Если этот порог установлен слишком высоко, могут отсутствовать разделения. Попробуйте установить более низкое значение или вообще удалить этот параметр из спецификации функции:data_human_train_tree <- ctree(Results ~ ., data = data_hum_train)
-
Балансировка классов: У вас действительно наблюдается несбалансированность в ваших данных (75.76% негативных и 24.24% позитивных). Рассмотрите возможность использования методов балансировки классов, таких как:
- Переобучение (oversampling) — увеличьте количество позитивных примеров, добавив копии существующих или генерируя новые с помощью методов, таких как SMOTE.
- Недообучение (undersampling) — уменьшите количество негативных примеров, случайно удаляя часть из них.
Пример использования SMOTE:
install.packages("DMwR") library(DMwR) data_hum_train_balanced <- SMOTE(Results ~ ., data = data_hum_train, perc.over = 100)
-
Проверка на мультиколлинеарность: Убедитесь, что ваши предикторы не высоко коррелируют друг с другом. Это можно сделать, используя корреляционные матрицы или рассчитать VIF (Variance Inflation Factor).
-
Предварительная обработка данных: Убедитесь, что вы правильно протестировали и закодировали все категориальные переменные. Возможно, стоит пересмотреть кодирование для порядковых переменных, таких как возраст или уровень образования, чтобы использовать порядковое кодирование.
-
Оценка модели: Используйте кросс-валидацию по k-складкам, чтобы оценить стабильность вашей модели. Это поможет определить, действительно ли ваша модель перенастраивается на данные или просто имеет плохую производительность.
-
Анализ важности предикторов: После получения модели можно проанализировать важность предикторов, чтобы понять, какие из них вносят наибольший вклад в предсказание.
-
Обустройство тестовой выборки: Убедитесь, что пропорции классов в тестовой выборке схожи с обучающей выборкой. Если вы будете использовать методы выбора, такие как стратифицированная выборка, это может помочь сохранить пропорции классов в обеих выборках.
Примечание: Прежде чем внедрять изменения, проведите исследование данных, чтобы понять их свойства. Включая визуализацию распределения каждого предиктора по классам, вы сможете получить более полное представление о структуре ваших данных и о том, как лучше моделировать их.
Следуя указанным рекомендациям, вы сможете создать более адекватное решающее дерево и добиться лучшей производительности вашей модели. Удачи!