numpy 转换为DMatrix后XGBoost训练和测试功能的差异

epggiuax  于 2023-06-23  发布在  其他
关注(0)|答案(3)|浏览(136)

只是想知道下一个案例是如何可能的:

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

x1c 0d1x我将训练数据集作为csr_matrix传递,其中有5233列,在转换为DMatrix后,我得到了5322个特征。
后来在预测步骤中,我得到了一个错误,因为上面的bug:(

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

错误:...训练数据没有以下字段:f5232
如何保证将我的train/test数据集正确转换到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]

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

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)
eqfvzcg8

eqfvzcg81#

一种可能的解释是,您在训练数据或测试数据中专门拥有一个特征级别。这种情况经常发生在one-hot编码之后,其结果是一个大矩阵,对于分类特征的每个级别都有一个新特征(列/变量)。
在你的例子中,看起来特征“f5232”要么只在训练数据集中,要么只在测试数据集中。在这两种情况下,模型评分都可能抛出错误(在大多数ML包的实现中),因为:
1.如果仅限于培训:模型对象(来自训练)将在其模型方程中引用此特征。在评分(测试)期间,它将抛出一个错误,说“我无法找到此列/功能”。
1.如果专用于测试(不太可能,因为测试数据通常小于训练数据):模型对象(来自训练)将 NOT 在其模型方程中引用此特征。在评分(测试)期间,它会抛出一个错误,说“我有这个列,但模型方程没有这个列”。这种错误也不太可能发生,因为大多数实现都知道这种情况(它们将忽略任何无关的列)。
解决方案:
1.最好的“自动化”解决方案是只保留那些列,这些列是训练和测试后one-hot编码所共有的。
1.对于特别分析:如果由于特征的重要性而不能降低特征的级别,那么就进行分层抽样,以确保特征的所有级别都出现在训练数据和测试数据中。

7fyelxc5

7fyelxc52#

这种情况可能发生在one-hot编码之后。比如说

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

所以,当稀疏矩阵中的所有列都是零时,DMatrix会删除这个列(我想,因为这个列对XGBoost没用)
通常,我在矩阵中添加一个伪行,其所有列中的内容都是1。

mzaanser

mzaanser3#

当RandomUnderSampler(罗斯)方法返回一个np.array而不是一个带有列名的Pandas DataFrame时,我就遇到了这样的问题。

from imblearn.under_sampling import RandomUnderSampler
rus = RandomUnderSampler(return_indices=True)
X_rus, y_rus, id_rus = rus.fit_sample(X_train, y_train)

我用这个解决了这个问题:

X_rus = pd.DataFrame(X_rus, columns = X_train.columns)

基本上是获取罗斯方法的输出,并从中创建一个Pandas DataFrame,其中包含来自原始X_train数据的列名,这些数据是RUS方法的输入。
这可以推广到任何类似的问题,XGBoost期望读取列名,但不能。只需创建一个Pandas DataFrame并相应地分配列名。

相关问题