Деревья решений — это группа методов «разделяй и властвуй», в которой используется перевернутая древовидная структура для прогнозирования результата нашей проблемы. Модель предсказывает значение целевой переменной, используя простые правила принятия решений, выведенные из доступных функций. Дерево решений — это один из самых мощных методов прогнозной аналитики для создания бизнес-правил, который можно использовать как для регрессии, так и для классификации.
Он начинается с корневого узла, состоящего из полного набора данных, и использует меры примесей для разделения узлов на ветви и далее на дочерние узлы. Идея состоит в том, чтобы продолжать разбиение до тех пор, пока у нас не будет однородности, то есть в конкретной ветви или выходе у нас будут наблюдения, принадлежащие только одному классу. Мы используем функцию для измерения качества разделения, и двумя наиболее важными измерениями являются примесь Джини и прирост информации (энтропия).
Мы увидим оба метода, используя дерево решений sklearn для набора данных о раке молочной железы.
#importing libraries import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns %matplotlib inline #importing data from sklearn from sklearn.datasets import load_breast_cancer data = load_breast_cancer() #converting data into pandas dataframe canc_data = pd.DataFrame(data.data, columns=data.feature_names) #adding target field to the dataset canc_data['target'] = pd.Series(data.target) #creating X and y X_feature = list(canc_data.columns) X_feature.remove('target') X = canc_data[X_feature] y = canc_data['target'] #splitting data for training and testing from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 100)
Индекс примесей Джини:
Джини — это вероятность того, что случайная выборка будет правильно классифицирована при случайном выборе. Джини обозначает чистоту, тогда как примесь Джини говорит нам о примеси узлов.
Таким образом, примесь Джини дает нам вероятность неправильной классификации наблюдения, то есть вероятность того, что конкретный признак будет неправильно классифицирован при случайном выборе.
Таким образом, примесь Джини представляет собой сумму произведения pᵢ (вероятность выбора элемента с меткой i) и 1 - pᵢ( вероятность неправильной классификации). Минимальное значение индекса Джини равно 0 (когда узел чистый, т.е. все элементы в узле относятся к одному конкретному классу). А когда все случаи в узле относятся к определенной категории, индекс Джини достигает нуля. Кроме того, максимальное значение равно 0,5, и это когда вероятность двух классов одинакова.
Дерево решений с использованием индекса Джини и критериев энтропии
for i in ['gini','entropy']: print("Output when criterion is :", i) print('----------------------------------') from sklearn.tree import DecisionTreeClassifier i = DecisionTreeClassifier(criterion = i ,random_state=0, max_depth = 3).fit(X_train, y_train) #predicting for our test data y_pred = i.predict(X_test) #generating classification report from sklearn.metrics import classification_report print(classification_report(y_test, y_pred)) #importing libraries to check model performance from sklearn.metrics import confusion_matrix from sklearn.metrics import accuracy_score from sklearn.metrics import log_loss from sklearn import metrics print("Accuracy score on test: " , round((i.score(X_test, y_test)),3)) print("Accuracy score on train: ", round((i.score(X_train, y_train)),3)) #printing log loss for the model print('log_loss : ', log_loss(y_test, y_pred)) #let find ROC and AUC score #before we calculate roc_auc_score(), we need to find out the predicted probabilities for test data. pred_prob = pd.DataFrame(i.predict_proba(X_test)) #we'll also add the actual label test_result = pd.DataFrame( { 'actual' : y_test}) test_result = test_result.reset_index() test_result['prob_0'] = pred_prob.iloc[:,0:1] test_result['prob_1'] = pred_prob.iloc[:,1:2] #to calculate ROC AUC score we will pass actual class labels and predicted probability auc_score = round(metrics.roc_auc_score(test_result.actual, test_result.prob_1),3) print("AUC Score : ",auc_score) #generating confusion matrix cf_matrix = confusion_matrix(y_test, y_pred) sns.heatmap(cf_matrix, annot=True, cmap='Blues') plt.ylabel("True Label") plt.xlabel("Predicted Label") plt.show() print("\n")
#decision tree visualization. We will use graphviz software for our purpose. from sklearn import tree from sklearn.tree import export_graphviz import pydotplus as pdot from IPython.display import Image #exporting the tree model into odt file gini = DecisionTreeClassifier(criterion = 'gini' ,random_state=0, max_depth = 3).fit(X_train, y_train) export_graphviz(gini, out_file='clf_tree_gini.odt', feature_names = X_train.columns,filled = True) graph = pdot.graphviz.graph_from_dot_file('clf_tree_gini.odt') graph.write_jpg('clf_tree_gini.png') Image(filename='clf_tree_gini.png')
Мы также можем рассчитать индекс Джини для перекрестной проверки. В верхнем узле вероятность обнаружения доброкачественного рака составляет 255/398, а злокачественного — 143/398.
gini_imp_node1 = 1 - (pow(255/398,2) + pow(143/398,2)) print(round(gini_imp_node1,2))
Мы получаем наш индекс Джини равным 0,46, что мы также можем видеть в верхнем узле дерева решений.
Энтропия:
Энтропия — это измерение примеси или случайности в наблюдаемых точках данных. Чем выше энтропия, тем ниже будет чистота. Таким образом, цель модели — уменьшить загрязнение, что достигается за счет Получения информации.
Энтропия максимальна, когда вероятность двух классов одинакова, и минимальна, когда энтропия равна 0 (т.е. узел чистый).
Давайте построим дерево решений, используя энтропию в качестве критерия измерения.
#exporting the tree model into odt file gini = DecisionTreeClassifier(criterion = 'entropy' ,random_state=0, max_depth = 3).fit(X_train, y_train) export_graphviz(gini, out_file='clf_tree_entropy.odt', feature_names = X_train.columns,filled = True) graph = pdot.graphviz.graph_from_dot_file('clf_tree_entropy.odt') graph.write_jpg('clf_tree_entropy.png') Image(filename='clf_tree_entropy.png')
Мы снова можем вычислить энтропию. В верхнем узле вероятность обнаружения доброкачественного рака составляет 255/398, а злокачественного — 143/398.
import math entropy_imp_node1 = -((255/398)*math.log2(255/398) + (143/398)*math.log2(143/398)) print(round(entropy_imp_node1,3))
Прирост информации: прирост информации эквивалентен уменьшению энтропии от родительского узла к дочернему узлу для заданных функций. Он измеряет снижение энтропии путем разделения набора данных в соответствии с заданным значением. Это дает нам информацию об уменьшении родительской энтропии после расщепления. Модель дерева решений выбирает функцию, которая обеспечивает наибольший прирост информации, и разделяет узел на основе этой функции.
Прирост информации (I.G.) = энтропия до ветвления — энтропия после ветвления
Индекс Джини или энтропия
Энтропия использует журналы и, следовательно, является более сложной в вычислительном отношении по сравнению с индексом Джини. И поэтому индекс Джини будет быстрее. Но мы также должны учитывать показатели производительности, прежде чем решить, какое измерение выбрать.
У каждой модели есть свои плюсы и минусы. Пожалуйста, просмотрите отличную документацию от scikit, чтобы узнать, что такое деревья решений.