2

我正在使用 xgboost python 来执行文本分类

下面是我正在考虑的火车

itemid       description                                            category
11802974     SPRO VUH3C1 DIFFUSER VUH1 TRIPLE Space heaters    Architectural Diffusers
10688548     ANTIQUE BRONZE FINISH PUSHBUTTON  switch           Door Bell Pushbuttons
9836436     Descente pour Cable tray fitting and accessories    Tray Cable Drop Outs

我正在使用 Sckit learn 的 counvectorizer 构建描述的文档术语矩阵,它使用下面的代码生成 scipy 矩阵(因为我有 110 万的大量数据,我正在使用稀疏表示来降低空间复杂度)

countvec = CountVectorizer()
documenttermmatrix=countvec.fit_transform(trainset['description'])

之后,我将使用上述矩阵应用特征选择

 fs = feature_selection.SelectPercentile(feature_selection.chi2, percentile=40)
 documenttermmatrix_train= fs.fit_transform(documenttermmatrix,y1_train)

我正在使用 xgboost 分类器来训练模型

model = XGBClassifier(silent=False)

model.fit(documenttermmatrix_train, y_train,verbose=True)

以下是我正在考虑的测试集

itemid      description                       category
9836442     TRIPLE Space heaters              Architectural Diffusers
13863918    pushbutton switch                  Door Bell Pushbuttons

我正在为测试集构建单独的矩阵,就像我使用下面的代码为训练集做的那样

 documenttermmatrix_test=countvec.fit_transform(testset['description'])

虽然预测测试集 Xgboost 期望训练集的所有特征都在测试集中,但这是不可能的(稀疏矩阵仅表示非零条目)

我无法将训练集和测试集组合成单个数据集,因为我只需要为训练集进行特征选择

谁能告诉我如何进一步接近?

4

3 回答 3

3

而不是countvec.fit_transform()在测试集上使用,只使用transform().

更改此行:

documenttermmatrix_test=countvec.fit_transform(testset['description'])

对此:

documenttermmatrix_test=countvec.transform(testset['description'])

这将确保训练集中存在的那些特征仅取自测试集,如果不可用,则将 0 放在那里。

fit_transform() 将忘记先前训练的数据并生成新矩阵,该矩阵可以具有与先前输出不同的特征。因此错误。

于 2017-11-23T05:30:17.947 回答
2

您必须fit_transform在训练集上使用,但只能在测试集上进行转换。因此,默认输出countvectorizer是一个 csr 矩阵。它不适用于XGBClissifier,您必须将其转换为 csc 矩阵。简单地做:X = csc_matrix(X)

于 2017-11-23T23:52:04.267 回答
0

解决这个问题没有简单的方法,尽管它很常见。XGBoost 和其他基于树的模型可以处理具有比训练集更多变量的测试集(因为它可以忽略它们),但绝不会更少(因为它期望对它们做出决定)。在这种情况下,您有一些选择,按可取/可能性的降序排列来解决您的问题:

  1. 不要使用稀疏矩阵。除非您在实时应用程序或其他令人望而却步的生产环境中构建此模型,否则最简单的做法是使用保持零列的普通矩阵。

  2. 看看你是如何对数据进行分区的。可能只有一个或两个因素具有不平衡的拆分,在这种情况下,您可以通过玩弄 scikit learn 的train_test_split() 功能来获得更平等的表示。

  3. 自己修剪数据。与选项 2 类似,如果您认为有几个条目是罪魁祸首,并且删除它们不会损害您的模型,您可以尝试从原始数据集中删除它们。当然,这是最不理想的选择,但如果它们真的很少而且相差甚远,它们不会影响模型的预测能力。

但从广义上讲,这表明数据集不健康。我还建议您查看其他可能将数据分类或分类为更少组的方法,这样就不会出现问题。

于 2017-11-21T14:55:09.970 回答