A maneira típica de treinar uma Árvore de Decisão (de 1 nível) é encontrar um atributo que ofereça a divisão mais pura. Ou seja, se dividirmos nosso conjunto de dados em dois subconjuntos, queremos que os rótulos dentro desses subconjuntos sejam o mais homogêneos possível. Portanto, também pode ser visto como a construção de muitas árvores - uma árvore para cada atributo - e a seleção da árvore que produz a melhor divisão.
Em alguns casos, também faz sentido selecionar um subconjunto de atributos e treinar árvores no subconjunto. Por exemplo, isso é usado na Floresta Aleatória para reduzir a correlação entre árvores individuais.
Mas quando se trata do AdaBoost, normalmente é suficiente garantir que o classificador base possa ser treinado em pontos de dados pesados, e a seleção aleatória de recursos é menos importante. As árvores de decisão podem lidar com pesos (veja, por exemplo, aqui ou aqui ). Isso pode ser feito ponderando a contribuição de cada ponto de dados para a impureza total do subconjunto.
Para referência, também adicionarei minha implementação do AdaBoost em python usando numpy e sklearn'sDecisionTreeClassifier
com 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)
Para prever os rótulos:
# 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)