xgboostclassifier xgbclassifier sklearn predict_proba how example datacamp python machine-learning xgboost

python - xgbclassifier - ¿Cómo puedo implementar entrenamiento incremental para xgboost?



xgboost python install (6)

Ahora hay (¿versión 0.6?) Un parámetro process_update que podría ayudar. Aquí hay un experimento con él:

import pandas as pd import xgboost as xgb from sklearn.model_selection import ShuffleSplit from sklearn.datasets import load_boston from sklearn.metrics import mean_squared_error as mse boston = load_boston() features = boston.feature_names X = boston.data y = boston.target X=pd.DataFrame(X,columns=features) y = pd.Series(y,index=X.index) # split data into training and testing sets rs = ShuffleSplit(test_size=0.3, n_splits=1, random_state=0) for train_idx,test_idx in rs.split(X): # this looks silly pass train_split = round(len(train_idx) / 2) train1_idx = train_idx[:train_split] train2_idx = train_idx[train_split:] X_train = X.loc[train_idx] X_train_1 = X.loc[train1_idx] X_train_2 = X.loc[train2_idx] X_test = X.loc[test_idx] y_train = y.loc[train_idx] y_train_1 = y.loc[train1_idx] y_train_2 = y.loc[train2_idx] y_test = y.loc[test_idx] xg_train_0 = xgb.DMatrix(X_train, label=y_train) 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} model_0 = xgb.train(params, xg_train_0, 30) 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) params.update({''process_type'': ''update'', ''updater'' : ''refresh'', ''refresh_leaf'': True}) model_2_v2_update = xgb.train(params, xg_train_2, 30, xgb_model=model_1) print(''full train/t'',mse(model_0.predict(xg_test), y_test)) # benchmark print(''model 1 /t'',mse(model_1.predict(xg_test), y_test)) print(''model 2 /t'',mse(model_2_v1.predict(xg_test), y_test)) # "before" print(''model 1+2/t'',mse(model_2_v2.predict(xg_test), y_test)) # "after" print(''model 1+update2/t'',mse(model_2_v2_update.predict(xg_test), y_test)) # "after"

Salida:

full train 17.8364309709 model 1 24.2542132108 model 2 25.6967017352 model 1+2 22.8846455135 model 1+update2 14.2816257268

El problema es que los datos de mi tren no se pudieron colocar en la RAM debido al tamaño de los datos del tren. Así que necesito un método que primero genere un árbol en un conjunto completo de datos de trenes, calcule los residuos construya otro árbol y así sucesivamente (como lo hace el árbol de gradiente aumentado) Obviamente, si llamo a model = xgb.train(param, batch_dtrain, 2) en algún bucle, no servirá de nada, porque en ese caso simplemente reconstruye el modelo completo para cada lote.


Descargo de responsabilidad: Soy nuevo en xgboost también, pero creo que me di cuenta de esto.

Intenta guardar tu modelo después de entrenar en el primer lote. Luego, en ejecuciones sucesivas, proporcione el método xgb.train con la ruta de archivo del modelo guardado.

Aquí hay un pequeño experimento que corrí para convencerme de que funciona:

Primero, divida el conjunto de datos de Boston en conjuntos de entrenamiento y pruebas. Luego dividir el conjunto de entrenamiento en mitades. Ajuste un modelo con la primera mitad y obtenga una puntuación que servirá como punto de referencia. Luego encaja dos modelos con la segunda mitad; Un modelo tendrá el parámetro adicional xgb_model . Si pasar el parámetro extra no hizo una diferencia, entonces esperaríamos que sus puntuaciones fueran similares ... Pero, afortunadamente, el nuevo modelo parece funcionar mucho mejor que el primero.

