Пост-обрезка деревьев решений с обрезкой по стоимости сложности#

The DecisionTreeClassifier предоставляет параметры, такие как min_samples_leaf и max_depth чтобы предотвратить переобучение дерева. Обрезка по стоимости сложности предоставляет другой вариант для контроля размера дерева. В DecisionTreeClassifierЭта техника обрезки параметризуется параметром сложности стоимости, ccp_alpha. Большие значения ccp_alpha увеличить количество обрезанных узлов. Здесь мы показываем только эффект от ccp_alpha регуляризации деревьев и как выбрать ccp_alpha на основе валидационных оценок.

Смотрите также Минимальная обрезка по стоимости-сложности для подробностей об обрезке.

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

import matplotlib.pyplot as plt

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier

Общая примесь листьев vs эффективные альфа-значения обрезанного дерева#

Минимальное стоимостное обрезание рекурсивно находит узел со «слабым звеном». Слабое звено характеризуется эффективным альфа, где узлы с наименьшим эффективным альфа обрезаются первыми. Чтобы понять, какие значения ccp_alpha может быть уместным, scikit-learn предоставляет DecisionTreeClassifier.cost_complexity_pruning_path который возвращает эффективные альфа-значения и соответствующие общие примеси листьев на каждом этапе процесса обрезки. По мере увеличения альфа-значения больше дерева обрезается, что увеличивает общую примесь его листьев.

X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

clf = DecisionTreeClassifier(random_state=0)
path = clf.cost_complexity_pruning_path(X_train, y_train)
ccp_alphas, impurities = path.ccp_alphas, path.impurities

На следующем графике максимальное эффективное значение альфа удалено, потому что это тривиальное дерево только с одним узлом.

fig, ax = plt.subplots()
ax.plot(ccp_alphas[:-1], impurities[:-1], marker="o", drawstyle="steps-post")
ax.set_xlabel("effective alpha")
ax.set_ylabel("total impurity of leaves")
ax.set_title("Total Impurity vs effective alpha for training set")
Total Impurity vs effective alpha for training set
Text(0.5, 1.0, 'Total Impurity vs effective alpha for training set')

Далее мы обучаем дерево решений, используя эффективные альфы. Последнее значение в ccp_alphas это значение alpha, которое обрезает всё дерево, оставляя дерево, clfs[-1], с одним узлом.

clfs = []
for ccp_alpha in ccp_alphas:
    clf = DecisionTreeClassifier(random_state=0, ccp_alpha=ccp_alpha)
    clf.fit(X_train, y_train)
    clfs.append(clf)
print(
    "Number of nodes in the last tree is: {} with ccp_alpha: {}".format(
        clfs[-1].tree_.node_count, ccp_alphas[-1]
    )
)
Number of nodes in the last tree is: 1 with ccp_alpha: 0.3272984419327777

Для оставшейся части этого примера мы удаляем последний элемент в clfs и ccp_alphas, потому что это тривиальное дерево только с одним узлом. Здесь мы показываем, что количество узлов и глубина дерева уменьшаются с увеличением alpha.

clfs = clfs[:-1]
ccp_alphas = ccp_alphas[:-1]

node_counts = [clf.tree_.node_count for clf in clfs]
depth = [clf.tree_.max_depth for clf in clfs]
fig, ax = plt.subplots(2, 1)
ax[0].plot(ccp_alphas, node_counts, marker="o", drawstyle="steps-post")
ax[0].set_xlabel("alpha")
ax[0].set_ylabel("number of nodes")
ax[0].set_title("Number of nodes vs alpha")
ax[1].plot(ccp_alphas, depth, marker="o", drawstyle="steps-post")
ax[1].set_xlabel("alpha")
ax[1].set_ylabel("depth of tree")
ax[1].set_title("Depth vs alpha")
fig.tight_layout()
Number of nodes vs alpha, Depth vs alpha

Точность в зависимости от alpha для обучающей и тестовой выборок#

Когда ccp_alpha установлен в ноль с сохранением остальных параметров по умолчанию DecisionTreeClassifier, дерево переобучается, что приводит к 100% точности обучения и 88% точности тестирования. По мере увеличения alpha больше дерева обрезается, создавая дерево решений, которое лучше обобщает. В этом примере установка ccp_alpha=0.015 максимизирует точность тестирования.

train_scores = [clf.score(X_train, y_train) for clf in clfs]
test_scores = [clf.score(X_test, y_test) for clf in clfs]

fig, ax = plt.subplots()
ax.set_xlabel("alpha")
ax.set_ylabel("accuracy")
ax.set_title("Accuracy vs alpha for training and testing sets")
ax.plot(ccp_alphas, train_scores, marker="o", label="train", drawstyle="steps-post")
ax.plot(ccp_alphas, test_scores, marker="o", label="test", drawstyle="steps-post")
ax.legend()
plt.show()
Accuracy vs alpha for training and testing sets

Общее время выполнения скрипта: (0 минут 0.408 секунд)

Связанные примеры

Понимание структуры дерева решений

Понимание структуры дерева решений

Регрессия дерева решений

Регрессия дерева решений

Построить поверхность решений деревьев решений, обученных на наборе данных ирисов

Построить поверхность решений деревьев решений, обученных на наборе данных ирисов

Обзор мета-оценщиков для многоклассового обучения

Обзор мета-оценщиков для многоклассового обучения

Галерея, созданная Sphinx-Gallery