我想知道下面的情况是如何发生的:
def fit(self, train, target): xgtrain = xgb.DMatrix(train, label=target, missing=np.nan) self.model = xgb.train(self.params, xgtrain, self.num_rounds)
我将训练数据集作为具有 5233 列的 csr_matrix 传递,在转换为 DMatrix 后,我得到了 5322 个特征。
后来在预测步骤中,由于上述错误,我得到了一个错误 🙁
def predict(self, test): if not self.model: return -1 xgtest = xgb.DMatrix(test) return self.model.predict(xgtest)
错误:… 训练数据没有以下字段:f5232
我如何保证正确地将我的 训练/测试 数据集转换为 DMatrix?
在 Python 中是否有类似于 R 的方法?
# 获取测试/训练稀疏矩阵的相同列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]
遗憾的是,我的方法不起作用:
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: # 似乎这是不可变结构,无法添加任何新项目!!! self.xgtest.feature_names.append(item)
回答:
一种可能的解释是,你的训练数据或测试数据中独有某个特征级别。这种情况通常在独热编码后发生,结果是一个大的矩阵,为你的分类特征的每个级别增加了一个新特征(列/变量)。
在你的情况下,看起来特征“f5232”要么只在训练数据集中,要么只在测试数据集中。无论哪种情况,模型评分都可能会抛出错误(在大多数机器学习包的实现中),因为:
- 如果只在训练数据中:模型对象(来自训练)会在其模型方程中引用此特征。在评分(在测试数据上)时,它会抛出错误说“我找不到这个列/特征”。
- 如果只在测试数据中(可能性较小,因为测试数据通常比训练数据小):模型对象(来自训练)不会在其模型方程中引用此特征。在评分(在测试数据上)时,它会抛出错误说“我有这个列,但模型方程中没有这个列”。这种错误的可能性也较小,因为大多数实现都意识到了这种情况(它们会忽略任何多余的列)。
解决方案:
- 最好的“自动化”解决方案是,在独热编码后,仅保留训练和测试数据中共有的那些列。
- 对于临时分析:如果你因为特征的重要性而无法放弃该特征的级别,那么可以进行分层抽样,以确保特征的所有级别都出现在训练和测试数据中。