Что такое деревья решений в машинном обучении?
20 октября 2022 г.Дерево решений – это контролируемый алгоритм машинного обучения, который работает на основе рекурсивных ответов на некоторые вопросы (условия "если-иначе"). Алгоритм используется как для регрессии, так и для классификации. Однако в основном для задач классификации.
Вопросы в полях называются внутренними узлами, где ответы на вопросы разбивают его на ветви. Узлы, которые больше не разделяются, называются листьями, которые представляют собой решение/выход модели.
Это дерево, конечно, намного больше и сложнее для больших наборов данных по сравнению с нашим простым примером выше. Дерево растет и формируется в соответствии с данными, которые мы ему предоставляем (обучение модели). Однако эта простая диаграмма также показывает, насколько просто на самом деле работает алгоритм. Вы уже можете себе представить, что для правильного разделения данных вам нужно задавать правильные вопросы, начиная с верхнего узла. Это означает, какие функции и какие условия использовать имеют решающее значение для построения эффективного дерева решений. Ну как это возможно?
Во-первых, функция корневого узла выбирается на основе результатов меры выбора атрибута (ASM). После этого ASM применяется ко всем рекурсивно возникающим узлам до тех пор, пока невозможно дальнейшее разделение (когда мы достигнем листа).
Выборочная мера атрибута (ASM)
Показатель выбора подмножества атрибутов — это метод, используемый для сокращения данных. Сокращение данных необходимо для лучшего анализа и прогнозирования целевой переменной. Именно так дерево решений выбирает узлы для наилучшего разбиения данных.
Два основных метода ASM:
- Индекс Джини
- Получение информации (ID3)
Индекс Джини
Индекс Джини или примесь Джини — это мера примеси (степень вероятности неправильной классификации признака), используемая для создания дерева решений. Функция с низким значением индекса Джини должна быть предпочтительной для выбора узлов при создании дерева решений. Индекс Джини используется для создания только двоичных разбиений дерева.
Получение информации (ID3)
Прирост информации показывает, насколько информативным является объект, измеряя изменения энтропии после разделения данных по этому объекту. Алгоритм дерева решений всегда пытается максимизировать прирост информации, в котором узел с наибольшим приростом информации выбирается в качестве первого узла (первое разделение). Поэтому дерево сначала разбивается по признаку с наибольшей энтропией, уменьшая энтропию на всем пути вниз по листьям.
Формула энтропии:
Мы можем использовать модель DecisionTreeClassifier из библиотеки обучения scikit (документация DecisionTreeClassifier):
Давайте воспользуемся набором данных о раке из библиотеки scikit-learn и применим модель дерева решений:
# Import train_test_split function and the dataset
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
from sklearn.tree import DecisionTreeClassifier
cancer = load_breast_cancer()
y = cancer.target
X = cancer.data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
clf = DecisionTreeClassifier(criterion='entropy', random_state=0)
clf.fit(X_train, y_train)
print("Training accuracy:{:.2f}".format(clf.score(X_train,y_train)))
print("Test accuracy: {:.2f}".format(clf.score(X_test,y_test)))
Точность нашего обучения выше, чем точность нашего теста, показывает нам, что наша модель переоснащает данные. Давайте построим наше дерево решений и рассмотрим его сложность.
from sklearn import tree
import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows = 1,ncols = 1,figsize = (16,8), dpi=100)
tree.plot_tree(clf, feature_names = cancer.feature_names, class_names=cancer.target_names, filled = True, fontsize = 5);
Изменение критерия asm с gine на энтропию:
clf = DecisionTreeClassifier(criterion='entropy', random_state=0)
clf.fit(X_train, y_train)
print("Training accuracy:{:.2f}".format(clf.score(X_train,y_train)))
print("Test accuracy: {:.2f}".format(clf.score(X_test,y_test)))
Точность нашего теста повысилась при использовании показателя выбора атрибута энтропии в качестве критерия разделения. Мы можем еще раз взглянуть на дерево, чтобы увидеть, есть ли какие-либо изменения в сделанных разбиениях.
fig, axes = plt.subplots(nrows = 1,ncols = 1,figsize = (16,8), dpi=100)
tree.plot_tree(clf, feature_names = cancer.feature_names, class_names=cancer.target_names, filled = True, fontsize = 5);
Как мы видим, наше дерево довольно сложное, что приводит к переоснащению данных. Мы можем уменьшить сложность дерева, указав максимальную глубину (max_depth) и предотвратив переоснащение.
clf = DecisionTreeClassifier(max_depth=3)
clf.fit(X_train, y_train)
print("Training accuracy:{:.2f}".format(clf.score(X_train,y_train)))
print("Test accuracy: {:.2f}".format(clf.score(X_test,y_test)))
Уменьшив максимальную глубину нашего дерева решений до трех, мы смогли уменьшить переоснащение и немного повысить точность теста. Если мы сейчас рассмотрим нашу древовидную диаграмму, мы увидим гораздо более простое дерево…
Установив значение max_depth равным 3, мы упростили дерево решений, обрезав его. Эта сокращенная модель менее сложна и ее немного легче понять по сравнению с предыдущей моделью, в которой дерево продолжало разбиваться до тех пор, пока все листья не станут чистыми (gini impurtiy = 0).
Регрессия дерева решений
Давайте посмотрим, как работает дерево решений для задачи регрессии. Для этого мы снова можем сгенерировать случайный набор данных:
import numpy as np
np.random.seed(5)
X = np.sort(5 * np.random.rand(40, 1), axis=0)
y = np.sin(X).ravel()
# Add noise to targets
y[::5] += 1 * (0.5 - np.random.rand(8))
Библиотека scikit-learn предоставляет нам модель дерева решений для регрессии под названием DecisionTreeRegressor:
from sklearn.tree import DecisionTreeRegressor
dt_reg = DecisionTreeRegressor(criterion="squared_error", random_state=0)
dt_reg.fit(X, y)
fig, axes = plt.subplots(nrows = 1, ncols = 1, figsize=(16,8), dpi=100)
tree.plot_tree(dt_reg, feature_names='X', filled=True, fontsize=5);
#generate a random Test data
T = np.linspace(0, 5, 100)[:, np.newaxis]
#creating two regression trees with different depths
dt_reg_1 = DecisionTreeRegressor(max_depth = 10, random_state=0)
dt_reg_2 = DecisionTreeRegressor(max_depth = 3, random_state=0)
#training the models
dt_reg_1.fit(X, y)
dt_reg_2.fit(X, y)
#making predictions for the random test data we generated above
y_pred_1 = dt_reg_1.predict(T)
y_pred_2 = dt_reg_2.predict(T)
#comparison plot to see the effect of tree depth
plt.figure()
plt.scatter(X, y, s=40, c="orange", label="actual")
plt.plot(T, y_pred_1, color="b", label="max_depth=10", linewidth=2)
plt.plot(T, y_pred_2, color="g", label="max_depth=3", linewidth=2)
plt.xlabel("X")
plt.ylabel("y")
plt.title("Decision Tree Regression")
plt.legend()
plt.show()
Глядя на рисунок, мы видим, как модель регрессора дерева решений с максимальной глубиной, равной десяти, превосходит данные, захватывая весь шум в данных. Кроме того, дерево с максимальной глубиной, равной трем, намного лучше обобщает и создает лучшее соответствие данным, не захватывая весь шум.
Преимущества
- Легко понять, интерпретировать и визуализировать
- Обычно не требуется ни масштабирования, ни нормализации, ни выбора признаков.
- Хорошо работает с несколькими типами данных (категориальными, числовыми, двоичными) в наборе данных (более простая предварительная обработка данных)
- Он также подходит для задач с несколькими выходами.
Недостатки
- Дерева решений, как правило, переопределяют и не очень хорошо обобщают
- В основном требуется ансамбль деревьев других моделей для повышения производительности обобщения.
- Деревья решений, как правило, формируют необъективные деревья, если существует дисбаланс данных. Наборы данных с преобладающими классами должны быть сбалансированы.
Если вам нравится это руководство, подписывайтесь на меня, чтобы получать дополнительные бесплатные руководства и курсы по машинному обучению!
Также опубликовано здесь
Оригинал