2017-03-27 3 views
0

ich auf Textklassifikation arbeite und nach der Merkmalsextraktion Schritt bekam ich ziemlich Matrizen, aus diesem Grund inkrementelles Lernen zu verwenden, habe ich versucht, wie folgt:Probleme beim Versuch, ein Cross-validiertes Out-of-Core-Lernmodell zu implementieren?

import xgboost as xgb 
from sklearn.model_selection import ShuffleSplit, train_test_split 
from sklearn.metrics import accuracy_score as acc 


def incremental_learning2(X, y): 
    # split data into training and testing sets 
    # then split training set in half 

    X_train, X_test, y_train, y_test = train_test_split(X, 
                 y, test_size=0.1, 
                 random_state=0) 

    X_train_1, X_train_2, y_train_1, y_train_2 = train_test_split(X_train, 
                y_train, 
                test_size=0.5, 
                random_state=0) 

    xg_train_1 = xgb.DMatrix(X_train_1, label=y_train_1) 
    xg_train_2 = xgb.DMatrix(X_train_2, label=y_train_2) 
    xg_test = xgb.DMatrix(X_test, label=y_test) 

    #params = {'objective': 'reg:linear', 'verbose': False} 
    params = {} 


    model_1 = xgb.train(params, xg_train_1, 30) 
    model_1.save_model('model_1.model') 

    # ================= train two versions of the model =====================# 
    model_2_v1 = xgb.train(params, xg_train_2, 30) 
    model_2_v2 = xgb.train(params, xg_train_2, 30, xgb_model='model_1.model') 

    #Predictions 
    y_pred = model_2_v2.predict(X_test) 

    kfold = StratifiedKFold(n_splits=10, random_state=1).split(X_train, y_train) 
    scores = [] 

    for k, (train, test) in enumerate(kfold): 
     model_2_v2.fit(X_train[train], y_train[train]) 
     score = model_2_v2.score(X_train[test], y_train[test]) 
     scores.append(score) 

     print('Fold: %s, Class dist.: %s, Acc: %.3f' % (k+1, np.bincount(y_train[train]), score)) 
    print('\nCV accuracy: %.3f +/- %.3f' % (np.mean(scores), np.std(scores))) 

In Bezug auf die oben genannten Code. Ich habe versucht, eine Kreuzvalidierung durchzuführen und einige Instanzen vorherzusagen. Es funktioniert jedoch nicht. Wie kann ich den obigen Code reparieren, um nach der Anpassung und Aktualisierung des GBM-Modells in einem sehr großen Datensatz übergreifend validierte Metriken und Vorhersagen zu erhalten?

+0

Können Sie näher auf "es funktioniert nicht"? Außerdem werden Sie wahrscheinlich mehr auf die Frage werfen, wenn Sie das 'python'-Tag hinzufügen. – Tchotchke

+0

Ja ... Wenn ich sage "funktioniert nicht" möchte ich sagen, dass der obige Code nicht funktioniert. @Tchotchke – tumbleweed

+0

Es gibt viele Möglichkeiten, in denen etwas nicht funktionieren kann. Sie erhalten einen Fehler, und wenn ja - wo? Sie erhalten keine Ergebnisse wie erwartet usw.Je mehr Details du gibst, desto einfacher ist es für die Menschen, dir zu helfen. – Tchotchke

Antwort

1

Dies ist die Lösung, die ich mir ausgedacht habe. Zunächst importieren wir die notwendigen Module und definieren eine einfache Funktion der quadratischen mittleren Fehler zu berechnen:

import numpy as np 
import xgboost as xgb 
from sklearn.model_selection import train_test_split as tts 
from sklearn.model_selection import StratifiedKFold 

def rmse(a, b): 
    return np.sqrt(((a - b) ** 2).mean()) 

Die mittleren quadratischen Fehler anders berechnet werden kann (schauen Sie in this thread für Details), aber aus Gründen der Übersichtlichkeit habe ich gewählt, ein explizite Formulierung.

Und hier ist eine schnelle und schmutzige Version Ihrer Funktion. Ich habe versucht, die Struktur deines Codes gleich zu halten, aber um der Lesbarkeit willen habe ich etwas Refactoring durchgeführt.

