转换为 DMatrix 后,XGBoost 训练和测试特征的差异

Spa*_*Boy 4 python numpy machine-learning python-2.7 xgboost

只是想知道下一种情况怎么可能:

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

在此输入图像描述 我将训练数据集作为具有 5233 列的csr_matrix传递,在转换为 DMatrix 后,我得到了 5322 个特征。

后来在预测步骤中,由于上述错误,我收到了错误:(

 def predict(self, test):
     if not self.model:
         return -1
     xgtest = xgb.DMatrix(test)
     return self.model.predict(xgtest)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

错误:...训练数据没有以下字段:f5232

如何保证将训练/测试数据集正确转换为 DMatrix?

有没有机会在Python中使用类似于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]
Run Code Online (Sandbox Code Playgroud)

不幸的是,我的方法不起作用:

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) 
Run Code Online (Sandbox Code Playgroud)

abh*_*eor 5

一种可能的解释是,您的特征级别仅在训练数据或测试数据中。这种情况通常发生在 one-hot 编码之后,其结果是一个大矩阵,每个级别的分类特征都有一个新特征(列/变量)。

在您的情况下,功能“f5232”看起来要么只在训练数据集中,要么只在测试数据集中。无论哪种情况,模型评分都可能会抛出错误(在 ML 包的大多数实现中),因为:

  1. 如果仅限于训练:模型对象(来自训练)将在其模型方程中引用此特征。在评分(测试时)期间,它将抛出一个错误,提示“我无法找到此列/功能”。
  2. 如果仅用于测试(不太可能,因为测试数据通常小于训练数据):模型对象(来自训练)将不会其模型方程中引用此特征。在评分(测试时)期间,它将抛出一个错误,提示“我有此列,但模型方程没有此列”。此错误的可能性也较小,因为大多数实现都认识到这种情况(它们将忽略任何无关的列)。

解决方案:

  1. 最好的“自动化”解决方案是仅保留那些训练和测试后 one-hot 编码所共有的列。
  2. 对于临时分析:如果由于功能的重要性而无法降低其级别,则进行分层抽样以确保该功能的所有级别都出现在训练和测试数据中。