Вернуться на страницу brain2net: https://brain2net.ru/post/derevya-i-lesa-klassifikacziya/

Построение дерева решений

In [11]:
import numpy as np
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from sklearn import tree
In [12]:
import matplotlib.pyplot as plt
%matplotlib inline
In [13]:
# Загрузка набора данных Breast Cancer
from sklearn.datasets import load_breast_cancer
cancer = load_breast_cancer()
In [14]:
# Разделение набора данных на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, stratify=cancer.target, random_state=42)
In [15]:
# Если не ограничить глубину, дерево может быть сколь угодно глубоким и сложным. 
# Поэтому необрезанные деревья склонны к переобучению и плохо обобщают результат на новые данные.
# Один из вариантов – остановка процесса построения дерева по достижении определенной глубины.
# max_depth=4 - можно задать только четыре последовательных вопроса 

clf = DecisionTreeClassifier(max_depth=4, random_state=0)
clf.fit(X_train, y_train)
print("Правильность на обучающем наборе: {:.3f}".format(clf.score(X_train, y_train)))
print("Правильность на тестовом наборе: {:.3f}".format(clf.score(X_test, y_test)))
Правильность на обучающем наборе: 0.988
Правильность на тестовом наборе: 0.951
In [16]:
# Визуализация дерева
# max_depth = 2 количество визуализируемых уровней
# fontsize = 6 Размер шрифта
tree.plot_tree(clf, max_depth = 2, fontsize = 6)
plt.show()
In [17]:
# Визуализация важности признаков
print("Важности признаков:\n{}".format(clf.feature_importances_))
Важности признаков:
[0.         0.         0.         0.         0.         0.
 0.         0.         0.         0.         0.01019737 0.04839825
 0.         0.         0.0024156  0.         0.         0.
 0.         0.         0.72682851 0.0458159  0.         0.
 0.0141577  0.         0.018188   0.1221132  0.01188548 0.        ]
In [18]:
for name, score in zip(cancer["feature_names"], clf.feature_importances_):
    print(name, score)
mean radius 0.0
mean texture 0.0
mean perimeter 0.0
mean area 0.0
mean smoothness 0.0
mean compactness 0.0
mean concavity 0.0
mean concave points 0.0
mean symmetry 0.0
mean fractal dimension 0.0
radius error 0.010197368202069328
texture error 0.0483982536186494
perimeter error 0.0
area error 0.0
smoothness error 0.002415595085315826
compactness error 0.0
concavity error 0.0
concave points error 0.0
symmetry error 0.0
fractal dimension error 0.0
worst radius 0.7268285094603201
worst texture 0.045815897088866304
worst perimeter 0.0
worst area 0.0
worst smoothness 0.014157702104714051
worst compactness 0.0
worst concavity 0.0181879968644502
worst concave points 0.12211319926548449
worst symmetry 0.01188547831013032
worst fractal dimension 0.0
In [19]:
# Визуализировать важности признаков
def plot_feature_importances_cancer(model):
    n_features = cancer.data.shape[1]
    plt.barh(range(n_features), model.feature_importances_, align='center')
    plt.yticks(np.arange(n_features), cancer.feature_names)
    plt.xlabel("Важность признака")
    plt.ylabel("Признак")
plot_feature_importances_cancer(clf)

Случайный лес

In [20]:
from sklearn.ensemble import RandomForestClassifier
In [21]:
X_train, X_test, y_train, y_test = train_test_split(
cancer.data, cancer.target, random_state=0)
In [40]:
forest = RandomForestClassifier(n_estimators=100, n_jobs=-1, random_state=0)
forest.fit(X_train, y_train)
Out[40]:
RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None,
                       criterion='gini', max_depth=None, max_features='auto',
                       max_leaf_nodes=None, max_samples=None,
                       min_impurity_decrease=0.0, min_impurity_split=None,
                       min_samples_leaf=1, min_samples_split=2,
                       min_weight_fraction_leaf=0.0, n_estimators=100,
                       n_jobs=-1, oob_score=False, random_state=0, verbose=0,
                       warm_start=False)
In [41]:
print("Правильность на обучающем наборе: {:.3f}"
      .format(forest.score(X_train, y_train)))
Правильность на обучающем наборе: 1.000
In [42]:
print("Правильность на тестовом наборе: {:.3f}".
      format(forest.score(X_test, y_test)))
Правильность на тестовом наборе: 0.870

Градиентный бустинг деревьев решений

In [25]:
from sklearn.ensemble import GradientBoostingClassifier
In [26]:
X_train, X_test, y_train, y_test = train_test_split(
cancer.data, cancer.target, random_state=0)

Для уменьшения переобучения можно применить

более сильную предварительную обрезку, ограничив максимальную глубину, max_depth=1

или снизить скорость обучения learning_rate=0.01

In [36]:
gbrt = GradientBoostingClassifier(random_state=0, 
                                  max_depth=2, learning_rate=0.01)
gbrt.fit(X_train, y_train)
Out[36]:
GradientBoostingClassifier(ccp_alpha=0.0, criterion='friedman_mse', init=None,
                           learning_rate=0.01, loss='deviance', max_depth=2,
                           max_features=None, max_leaf_nodes=None,
                           min_impurity_decrease=0.0, min_impurity_split=None,
                           min_samples_leaf=1, min_samples_split=2,
                           min_weight_fraction_leaf=0.0, n_estimators=100,
                           n_iter_no_change=None, presort='deprecated',
                           random_state=0, subsample=1.0, tol=0.0001,
                           validation_fraction=0.1, verbose=0,
                           warm_start=False)
In [34]:
print("Правильность на обучающем наборе: {:.3f}"
      .format(gbrt.score(X_train, y_train)))
Правильность на обучающем наборе: 0.974
In [35]:
print("Правильность на тестовом наборе: {:.3f}"
      .format(gbrt.score(X_test, y_test)))
Правильность на тестовом наборе: 0.965

Другой пример

In [37]:
from sklearn.datasets import make_hastie_10_2
In [38]:
X, y = make_hastie_10_2(random_state=0)
X_train, X_test = X[:2000], X[2000:]
y_train, y_test = y[:2000], y[2000:]
In [39]:
clf = GradientBoostingClassifier(n_estimators=100, learning_rate=1.0,
    max_depth=1, random_state=0).fit(X_train, y_train)
clf.score(X_test, y_test)
Out[39]:
0.913

Вернуться на страницу brain2net: https://brain2net.ru/post/derevya-i-lesa-klassifikacziya/

In [ ]: