Skip to forum
Benachrichtigungen
Alles löschen

Hilfe bei Python Ensemble Learning - Codeanalyse [Biete €]

8 Beiträge
4 Benutzer
2 Reactions
1,353 Ansichten
SaLoZ
Joined: 16.01.2012

Hallo Pokergemeinde,

ich sitze für ein Uniprojekt an einem Pythoncode für Ensemble Learning. Ich habe die Grundsätze des Ensemble Learnings und die grundlegenden Modelle wie AdaBoost, CatBoost verstanden und nachvollziehen können, jedoch verstehe ich nicht, wie diese zusammen am Ende "verknüpft" werden um bessere Metrics zu erzielen (Accuracy, F1 Score). Es ist funktionsfähiger Code vorhanden, ich hoffe hier auf einen ML-Fortgeschrittenen, der das Schritt für Schritt mit mir durchgehen könnte, ich würde das gerne später "vereinfacht" selber schreiben können.

Ich weiß grundsätzlich nicht, ob man hier solche Anfragen posten darf, ich wollte einfach mal fragen. Wenn es möglich ist und sich jemand findet, würde ich vorschlagen, dass man das mit Zoom machen würde per Bildschirmübertragung. Ich würde dann auch bei PayPal dafür zahlen


Antwort
Zitat
7 replies
Izzet
Joined: 27.03.2006

Bin selbst ML Anfänger und kann dir daher wahrscheinlich nicht groß helfen. Der Sinn des Ensemble Learnings ist es ja, robustere Estimator zu erschaffen (höhere Accuracy bei Classification Problemen, niedrigerer MAE bei Regression). Eine Möglichkeit ist es, Averages der Predictions unterschiedlicher Estimator zu erstellen (meinst du das, mit "Verknüpfen"?). Eine weitere Möglichkeit ist das "boosten" wie es in den von dir genannten Methoden verwendet wird.. in der scikitlearn Doku gibts dazu ne Erläuterung, falls du die nicht schon gelesen hast.. https://scikit-learn.org/stable/modules/ensemble.html#adaboost


Antwort
Zitat
febsan
Joined: 20.09.2007

Ich glaub du willst folgendes:
1. trainiere dein Modell nichtdeterministisch n-mal
2. predicte mit n modellen und nehme einen Mittelwert der predictions (genomen wird meist arithmetisches mittel oder median)

/e: adaboost ist ja schon ein ensemble, da musst du nix mehr verknüpfen...


Antwort
Zitat
SaLoZ
Joined: 16.01.2012

Ich versuche euch zu zeigen, was ich meine. In dem Code wird XGBoost, CatBoost, ein DNN, usw. verwendet.

def score_function(TP,FP,FN,TN):
    return TP*5 + FP*(-25) + FN*(-5) + TN*0

def max_score_function(TP,FP,FN,TN):
    return (FN + TP) * 5

def crossvaltest_xg(params, X, y, n_splits=5):
    skf = StratifiedKFold(n_splits=5)
    accuracy, score, f1 = [], [], []
    for train_index, test_index in skf.split(X, y):
        X_train, X_test = X.iloc[train_index, :], X.iloc[test_index, :]         y_train, y_test = y.iloc[train_index], y.iloc[test_index]
        
        clf = XGBClassifier(**params)
        clf.fit(X_train, y_train)
        
        y_pred = np.array(clf.predict(X_test))
        tn, fp, fn, tp = confusion_matrix(y_test, y_pred).ravel()
        
        accuracy.append(accuracy_score(y_test, y_pred))
        score.append(score_function(tp,fp,fn,tn))
        f1.append(f1_score(y_test, y_pred))
        
    return np.mean(score)

def xgboost_param_tune(params, X, y ,n_splits=5):
    ps = paramsearch(params_xg)
    for prms in chain(ps.grid_search(['n_estimators','learning_rate']),
                      ps.grid_search(['max_depth','min_child_weight'])):
        res = crossvaltest_xg(prms,X, y,n_splits)
        ps.register_result(res,prms)
        print(res,prms,'best:',ps.bestscore(),ps.bestparam())
        print()
    return ps.bestparam(), ps.bestscore()

Das wird dann für alle Classifier gemacht.

Am Ende hat man dann ein Model Tuning:

params_xg = {'max_depth':[1, 2, 3, 4, 5, 6, 7, 8, 9],
             'n_estimators':[100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100],
             'learning_rate':[0.03,0.001,0.01,0.1], 
             'min_child_weight': [1,2,3,4]}

params_cat = {'depth':[1,3,5,7],
              'iterations':[100, 200,400,600,800,1000,2000],
              'learning_rate':[0.03,0.001,0.01,0.1], 
              'l2_leaf_reg':[1,5,10,100],
              'border_count':[2,5,10,20,50,100],
              'thread_count':4,
              'silent': True}

params_ada = {'learning_rate':[0.03,0.001,0.01,0.1],
              'n_estimators':[100, 300, 500, 700, 900, 1000],
              'algorithm': ['SAMME', 'SAMME.R']}

params_log_reg = {'C':[0.001,0.01,0.1,1,10,100,1000]}

params_dnn = {'epochs': 500, 'batch_size': 32}

params_log_reg, best_log_reg = log_reg_param_tune(params_log_reg,X, y)
params_xg_boost, best_xg = xgboost_param_tune(params_xg,X, y)
params_ada, best_ada = ada_param_tune(params_ada,X, y)
params_cat, best_cat = cat_param_tune(params_cat,X, y)
best_dnn = DNN(params_dnn)

