【问题标题】:error while predicting test data in xgboost python在xgboost python中预测测试数据时出错
【发布时间】:2018-05-04 14:46:27
【问题描述】:

我正在使用 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 期望训练集的所有特征都在测试集中,但这是不可能的(稀疏矩阵仅表示非零条目)

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

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

【问题讨论】:

    标签: python scipy scikit-learn xgboost countvectorizer


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • ..非常感谢您的想法。我尝试了一种方法。我将训练集特征列表保留在列表中,并使用训练集特征作为词汇构建了测试集矩阵。即_countvec = CountVectorizer(vocabulary=trainset_features)_, documenttermmatrix_test=countvec.fit_transform(testset['ProductDescription'])。我有 35216 个功能列表。我仍然在输入数据中得到 _ 错误预期 f35215 .....当我使用 print(documenttermmatrix_test.getcol(35215)) 看到该列的值时,没有任何值。是否错误是因为这个, 谁能给我打电话
    • 如果上面是 print(documenttermmatrix_test.getcol(35213)) 的情况,则没有任何价值。为什么它没有给出错误 expected f35213, f35215 in input data
    【解决方案2】:

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

    改变这一行:

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

    到这里:

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

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

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

    【讨论】:

    • 感谢您的建议。由于我在 documenttermmatrix_test 中使用 countvec = CountVectorizer(vocabulary=trainset_features) 行设置了 countvectorizer 的词汇来训练集合特征,因此我只有来自 trainset 的特征。但顺序不同。我认为不同的顺序是问题所在。虽然预测它的预期训练集和测试集功能似乎是相同的顺序......但是我不知道如何使它们以相同的顺序排列。
    • @RanjanaGirish 没关系。如果您正确使用 CountVectorizer,它将自动以相同的顺序返回它们。请解释vocabulary=trainset_features。你是怎么做的?另外,请在问题中添加此详细信息。你还没有提到它。
    • 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)terms=np.asarray(countvec.get_feature_names())[fs.get_support()]trainset_features=set(terms)。这就是我制作 trainset_features 的方式。
    • @RanjanaGirish 那么你又要声明countVec了吗?重新初始化?如果没有,则无需执行此操作。只需使用您训练数据的原始 countVec 即可。它的词汇表已经用训练数据特征设置好了。
    • 在为构造训练集矩阵而初始化的 countvectorizer 词汇表中,我将拥有训练集描述中的所有术语。稍后我将为此应用特征选择并获得重要的术语。我将只使用那些重要的术语(trainset_features)进行训练。所以我将再次用vocabulary=trainset_features 初始化计数向量器来构造测试集矩阵。如果我只考虑一个,那么训练和测试集中相同特征的索引会有所不同知道(countvectorizer 会导致 scipy 矩阵,该矩阵具有没有名称的特征的索引。我在做什么错了吗?
    【解决方案3】:

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

    【讨论】:

    • @RanjanaGirish 除了我的,请遵循这个答案。这似乎是您在预测时遇到的问题 (expected f35215 in input data)。还要确保在拟合期间使用 csc_matrix()。
    • @RanjanaGirish 这似乎是 XGBoost 无法正确处理稀疏矩阵的问题。 github.com/dmlc/xgboost/issues/1238
    猜你喜欢
    • 2021-07-09
    • 1970-01-01
    • 2021-02-24
    • 2019-12-25
    • 1970-01-01
    • 1970-01-01
    • 2017-07-25
    • 2016-06-02
    • 2022-08-11
    相关资源
    最近更新 更多