Почему ошибка моей реализации AdaBoost не исчезает?

Я пытаюсь реализовать Adaboost M1 в Python из этого псевдокода: введите здесь описание изображения

Я кое-что добился, однако количество моих «неправильных прогнозов» не уменьшается.

Я проверил свою функцию обновления веса, и, похоже, она корректно обновляет веса.

Ошибка может быть в классификаторе, поскольку количество «неправильных прогнозов» является одним и тем же целым числом на каждой второй итерации - я пробовал 100 итераций. Я понятия не имею, почему он не дает меньше ошибок за итерацию.

Совет будет принят с благодарностью. Спасибо:)

from sklearn import tree
import pandas as pd
import numpy as np
import math

df = pd.read_csv("./dataset(3)/adaboost_train.csv")
X_train = df.loc[:,'x1':'x10']
Y_train = df[['y']]



def adaBoost(X_train,Y_train):
    classifiers = []
    # initializing the weights:
    N = len(Y_train)
    w_i = [1 / N] * N

    T = 20
    x_train = (X_train.apply(lambda x: x.tolist(), axis=1))
    clf_errors = []

    for t in range(T):
        print("Iteration:", t)
        # clf = clf2.fit(X_train,Y_train, sample_weight = w_i)

        clf = tree.DecisionTreeClassifier(max_depth=1)
        clf.fit(X_train, Y_train, sample_weight = w_i)

        #Predict all the values:
        y_pred = []
        for sample in x_train:
            p = clf.predict([sample])
            p = p[0]
            y_pred.append(p)
        num_of_incorrect = calculate_error_clf(y_pred, Y_train)


        clf_errors.append(num_of_incorrect)

        error_internal = calc_error(w_i,Y_train,y_pred)

        alpha = np.log((1-error_internal)/ error_internal)
        print(alpha)

        # Add the predictions, error and alpha for later use for every iteration
        classifiers.append((y_pred, error_internal, alpha))

        if t == 2 and y_pred == classifiers[0][0]:
            print("TRUE")


        w_i = update_weights(w_i,y_pred,Y_train,alpha,clf)


def calc_error(weights,Y_train,y_pred):
    err = 0
    for i in range(len(weights)):
        if y_pred[i] != Y_train['y'].iloc[i]:
            err= err + weights[i]
    # Normalizing the error:
    err = err/np.sum(weights)
    return err

# If the prediction is true, return 0. If it is not true, return 1.
def check_pred(y_p, y_t):
    if y_p == y_t:
        return 0
    else:
        return 1

def update_weights(w,y_pred,Y_train,alpha,clf):
    for j in range(len(w)):
        if y_pred[j] != Y_train['y'].iloc[j]:
            w[j] = w[j]* (np.exp( alpha * 1))
    return w

def calculate_error_clf(y_pred, y):
    sum_error = 0
    for i in range(len(y)):
        if y_pred[i] != y.iloc[i]['y']:
            sum_error += 1
        e = (y_pred[i] - y.iloc[i]['y'])**2


        #sum_error += e
    sum_error = sum_error
    return sum_error


Я ожидаю, что ошибка уменьшится, но это не так. Например:

iteration 1: num_of_incorrect 4444
iteration 2: num_of_incorrect 4762
iteration 3: num_of_incorrect 4353
iteration 4: num_of_incorrect 4762
iteration 5: num_of_incorrect 4450
iteration 6: num_of_incorrect 4762
...
does not converge




person meerkat    schedule 23.03.2019    source источник


Ответы (1)


Количество ошибочных классификаций НЕ будет уменьшаться с каждой итерацией (поскольку каждый классификатор является недельным классификатором). Это ансамблевая модель, в которой больший вес придается ранее ошибочно классифицированной выборке. Таким образом, на следующей итерации некоторые из ранее неправильно классифицированных выборок будут правильно классифицированы, но это также может привести к неправильной классификации ранее правильно классифицированных выборок (следовательно, ошибка уровня итерации не улучшается). Несмотря на то, что каждый классификатор слаб, поскольку окончательный результат представляет собой взвешенную сумму всех классификаторов, окончательная классификация сходится к сильному ученику (см. Строку 3 алгоритма).

Моя реализация с использованием numpy

from sklearn import tree
import pandas as pd
import numpy as np
import math
from sklearn.datasets import load_breast_cancer, classification_report
from sklearn.metrics import confusion_matrix

data = load_breast_cancer()
X_train = data.data
Y_train = np.where(data.target == 0, 1, -1)

def adaBoost(X_train,Y_train):
    classifiers = []
    # initializing the weights:
    N = len(Y_train)
    w_i = np.array([1 / N] * N)

    T = 20
    clf_errors = []

    for t in range(T):
        clf = tree.DecisionTreeClassifier(max_depth=1)
        clf.fit(X_train, Y_train, sample_weight = w_i)

        #Predict all the values:
        y_pred = clf.predict(X_train)   
        #print (confusion_matrix(Y_train, y_pred))

        # Line 2(b) of algorithm 
        error = np.sum(np.where(Y_train != y_pred, w_i, 0))/np.sum(w_i)
        print("Iteration: {0}, Missed: {1}".format(t, np.sum(np.where(Y_train != y_pred, 1, 0))))

        # Line 2(c) of algorithm 
        alpha = np.log((1-error)/ error)
        classifiers.append((alpha, clf))
        # Line 2(d) of algorithm 
        w_i = np.where(Y_train != y_pred, w_i*np.exp(alpha), w_i)
    return classifiers

clfs = adaBoost(X_train, Y_train)

# Line 3 of algorithm 
def predict(clfs, x):
    s = np.zeros(len(x))
    for (alpha, clf) in clfs:
        s += alpha*clf.predict(x)
    return np.sign(s)

print (confusion_matrix(Y_train, predict(clfs,X_train)))

Вывод:

Iteration: 0, Missed: 44 Iteration: 1, Missed: 48 Iteration: 2, Missed: 182 Iteration: 3, Missed: 73 Iteration: 4, Missed: 102 Iteration: 5, Missed: 160 Iteration: 6, Missed: 185 Iteration: 7, Missed: 69 Iteration: 8, Missed: 357 Iteration: 9, Missed: 127 Iteration: 10, Missed: 256 Iteration: 11, Missed: 160 Iteration: 12, Missed: 298 Iteration: 13, Missed: 64 Iteration: 14, Missed: 221 Iteration: 15, Missed: 113 Iteration: 16, Missed: 261 Iteration: 17, Missed: 368 Iteration: 18, Missed: 49 Iteration: 19, Missed: 171 [[354 3] [ 3 209]]

precision recall f1-score support -1 0.99 0.99 0.99 357 1 0.99 0.99 0.99 212 avg / total 0.99 0.99 0.99 569

Как видите, количество промахов не улучшится, однако, если вы проверите матрицу путаницы (раскомментируйте код), вы увидите, что некоторые из ранее неправильно классифицированных образцов будут правильно классифицированы. Наконец, для прогнозов, поскольку мы взвешиваем классификаторы по ошибке, сумма весов сходится к сильному классификатору (как видно из сделанных окончательных прогнозов).

person mujjiga    schedule 23.03.2019
comment
Здесь вы оба напечатали количество ошибочно классифицированных меток для каждой итерации. А как насчет err_m? Можем ли мы ожидать, что этот показатель снизится или увеличится? - person pydrink; 07.03.2021