在xgboost python中预测测试数据时出错

在xgboost python中预测测试数据时出错,python,scipy,scikit-learn,xgboost,countvectorizer,Python,Scipy,Scikit Learn,Xgboost,Countvectorizer,我正在使用xgboost python执行文本分类 下面是我正在考虑的列车组 itemid description category 11802974 SPRO VUH3C1 DIFFUSER VUH1 TRIPLE Space heaters Architectural Diffusers 10688548 ANTIQUE BRONZE FINISH PUSHBUTTON

我正在使用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的Convectorizer构建描述的文档术语矩阵,它使用下面的代码生成scipy矩阵(因为我有110万的海量数据,我正在使用稀疏表示来降低空间复杂性)

countvec = CountVectorizer()
documenttermmatrix=countvec.fit_transform(trainset['description'])
 documenttermmatrix_test=countvec.fit_transform(testset['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
我正在为测试集构建单独的矩阵,正如我使用下面的代码为火车集所做的那样

countvec = CountVectorizer()
documenttermmatrix=countvec.fit_transform(trainset['description'])
 documenttermmatrix_test=countvec.fit_transform(testset['description'])
虽然预先设定测试集Xgboost期望列车集的所有功能都在测试集中,但这是不可能的(稀疏矩阵仅表示非零条目)

我不能将列车和测试集合并到单个数据集中,因为我只需要对列车集进行特征选择


有人能告诉我如何进一步解决这个问题吗?

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

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

  • 看看您是如何对数据进行分区的。可能只有一个或两个因素存在不平衡分割,在这种情况下,您可以通过使用scikit learn的
    train_test_split()
    获得更平等的表示

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


  • 但总体而言,这是一个不健康数据集的迹象。我还建议您考虑其他方法,将数据放入垃圾箱或分类到较少的组中,这样就不会出现问题

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

    更改此行:

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

    documenttermmatrix_test=countvec.transform(testset['description'])
    
    这将确保训练集中存在的那些功能仅取自测试集,如果不可用,则将0放在测试集中


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

    您必须在列车组上使用
    fit\u transform
    ,但只能在测试组上使用transform。因此,
    countvectorizer
    的默认输出是csr矩阵。它不适用于
    XGBClissifier
    ,您必须将其转换为csc矩阵。简单地做:
    X=csc\u矩阵(X)

    。非常感谢您的想法。我试过一种方法。我将列车组特征列表保存在列表中,并以列车组特征为词汇构建测试集矩阵。i、 e_ucountvec=CountVectorizer(词汇表=trainset\u功能)\uu,documenttermmatrix\u test=countvec.fit\u transform(testset['ProductDescription'])。我有35216个功能的列表。但我还是得到了输入数据中预期为f35215的错误…。当我使用print(documenttermmatrix_test.getcol(35215))看到该列的值时,没有任何值。无论错误是否是因为这个原因,是否有人可以打电话给meIf,如果上面的print(documenttermmatrix_test.getcol(35213))没有值。为什么它没有给出输入数据中预期的错误f35213、f35215谢谢您的建议。由于我已使用documenttermmatrix_测试中的line countvec=countvectorizer(词汇=trainset_功能)将countvectorizer的词汇表设置为训练集功能,因此我仅拥有来自trainset的功能。但顺序不同。我认为不同的顺序是问题所在。虽然预测列车集和测试集功能的顺序是相同的,但似乎……但我不知道如何使它们保持相同的顺序。@RanjanaGirish,这无关紧要。如果正确使用CountVectorizer,它将自动以相同的顺序返回它们。请解释
    词汇=trainset\u功能。你是怎么做到的?此外,请在问题中添加此详细信息。您还没有提到它。
    countvec=CountVectorizer()
    documenttermmatrix=countvec.fit\u transform(列车组['description'])
    fs=feature\u selection.SelectPercentile(feature\u selection.chi2,percentile=40)
    documenttermmatrix\u train=fs.fit\u transform(documenttermmatrix,y1列车)
    terms=np.asarray(countvec.get\u feature\u names())[fs.get\u support()]
    trainset\u features=set(terms)
    。这就是我制作列车组功能的方法。@RanjanaGirish那么你又在声明
    countVec
    ?再次初始化它?如果没有,那么就没有必要这样做。只需使用训练数据的原始countVec。其词汇表已经设置了训练数据特征。在为构造训练集矩阵而初始化的计数向量器词汇表中,我将拥有训练集描述中的所有术语。稍后,我将为此应用功能选择并获取重要术语。我将仅使用这些重要术语(列车组功能)进行培训。因此,我将再次使用
    词汇=trainset\u功能初始化计数向量器来构造测试集矩阵。如果我只考虑一个,则在列车和测试集中相同特征的索引将有所不同(知道)(CoovivCurrisher结果是具有特征索引的SISPY矩阵)。