Когда мы начинаем работать с данными, мы (как правило, всегда) замечаем, что в данных есть несколько ошибок, таких как пропущенные значения, выбросы, неправильное форматирование и т. Д. В двух словах мы называем их несогласованностью. Эта согласованность более или менее искажает данные и мешает алгоритмам машинного обучения правильно прогнозировать.
Ранее мы наблюдали, как выбросы могут исказить наш анализ. Кроме того, мы заметили, что классификатор k-NN повысил точность после того, как мы удалили выбросы и оптимизировали его параметры, тогда как для нас наш классификатор дерева решений работал плохо. Есть предположение, что мы не оптимизировали параметры, которые принимает классификатор, поэтому в этой статье мы увидим, подходит ли классификатор для этой задачи или требует дополнительного рассмотрения.
Если вы не читали статью, вы можете найти ее здесь:
Давайте посмотрим, сможем ли мы работать с параметрами, которые использует классификатор DT, чтобы повысить нашу точность.
class sklearn.tree.DecisionTreeClassifier
(*, criterion='gini', splitter='best', max_depth=None, min_samples_split=2, min_samples_leaf=1, min_weight_fraction_leaf=0.0, max_features=None, random_state=None, max_leaf_nodes=None, min_impurity_decrease=0.0, min_impurity_split=None, class_weight=None, presort='deprecated', ccp_alpha=0.0)
Критерий
Функция измерения качества раскола. Есть два наиболее важных критерия: {"Джини", "Энтропия"}.
Индекс Джини рассчитывается путем вычитания суммы квадратов вероятностей каждого класса из единицы. Он предпочитает большие перегородки.
Прирост энтропии или информации умножает вероятность класса на логарифм (основание = 2) вероятности этого класса.
Как насчет того, чтобы использовать оба этих критерия и проверить их взаимодействие с помощью max_depth, minimum_samples_split, minimum_weight_fraction_leaf.
Min_weight_fraction_leaf
Минимальная взвешенная часть суммы весов (всех входных выборок), которая должна находиться в листовом узле. Если параметр sample_weight не указан, образцы имеют одинаковый вес.
fractions = [0,0.1,0.2,0.3,0.4,0.5] from sklearn.metrics import accuracy_score min_weight_fraction_leaf = [] acc_gini = [] acc_entropy = [] for i in fractions: dtree = DecisionTreeClassifier(criterion='gini', min_weight_fraction_leaf=i ) dtree.fit(X_train, y_train) pred = dtree.predict(X_test) acc_gini.append(accuracy_score(y_test, pred)) #### dtree = DecisionTreeClassifier(criterion='entropy',min_weight_fraction_leaf=i) dtree.fit(X_train, y_train) pred = dtree.predict(X_test) acc_entropy.append(accuracy_score(y_test, pred)) #### min_weight_fraction_leaf.append(i) d = pd.DataFrame({'acc_gini':pd.Series(acc_gini), 'acc_entropy':pd.Series(acc_entropy), 'min_weight_fraction_leaf':pd.Series(max_depth)}) # visualizing changes in parameters plt.plot('min_weight_fraction_leaf','acc_gini', data=d, label='gini') plt.plot('min_weight_fraction_leaf','acc_entropy', data=d, label='entropy') plt.xlabel('min_weight_fraction_leaf') plt.ylabel('accuracy') plt.legend()
Из графика ниже видно, что точность выше на 0,3 для обоих критериев.
Почему ?
После предоставления весов выборкам в конечных узлах, оконечных узлах, мы получаем аналогичную точность, возможно, аналогичный прирост информации и примеси, общие для обоих критериев. Это означает, что мы получаем чистые узлы.
min_samples_split
Минимальное количество выборок, необходимое для разделения внутреннего узла:
- Если int, то считайте
min_samples_split
как минимальное число. - Если с плавающей точкой, тогда
min_samples_split
- дробная часть, аceil(min_samples_split * n_samples)
- минимальное количество выборок для каждого разбиения.
min_samples_split = [] acc_gini = [] acc_entropy = [] for i in range(2,20,1): dtree = DecisionTreeClassifier(criterion='gini', min_samples_split=i ) dtree.fit(X_train, y_train) pred = dtree.predict(X_test) acc_gini.append(accuracy_score(y_test, pred)) #### dtree = DecisionTreeClassifier(criterion='entropy',min_samples_split=i) dtree.fit(X_train, y_train) pred = dtree.predict(X_test) acc_entropy.append(accuracy_score(y_test, pred)) #### min_samples_split.append(i) d = pd.DataFrame({'acc_gini':pd.Series(acc_gini), 'acc_entropy':pd.Series(acc_entropy), 'min_samples_split':pd.Series(max_depth)}) # visualizing changes in parameters plt.plot('min_samples_split','acc_gini', data=d, label='gini') plt.plot('min_samples_split','acc_entropy', data=d, label='entropy') plt.xlabel('min_samples_split') plt.ylabel('accuracy') plt.legend()
Из приведенного выше графика мы видим, что энтропия работает лучше при min_samples_split на 7.
Почему?
С математической точки зрения, Entropy принимает во внимание образцы и их информацию для построения дерева. Таким образом, здесь, при оптимальном значении количества сэмплов, мы получаем больше информации о дальнейших разделениях. С другой стороны, хотя индекс Джини лучше всего работает в больших разделах. Имеющиеся данные содержат примеси, которые вызывают снижение точности с увеличением min_samples_split.
Максимальная глубина
Максимальная глубина дерева. Если None, то узлы расширяются до тех пор, пока все листья не станут чистыми или пока все листья не будут содержать менее min_samples_split выборок. Поэтому рекомендуется, чтобы оба параметра работали в гармонии.
max_depth = [] acc_gini = [] acc_entropy = [] for i in range(1,30): dtree = DecisionTreeClassifier(criterion='gini',max_depth=i ) dtree.fit(X_train, y_train) pred = dtree.predict(X_test) acc_gini.append(accuracy_score(y_test, pred)) #### dtree = DecisionTreeClassifier(criterion='entropy', max_depth=i) dtree.fit(X_train, y_train) pred = dtree.predict(X_test) acc_entropy.append(accuracy_score(y_test, pred)) #### max_depth.append(i) d = pd.DataFrame({'acc_gini':pd.Series(acc_gini), 'acc_entropy':pd.Series(acc_entropy), 'max_depth':pd.Series(max_depth)}) # visualizing changes in parameters plt.plot('max_depth','acc_gini', data=d, label='gini') plt.plot('max_depth','acc_entropy', data=d, label='entropy') plt.xlabel('max_depth') plt.ylabel('accuracy') plt.legend()
Отсюда ясно видно, что индекс Джини превосходит энтропию.
Почему?
Как мы знаем, индекс Джини учитывает вероятность классов, поэтому степень индекса Джини варьируется от 0 до 1, где 0 означает, что все элементы принадлежат определенному классу или если существует только один класс, а 1 означает что элементы случайным образом распределяются по разным классам. Индекс Джини 0,5 означает, что элементы равномерно распределены по некоторым классам.
В нашем примере мы можем сделать вывод, что при max_depth = 6 мы наблюдаем узлы с низкой примесью, что увеличивает точность нашей модели.
Вывод
Возвращаясь к нашему обсуждению сверху, мы можем сделать следующие выводы:
- Gini-Index обеспечивает высочайшую точность с максимальной глубиной = 6.
- Энтропия и индекс Джини могут вести себя одинаково с соответствующим образом выбранным min_weight_fraction_leaf.
- С min_samples_split равным 7, Entropy превосходит Джини из-за элементарного предположения, что большее количество выборок обеспечит больший объем информации и будет иметь тенденцию искажать индекс Джини по мере увеличения примеси.
Поэтому, взяв в качестве критериев Джини и max_depth = 6, мы получили точность 32%, что на 18% больше, чем без использования параметрической оптимизации. Следовательно, правильная оптимизация параметра повысит точность модели и обеспечит лучшие результаты.