import xgboost as xgb from sklearn.cross_validation import train_test_split as ttsplit from sklearn.datasets import load_boston from sklearn.metrics import mean_squared_error as mse X = load_boston()[''data''] y = load_boston()[''target''] # split data into training and testing sets # then split training set in half X_train, X_test, y_train, y_test = ttsplit(X, y, test_size=0.1, random_state=0) X_train_1, X_train_2, y_train_1, y_train_2 = ttsplit(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} 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'') print(mse(model_1.predict(xg_test), y_test)) # benchmark print(mse(model_2_v1.predict(xg_test), y_test)) # "before" print(mse(model_2_v2.predict(xg_test), y_test)) # "after" # 23.0475232194 # 39.6776876084 # 27.2053239482

Déjame saber si algo no está claro!

referencia: https://github.com/dmlc/xgboost/blob/master/python-package/xgboost/training.py


Para paulperry''s code, si cambia una línea de "train_split = round (len (train_idx) / 2)" a "train_split = len (train_idx) - 50". el modelo 1 + update2 cambiará de 14.2816257268 a 45.60806270012028. Y una gran cantidad de "hoja = 0" da como resultado un archivo de volcado.

El modelo actualizado no es bueno cuando el conjunto de muestra de actualización es relativamente pequeño. Para binary: logistic, el modelo actualizado no se puede utilizar cuando el conjunto de muestra de actualización solo tiene una clase.


Parece que no necesitas nada más que llamar a tu xgb.train(....) nuevo, pero proporciona el resultado del modelo del lote anterior:

# python params = {} # your params here ith_batch = 0 n_batches = 100 model = None while ith_batch < n_batches: d_train = getBatchData(ith_batch) model = xgb.train(params, d_train, xgb_model=model) ith_batch += 1

esto se basa en https://xgboost.readthedocs.io/en/latest/python/python_api.html


Si su problema está relacionado con el tamaño del conjunto de datos y realmente no necesita Aprendizaje Incremental (no está tratando con una aplicación de Streaming, por ejemplo), debería revisar Spark o Flink.

Estos dos marcos pueden entrenarse en conjuntos de datos muy grandes con una pequeña memoria RAM, aprovechando la memoria de disco. Ambos framework tratan los problemas de memoria internamente. Aunque Flink lo resolvió primero, Spark se ha puesto al día en los últimos lanzamientos.

Echa un vistazo a:


Creé una parte del cuaderno de jupyter para demostrar que el modelo xgboost se puede entrenar de manera incremental. Usé el conjunto de datos de Boston para entrenar el modelo. Hice 3 experimentos: aprendizaje de un disparo, aprendizaje de un disparo iterativo, aprendizaje incremental iterativo. En el entrenamiento incremental, pasé los datos de Boston al modelo en lotes de tamaño 50.

Lo esencial es que tendrá que recorrer los datos varias veces para que el modelo converja a la precisión alcanzada por el aprendizaje de un disparo (todos los datos).

Aquí está el código correspondiente para hacer un aprendizaje incremental iterativo con xgboost.

batch_size = 50 iterations = 25 model = None for i in range(iterations): for start in range(0, len(x_tr), batch_size): model = xgb.train({ ''learning_rate'': 0.007, ''update'':''refresh'', ''process_type'': ''update'', ''refresh_leaf'': True, #''reg_lambda'': 3, # L2 ''reg_alpha'': 3, # L1 ''silent'': False, }, dtrain=xgb.DMatrix(x_tr[start:start+batch_size], y_tr[start:start+batch_size]), xgb_model=model) y_pr = model.predict(xgb.DMatrix(x_te)) #print('' MSE itr@{}: {}''.format(int(start/batch_size), sklearn.metrics.mean_squared_error(y_te, y_pr))) print(''MSE itr@{}: {}''.format(i, sklearn.metrics.mean_squared_error(y_te, y_pr))) y_pr = model.predict(xgb.DMatrix(x_te)) print(''MSE at the end: {}''.format(sklearn.metrics.mean_squared_error(y_te, y_pr)))

Versión de XGBoost: 0.6