Когда мы начинаем работать с данными, мы (как правило, всегда) замечаем, что в данных есть несколько ошибок, таких как пропущенные значения, выбросы, неправильное форматирование и т. Д. В двух словах мы называем их несогласованностью. Эта согласованность более или менее искажает данные и мешает алгоритмам машинного обучения правильно прогнозировать.

Ранее мы наблюдали, как выбросы могут исказить наш анализ. Кроме того, мы заметили, что классификатор 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% больше, чем без использования параметрической оптимизации. Следовательно, правильная оптимизация параметра повысит точность модели и обеспечит лучшие результаты.

использованная литература