Und dann die Predictions:

skf = StratifiedKFold(n_splits=5)
accuracy, score, f1 = [], [], []
for train_index, test_index in skf.split(X, y):
    X_train, X_test = X.iloc[train_index, :], X.iloc[test_index, :]     y_train, y_test = y.iloc[train_index], y.iloc[test_index]
    
    clf = LogisticRegression(**params_log_reg)
    clf.fit(X_train, y_train)
    y_pred_log_reg = np.array(clf.predict(X_test))
    
    clf = XGBClassifier(**params_xg_boost)
    clf.fit(X_train, y_train)
    y_pred_xg = np.array(clf.predict(X_test))
    
    clf = AdaBoostClassifier(**params_ada)
    clf.fit(X_train, y_train)
    y_pred_ada = np.array(clf.predict(X_test))
    
    clf = CatBoostClassifier(**params_cat)
    clf.fit(X_train, y_train)
    y_pred_cat = np.array(clf.predict(X_test))
    
    X_train = np.array(X_train)
    X_test = np.array(X_test)
    y_train = np.array(y_train)
    y_test = np.array(y_test)
        
   
    X_train_dnn = sc.fit_transform(X_train)
    X_test_dnn = sc.transform(X_test)
    clf = Sequential()
    clf.add(Dense(128, activation='relu', kernel_initializer='random_normal', input_dim=14))
    clf.add(Dense(128, activation='relu', kernel_initializer='random_normal'))
    clf.add(Dense(1, activation='sigmoid', kernel_initializer='random_normal'))
    clf.compile(optimizer ='adam',loss='binary_crossentropy', metrics =['accuracy'])
    clf.fit(X_train_dnn, y_train, epochs=params_dnn['epochs'], batch_size=params_dnn['batch_size'], verbose = False)
    y_pred_dnn = np.array(clf.predict(X_test_dnn))
    y_pred_dnn[y_pred_dnn>0.5] = 1
    y_pred_dnn[y_pred_dnn<0.5] = 0
    
    y_pred = []
    for i in range(len(y_pred_cat)):
        temp_prediction = [float(y_pred_log_reg[i]), float(y_pred_xg[i]), float(y_pred_ada[i]), float(y_pred_cat[i]), float(y_pred_dnn[i])]
        y_pred.append(most_common(temp_prediction))
    tn, fp, fn, tp = confusion_matrix(y_test, y_pred).ravel()

    accuracy.append(accuracy_score(y_test, y_pred))
    score.append(score_function(tp,fp,fn,tn))
    f1.append(f1_score(y_test, y_pred))

print('Mean Score = {0}'.format(np.mean(score)))
print('Mean Accuracy = {0}'.format(np.mean(accuracy)))
print('Mean F1_score = {0}'.format(np.mean(f1)))

Am Ende hat man dann ein Ergebnis:

Mean Score = 51.0
Mean Accuracy = 0.9898865248226949
Mean F1_score = 0.903135888501742

Versteht ihr, wo diese "Verknüpfung" zustande kommt?
Man hat ja mehrere Classifier aber am Ende "Mean Scores" von allen zusammen.


Antwort
Zitat
flowIIpoker
Joined: 14.02.2007

mal eine frage.

ist das eigentlich guter stil berechnungen in das returnstatement zu schreiben?!?
das kenn ich so eigentlich nicht (und ich spreche mehr als eine programmiersprache) und scheint auch erst neuerdings mode geworden zu sein


Antwort
Zitat
Izzet
Joined: 27.03.2006

Original von SaLoZ

Versteht ihr, wo diese "Verknüpfung" zustande kommt?
Man hat ja mehrere Classifier aber am Ende "Mean Scores" von allen zusammen.

Die Verknüpfung scheint hier zustande zu kommen:
y_pred = []
for i in range(len(y_pred_cat)):
temp_prediction = [float(y_pred_log_reg), float(y_pred_xg), float(y_pred_ada), float(y_pred_cat), float(y_pred_dnn)]
y_pred.append(most_common(temp_prediction))
tn, fp, fn, tp = confusion_matrix(y_test, y_pred).ravel()

Aus der temp_prediction list, die die Predictions der einzelnen Classifier enthält, wird anscheind irgendein Wert selektiert?


Antwort
Zitat
flowIIpoker
Joined: 14.02.2007

bei dem uneingeruecktem code. meinst du da hat jemand lust den zu lesen

sowas empfinde ich schon in anderen sprachen als unhoeflich
aber bei python ist das syntax

also ich kuck mir das gar nicht erst an und es wird vielen auch so gehen, die taeglich ihr geld damit verdienen


Antwort
Zitat
SaLoZ
Joined: 16.01.2012

Sorry, ich bin auch relativer Python-Neuling und bin direkt ins ML "eingetaucht". Wollte also nicht unhöflich sein . Ich habs so übernommen, wie es gecodet wurde. Hab das dann quasi einfach zum Laufen gebracht auf meinem Rechner und ich jetzt probiere ich das zu verstehen und es quasi "in einfacherem Code" nochmal selbst zu schreiben.

Mein Angebot steht nach wie vor, den Code via Zoom gegen Bezahlung durchzugehen.


Antwort
Zitat