Jak wykorzystać kikut decyzyjny jako słabego ucznia w Adaboost?

12

Chcę wdrożyć Adaboost przy użyciu decyzji Stump. Czy poprawne jest podejmowanie tylu decyzji, ile funkcji naszego zestawu danych w każdej iteracji Adaboost?

Na przykład, jeśli mam zestaw danych z 24 funkcjami, czy powinienem mieć 24 klasyfikatory kikutów decyzyjnych w każdej iteracji? A może powinienem losowo wybierać niektóre funkcje i tworzyć na nich klasyfikator zamiast wszystkich funkcji?

Pegah
źródło

Odpowiedzi:

12

Typowym sposobem szkolenia (1-poziomowego) drzewa decyzyjnego jest znalezienie takiego atrybutu, który daje najczystszy podział. Tj. Jeśli podzielimy nasz zestaw danych na dwa podzbiory, chcemy, aby etykiety w tych podzestawach były jak najbardziej jednorodne. Można go zatem postrzegać jako budowanie wielu drzew - drzewa dla każdego atrybutu - a następnie wybieranie drzewa, które daje najlepszy podział.

W niektórych przypadkach sensowne jest również wybranie podzbioru atrybutów, a następnie wyszkolenie drzew w tym podzbiorze. Na przykład jest to używane w Losowym lesie w celu zmniejszenia korelacji między poszczególnymi drzewami.

Ale jeśli chodzi o AdaBoost, zazwyczaj wystarczy, aby upewnić się, że podstawowy klasyfikator może zostać przeszkolony w ważonych punktach danych, a losowy wybór funkcji jest mniej ważny. Drzewa decyzyjne mogą obsługiwać wagi (patrz np. Tutaj lub tutaj ). Można tego dokonać poprzez zważenie udziału każdego punktu danych w całkowitym zanieczyszczeniu podzbioru.

Dla odniesienia dodam również moją implementację AdaBoost w pythonie, używając numpy i sklearnDecisionTreeClassifier z max_depth=1:

# input: dataset X and labels y (in {+1, -1})
hypotheses = []
hypothesis_weights = []

N, _ = X.shape
d = np.ones(N) / N

for t in range(num_iterations):
    h = DecisionTreeClassifier(max_depth=1)

    h.fit(X, y, sample_weight=d)
    pred = h.predict(X)

    eps = d.dot(pred != y)
    alpha = (np.log(1 - eps) - np.log(eps)) / 2

    d = d * np.exp(- alpha * y * pred)
    d = d / d.sum()

    hypotheses.append(h)
    hypothesis_weights.append(alpha)

Do przewidywania etykiet:

# X input, y output
y = np.zeros(N)
for (h, alpha) in zip(hypotheses, hypotheses_weight):
    y = y + alpha * h.predict(X)
y = np.sign(y)
Aleksiej Grigoriew
źródło
Dzięki. Czy kikut decyzyjny jest używany jako rpart (jako algorytm drzewa decyzyjnego) o maksymalnej głębokości 1? Mam na myśli, czy powinienem wybrać atrybut losowo, czy drzewo powinno się podzielić w oparciu o określone kryteria, takie jak Indeks Gini? @AlexeyGrigorev
Pegah
Kikut decyzyjny = 1 reguła = drzewo decyzyjne z jednym węzłem (z maksymalną głębokością 1). Powinieneś wybrać podział na podstawie jakiejś miary zanieczyszczenia, na przykład na podstawie indeksu Gini.
Alexey Grigorev
Dzięki za tę szczegółową odpowiedź!
xsari3x