Програмне забезпечення та програмування
Будівельні рішення Дерева з стяжки: підручник з кодування початківців
Table of Contents
Рішення дерев є одним з найбільш інтуїтивно зрозумілих і широко використовуваних алгоритмів машинного навчання для класифікації і регресія. Вони працюють, розщеплюючи дані в гілки, засновані на значеннях функцій, мимлюючий спосіб людини приймає рішення. Хоча бібліотеки, такі як scikit‐learn, приймають рішення дерева тривіаль, реалізуючи один з подряпин є відмінним способом для новачків, щоб захопити внутрішні роботи алгоритму. Цей підручник буде направляти вас через теорію і код, так що ви можете побудувати власний дерево рішень з нуля.
Що таке рішення?
Дерево рішення - це структура, де кожен внутрішній вузол являє собою тест на функцію (наприклад, «Іс-рок» > 30?»), кожен відділ представляє результат цього тесту, і кожен вузол листування має етикетку класу або безперервне значення. Мета полягає в створенні моделі, яка прогнозує цільову змінну шляхом вивчення простих правил прийняття рішень, що посилаються з особливостей даних. Дерева рішень популярні, оскільки вони легко інтерпретуються і вимагають малої інформації (не масштабування або нормалізація).
Дерево побудовано прямо: починаючи від кореня, алгоритм вибирає найкращу функцію і точку розщеплення, яка розділяє дані максимально чисто. Цей процес повторюється на кожному підмножинні до моменту завершення стану зупинки. Для більшого фону, Вікіпедія entry on the city learning] забезпечує надійний огляд.
Основні поняття Ви повинні витримати
Відсутні, філії та листя
Внутрішня вершина містить весь набір даних про навчання. Внутрішні вершини перевіряють функцію та розщеплюють дані на дві або більше дочірніх вузлів. Гілки є з'єднання, які представляють результат тесту. Листові вузли (термінальні вузли) виводять остаточне прогнозування – найбільш поширений клас класифікації або значення в регресії.
Розщеплення критерії
Для побудови дерева потрібно заміряти якість потенційного розщеплення. Найпоширенішими критеріями є:
- Gini домішка] – використовується в класифікації, щоб вимірювати, як часто вибраний елемент буде неправильно позначений, якщо він випадково позначений відповідно до розподілу класів в підмножині. Нижня Джіна краще.
- Entropy] – вимірює кількість порушень або невизначеності в множині. Мета полягає в мінімізації ентропії після розщеплення (інформаційне набуття).
- Визнання – використовується для регресія дерев. Розраховує зменшення варіантності (або на увазі похибку квадрата) досягається розщепленням.
Алгоритм оцінює кожен можливим розщеплення на кожній функції і підбирає той, що дає найбільше зниження домішок (або отримання інформації).
Інформація про Gain і Gain Ratio
Приріст інформації є відмінністю між домішками материнського вузла та вагою сумою дитячих домішок. Хоча простий, він прагне до вигоди функції з багатьма значеннями. Співвідношення наростання (використаний в C4.5) нормалізує це. Для цього уроці ми прилипаємо стандартну інформацію, використовуючи домішки Gini, яка є типовим у CART (класифікація та регієзнавчих дерев).
Будівництво рішення Дерево крок за кроком
1. Підготувати дані
Для простоти використовуйте бінарну класифікацію даних, що визначаються нумерними функціями. Наприклад:
- Особливості: Вік, Дохід
- Target: Затверджено (1) або Не затверджено (0)
Чисті дані: обробляти відсутні значення, видаляти дублікати, і забезпечити неоднорідні види. Рішення дерева можуть обробляти змішані типи даних, але ми прилипаємо до номемеричної для реалізації.
2. Визначення функції розщеплення
Ми втілюємо Gini домішки. Індекс Gini для набору предметів:
]
де p i є пропорція предметів в класі i. Для бінарного розщеплення загальний Gini є ваговим середнім частинам дочірніх вузлів.
3. Впровадження Split Оцінка
Для кожної функції сортуйте унікальні значення. Випробуйте кожен можливий поріг (середині між послідовними значеннями). Для кожного кандидата поріг розщепіть дані на ліві та праві групи, складіть Gini та відстежуйте найкращий розщеплення.
4. Побудувати Дерево Рекурсивно
Створіть функцію, яка бере підмножину даних і поточну глибину. Він перевіряє умови зупинки (наприклад, максимальну глибину досягається, мінімальні зразки на вершину або не отримують інформації). Якщо стан відповідає, створіть вузол листка з більшістю класу. В іншому випадку знайдіть найкращий розщеплення і створіть внутрішній вузол, після чого відступно викликайте функцію зліва і праві розщеплення.
5. Зробіть прогнози
Після того, як дерево побудовано, прогноз прямопередбачуваний: запустіть в корінь, слідуйте за галузями, оцінивши можливості тестів на новий зразок, і повертаєте значення листа, яке ви приземлите.
Повна реалізація на Python
Нижче наведено повну, мінімальну реалізацію дерева рішень для класифікації за допомогою Gini домішки. Цей код призначений для навчання – він не оптимізований для великих даних.
import numpy as np
from collections import Counter
class DecisionTree:
def __init__(self, max_depth=None, min_samples_split=2):
self.max_depth = max_depth
self.min_samples_split = min_samples_split
self.tree = None
def fit(self, X, y):
dataset = np.column_stack((X, y))
self.tree = self._grow_tree(dataset)
def _grow_tree(self, dataset, depth=0):
X, y = dataset[:, :-1], dataset[:, -1]
n_samples, n_features = X.shape
n_labels = len(np.unique(y))
# Stopping conditions
if (n_labels == 1 or depth == self.max_depth or n_samples < self.min_samples_split):
leaf_value = Counter(y).most_common(1)[0][0]
return {'leaf': True, 'value': leaf_value}
best_feature, best_threshold = self._best_split(dataset, n_features)
if best_feature is None:
leaf_value = Counter(y).most_common(1)[0][0]
return {'leaf': True, 'value': leaf_value}
left_idx, right_idx = self._split(dataset[:, best_feature], best_threshold)
left_subtree = self._grow_tree(dataset[left_idx], depth+1)
right_subtree = self._grow_tree(dataset[right_idx], depth+1)
return {'leaf': False,
'feature': best_feature,
'threshold': best_threshold,
'left': left_subtree,
'right': right_subtree}
def _best_split(self, dataset, n_features):
best_gini = float('inf')
best_feature, best_threshold = None, None
for feature in range(n_features):
thresholds = np.unique(dataset[:, feature])
for i in range(len(thresholds)-1):
thresh = (thresholds[i] + thresholds[i+1]) / 2
left_idx, right_idx = self._split(dataset[:, feature], thresh)
if len(left_idx) == 0 or len(right_idx) == 0:
continue
gini = self._gini_gain(dataset, left_idx, right_idx)
if gini < best_gini:
best_gini = gini
best_feature = feature
best_threshold = thresh
return best_feature, best_threshold
def _split(self, values, threshold):
left_idx = np.where(values <= threshold)[0]
right_idx = np.where(values > threshold)[0]
return left_idx, right_idx
def _gini_gain(self, dataset, left_idx, right_idx):
total = len(left_idx) + len(right_idx)
gini_left = self._gini(dataset[left_idx, -1])
gini_right = self._gini(dataset[right_idx, -1])
return (len(left_idx)/total) * gini_left + (len(right_idx)/total) * gini_right
def _gini(self, labels):
_, counts = np.unique(labels, return_counts=True)
p = counts / np.sum(counts)
return 1 - np.sum(p**2)
def predict(self, X):
return np.array([self._predict_row(x, self.tree) for x in X])
def _predict_row(self, x, node):
if node['leaf']:
return node['value']
if x[node['feature']] <= node['threshold']:
return self._predict_row(x, node['left'])
else:
return self._predict_row(x, node['right'])
Тестування дерева
Використовуйте простий набір даних, як класичний ірис, який містить дані (дві функції для бінарної класифікації). scikit‐learn Iris dataset]. Порівняйте точність вашого дерева з scikit‐learn для перевірки правильності.
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
data = load_iris()
X = data.data[:100] # take only first two classes (binary)
y = data.target[:100]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
tree = DecisionTree(max_depth=3)
tree.fit(X_train, y_train)
preds = tree.predict(X_test)
accuracy = np.mean(preds == y_test)
print(f'Accuracy: {accuracy:.2f}')
Додаткові методи для поліпшення вашого дерева
Виконувати, щоб уникнути перенаряддя
Повно вирощене дерево може запам'ятати шум у даних про навчання. Виконуючи вилучення гілок, які мають мало передбачувану потужність. Загальні методи передпобіжні (зростання на початку після або ]) і післяоперації (зростання повного дерева, після видалення гілок за допомогою набору перевірки або вартості.
Обробка безперервних і катогорічних характеристик
Для безперервних функцій ми використовували середні точки між сортованими значеннями як пороги. Для категоричних особливостей (наприклад, «Колор = червоний/зелений/синій»), кожна категорія може стати окремою галицею (багатосторонній спліт) або ви можете бінарними методами їх. Більшість сучасних реалізацій (подібна scikit‐learn) використовують бінарні спліти навіть для категоричних особливостей, оцінюючи всі підкладки.
Зцілення з пропускними значеннями
Негайні дані в реальному житті часто не мають значення. Простий підхід полягає в тому, щоб призначити відсутні значення до найбільш частого відділення серед зразків підготовки, які мають функцію. C4.5 використовує імовірнісний метод. Оскільки це початковий підручник, ми припустимо, що дані завершені.
Порівняти з абразивами та подальшим читанням
Під час побудови з нуля є навчальні, виробничі системи використовують бібліотеки, такі як scikit‐learn, які забезпечують оптимальні впровадження C. Ви можете дізнатися більше з офіційної scikit‐learn рішення, документації дерев]. Для більш глибокої теорії книги « Елементи статистичного навчання» Hastie, Tibshirani та Friedman є авторитетним ресурсом. Ще одним відмінним посиланням є оригінальна книга CART від Breiman et al.
Висновок
Побудова дерева рішення з нуля визнає одне з найбільш фундаментальних алгоритмів в машинному навчанні. Ви навчилися, як проста процедура прямої розщеплення може виробляти потужну модель. Списаючи код самостійно, ви отримуєте більш глибоке розуміння порушень, розщеплення, а торгові марки між двома і варіакцією. Як наступний крок, спробуйте додавати регресивну підтримку, обрізку або обробки категоричних особливостей. Навички ви розробляєте тут, служитимуть вам, а ви переходите на більш складні методи ансамблю, як випадкові ліси і градієнтний приріст.