def incremental_learning2(X, y, n_splits=10, params = {}):  
    # Initialize score arrays 
    sc_1, sc_2_v1, sc_2_v2 = (np.zeros(n_splits) for i in range(3)) 
    # Create cross-validator 
    kfold = StratifiedKFold(n_splits=n_splits, random_state=0).split(X, y) 
    # Iterate through folds 
    for k, (train, test) in enumerate(kfold): 
     # Split data 
     X_test, y_test = X[test], y[test]  
     splits = tts(X[train], y[train], test_size=0.5, random_state=0) 
     X_train_1, X_train_2, y_train_1, y_train_2 = splits 
     # Create data matrices 
     xg_train_1 = xgb.DMatrix(X_train_1, label=y_train_1) 
     xg_train_2 = xgb.DMatrix(X_train_2, label=y_train_2) 
     xg_test = xgb.DMatrix(X_test, label=y_test)  
     # Fit models 
     model_1 = xgb.train(params, xg_train_1, 30)   
     model_1.save_model('model_1.model') 
     model_2_v1 = xgb.train(params, xg_train_2, 30) 
     model_2_v2 = xgb.train(params, xg_train_2, 30, xgb_model='model_1.model') 
     # Make predictions and compute scores 
     preds = (m.predict(xg_test) for m in [model_1, model_2_v1, model_2_v2]) 
     sc_1[k], sc_2_v1[k], sc_2_v2[k] = (rmse(p, y_test) for p in preds) 
    # Return scores 
    return sc_1, sc_2_v1, sc_2_v2 

Ich habe auch das Ausgabeformat verbessert, um Ergebnisse in Form einer Tabelle anzuzeigen. Diese Funktionalität wird in einer separaten Funktion implementiert:

def display_results(a, b, c): 
    def hline(): 
     print('-'*50) 
    print('Cross-validation root mean square error\n')  
    print('Fold\tmodel_v1\tmodel_2_v1\tmodel_2_v2') 
    hline() 
    for k, (ak, bk, ck) in enumerate(zip(a, b, c)): 
     print('%s\t%.3f\t\t%.3f\t\t%.3f' % (k+1, ak, bk, ck))   
    hline() 
    print('Avg\t%.3f\t\t%.3f\t\t%.3f' % tuple(np.mean(s) for s in [a, b, c])) 
    print('Std\t%.3f\t\t%.3f\t\t%.3f' % tuple(np.std(s) for s in [a, b, c])) 

Demo

Wie Sie nicht Ihre Datenmenge teilen Ich hatte Mock-Daten zu erzeugen, um meinen Code zu testen.

from sklearn.datasets import make_blobs 
X, y = make_blobs(n_samples=500000, centers=50, random_state=0) 

scores_1, scores_2_v1, scores2_v2 = incremental_learning2(X, y) 
display_results(scores_1, scores_2_v1, scores2_v2) 

Der obige Code läuft ohne Fehler und die Ausgabe sieht wie folgt aus:

Cross-validation root mean square error 

Fold model_v1  model_2_v1  model_2_v2 
-------------------------------------------------- 
1  9.127   9.136   9.116 
2  9.168   9.155   9.128 
3  9.117   9.095   9.080 
4  9.107   9.113   9.089 
5  9.122   9.126   9.109 
6  9.096   9.099   9.084 
7  9.148   9.163   9.145 
8  9.089   9.090   9.069 
9  9.128   9.122   9.108 
10  9.185   9.162   9.160 
-------------------------------------------------- 
Avg  9.129   9.126   9.109 
Std  0.029   0.026   0.028 

Bemerkungen

  • Zum Vergleich Ich habe auch model_1-Kreuz validiert.
  • In der Probe laufen model_1 und model_2_v1 haben ungefähr die gleiche Genauigkeit, während model_2_v2 führt etwas besser, als man vernünftigerweise erwarten könnte.
  • Ich spielte herum mit der Größe des Datensatzes (n_samples) und die Anzahl der Klassen (centers) und interessanterweise, wenn die Werte dieser Parameter reduziert werden model_2_v2 ist die am wenigsten genaue der drei.
  • Hoffentlich sollte die Verwendung einer anderen Konfiguration, d. H. Ordnungsgemäßes Festlegen des benannten Funktionsarguments params, Dinge wie erwartet funktionieren lassen.
+0

Danke für die Hilfe !. Ich überprüfe die Antwort. – tumbleweed

Verwandte Themen