La diferencia de XGBoost en las funciones de tren y prueba después de convertir a DMatrix

Solo me pregunto como es posible el siguiente caso:

def fit(self, train, target): xgtrain = xgb.DMatrix(train, label=target, missing=np.nan) self.model = xgb.train(self.params, xgtrain, self.num_rounds) 

introduzca la descripción de la imagen aquí Pasé el conjunto de datos del tren como csr_matrix con 5233 columnas, y después de convertir a DMatrix obtuve 5322 características.

Más adelante, predice el paso, obtuve un error como la causa del error anterior 🙁

  def predict(self, test): if not self.model: return -1 xgtest = xgb.DMatrix(test) return self.model.predict(xgtest) 

introduzca la descripción de la imagen aquí

Error: … los datos de entrenamiento no tenían los siguientes campos: f5232

¿Cómo puedo garantizar la conversión correcta de mis conjuntos de datos de prueba / tren a DMatrix?

¿Hay alguna posibilidad de usar en Python algo similar a R?

 # get same columns for test/train sparse matrixes col_order <- intersect(colnames(X_train_sparse), colnames(X_test_sparse)) X_train_sparse <- X_train_sparse[,col_order] X_test_sparse <- X_test_sparse[,col_order] 

Mi enfoque no funciona, por desgracia:

 def _normalize_columns(self): columns = (set(self.xgtest.feature_names) - set(self.xgtrain.feature_names)) | \ (set(self.xgtrain.feature_names) - set(self.xgtest.feature_names)) for item in columns: if item in self.xgtest.feature_names: self.xgtest.feature_names.remove(item) else: # seems, it's immutable structure and can not add any new item!!! self.xgtest.feature_names.append(item) 

Otra posibilidad es tener un nivel de función exclusivamente en datos de entrenamiento y no en datos de prueba. Esta situación ocurre principalmente mientras se publica una encoding activa cuya matriz resultante tiene un nivel para cada nivel de características categóricas. En su caso, parece que “f5232” es exclusivo en entrenamiento o en datos de prueba. Si cualquiera de los dos casos de puntuación del modelo puede generar un error (en la mayoría de las implementaciones de paquetes ML) porque:

  1. Si es exclusivo del entrenamiento: el objeto modelo tendrá referencia de esta característica en la ecuación del modelo. Al puntuar, se emitirá un error diciendo que no puedo encontrar esta columna.
  2. Si es exclusivo para la prueba (es menos probable que los datos de prueba sean generalmente más pequeños que los datos de entrenamiento): el objeto modelo NO tendrá referencia de esta característica en la ecuación del modelo. Al puntuar, se emitirá un error diciendo que obtuve esta columna, pero la ecuación del modelo no tiene esta columna. Esto también es menos probable porque la mayoría de las implementaciones son conscientes de este caso.

Soluciones:

  1. La mejor solución “automatizada” es mantener solo esas columnas, que son comunes tanto para el entrenamiento como para las pruebas posteriores a la encoding en caliente.
  2. Para un análisis ad hoc, si no puede darse el lujo de bajar el nivel de la función debido a su importancia, realice un muestreo estratificado para garantizar que todos los niveles de la función se distribuyan a los datos de capacitación y pruebas.

Esta situación puede suceder después de una encoding en caliente. Por ejemplo,

 ar = np.array([ [1, 2], [1, 0] ]) enc = OneHotEncoder().fit(ar) ar2 = enc.transform(ar) b = np.array([[1, 0]]) b2 = enc.transform(b) xgb_ar = xgb.DMatrix(ar2) xgb_b = xgb.DMatrix(b2) print(b2.shape) # (1, 3) print(xgb_b.num_col()) # 2 

Entonces, cuando tienes toda la columna cero en una matriz dispersa, DMatrix elimina esta columna (creo, porque esta columna es inútil para XGBoost)

Por lo general, agrego una fila falsa a la matriz que contiene 1 en todas las columnas.