Объяснить, как работает дерево решений. Какие критерии используются при разбиении данных в узлах?
Дерево решений рекурсивно перебирает все признаки и находит значения, разбивающие данные на две группы с максимальным приростом метрики.
В задачах классификации используются критерий Джини или энтропия Шэннона. В задачах регрессии – MSE, MAE.
Что такое переобучение в деревьях решений и как с ним бороться?
Переобучение – это слишком сильная подстройка модели под обучающие данные. При этом на обучающих данных метрики качества высокие, а на тестовых – заметно ниже.
Для борьбы с переобучением дерева решений применяется регуляризация с настройкой таких гиперпараметров, как: max_depth, min_samples_split, min_samples_leaf. Они настраиваются до начала обучения модели.
Реализовать дерево решений из Sklearn и настроить его гиперпараметры с помощью кроссвалидации.
Пример решения для задачи классификации:
# Подбор гиперпараметров дерева решений с помощью кроссвалидации
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split, GridSearchCV, StratifiedKFold
from sklearn.metrics import accuracy_score
import pandas as pd
# Задаем гиперпараметры для перебора вариантов
params = {
'max_depth': [3, 5, 10],
'min_samples_split': [3, 5, 10],
'min_samples_leaf': [3, 5, 10],
'max_features': [3, 5, 10],
'criterion': ['gini', 'entropy']
}
# Загрузка данных
X, y = load_iris(return_X_y=True)
# Разбиение данных на обучающие и тестовые
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# Инициализация модели и её обучение
model = DecisionTreeClassifier(random_state=1)
# Используем стратифицированную кроссвалидацию из 5 фолдов с перемешиванием
cv = StratifiedKFold(n_splits=5, shuffle=True)
# Выполняем перебор гиперпараметров с оценкой полученных моделей
gscv = GridSearchCV(model, params, cv=cv, scoring='accuracy')
gscv.fit(X_train, y_train)
# Прогноз лучшей модели
best_model = gscv.best_estimator_
y_pred = best_model.predict(X_test)
# Оценка качества прогноза лучшей модели
acc = accuracy_score(y_test, y_pred)
print(f"Accuracy: {acc:.2f}")
# Просмотр лучших параметров и лучшей модели
print(f"Best params: {gscv.best_params_}")
print(f"Best estimator: {gscv.best_estimator_}")
# Вывод всех полученных комбинаций гиперпараметров с оценками моделей
results = pd.DataFrame(gscv.cv_results_)
print(results[['params', 'mean_test_score', 'rank_test_score']].sort_values(by='rank_test_score'))
Какие признаки важны в построенном дереве?
Для выявления важнейших признаков можно воспользоваться атрибутом .feature_importances_ и визуализацией дерева .plot_tree().
Вот наиболее точный способ оценки важности признаков:
print(f"Feature importances: {best_model.feature_importances_}")
Для построения визуализации дерева необходимо установить библиотеку matplotlib и импортировать соответствующий класс. По визуализации можно судить о важности признаков только приблизительно. Чем ближе встреченный признак к корню дерева, тем он, как правило, важнее. Но не всегда.
from sklearn.tree import plot_tree
# Здесь код загрузки данных и построения модели
plot_tree(model)
Как дерево решений обрабатывает категориальные признаки?
В реализации Scikit Learn – категориальные признаки необходимо кодировать (One Hot Encoding, Ordinal Encoding).
В Catboost и подобных алгоритмах бустинга категориальные признаки обрабатываются нативно.
Как прочитать и понять визуализированное дерево решений?
Пример визуализации.

Каждый прямоугольник — это узел дерева. Он содержит:
feature_name <= threshold— условие разбиения (если это не лист),giniилиentropy— значение функции потерь в этом узле (оно всегда стремится к минимизации),samples— сколько объектов дошло до этого узла,value = [n1, n2, n3]— количество объектов каждого класса в этом узле,class = ...— к какому классу относится узел (наиболее частый класс).
Как дерево ведет себя на несбалансированных классах?
Дисбаланс классов может привести к некорректным результатам в задачах классификации. Особенно, если число данных одного класса значительно выше данных другого класса.
Для количественной балансировки классов в дереве решений можно применить аргумент class_weight.
model = DecisionTreeClassifier(class_weight="balanced") # Возможны и другие варианты аргумента
Также для балансировки классов можно применить другие техники:
- SMOTE – искусственное увеличение данных для минорного класса с целью создать баланс с мажорным классом.
- undersampling – обрезка количества наблюдений для мажорного класса с целью создать баланс с минорным.