多类文本分类期间 xgboost sklearn 中的 feature_names 不匹配

Posted

技术标签:

【中文标题】多类文本分类期间 xgboost sklearn 中的 feature_names 不匹配【英文标题】:Mismatch in feature_names in xgboost sklearn during multi-class text classification 【发布时间】:2016-12-25 23:39:31 【问题描述】:

我正在尝试在 python(sklearn 版)中使用 xgboost 执行多类文本分类,但有时它会出错,告诉我特征名称不匹配。奇怪的是,有时它确实有效(也许 4 次中有 1 次),但不确定性让我现在很难依赖这个解决方案,即使它显示了令人鼓舞的结果,甚至没有做任何真正的预处理。

我在代码中提供了一些说明性的示例数据,这些数据与我将使用的类似。我目前拥有的代码如下:

反映 maxymoo 建议的更新代码

import xgboost as xgb
import numpy as np
from sklearn.cross_validation import KFold, train_test_split
from sklearn.metrics import accuracy_score
from sklearn.feature_extraction.text import CountVectorizer

rng = np.random.RandomState(31337)    

y = np.array([0, 1, 2, 1, 0, 3, 1, 2, 3, 0])
X = np.array(['milk honey bear bear honey tigger',
          'tom jerry cartoon mouse cat cat WB',
          'peppa pig mommy daddy george peppa pig pig',
          'cartoon jerry tom silly',
          'bear honey hundred year woods',
          'ben holly elves fairies gaston fairy fairies castle king',
          'tom and jerry mouse WB',
          'peppa pig daddy pig rebecca rabit',
          'elves ben holly little kingdom king big people',
          'pot pot pot pot jar winnie pooh disney tigger bear'])

xgb_model = make_pipeline(CountVectorizer(), xgb.XGBClassifier())

kf = KFold(y.shape[0], n_folds=2, shuffle=True, random_state=rng)
for train_index, test_index in kf:
    xgb_model.fit(X[train_index],y[train_index])
    predictions = xgb_model.predict(X[test_index])
    actuals = y[test_index]
    accuracy = accuracy_score(actuals, predictions)
    print accuracy

我容易得到的错误如下:

Traceback (most recent call last):
  File "main.py", line 95, in <module>
    predictions = xgb_model.predict(X[test_index])
  File "//anaconda/lib/python2.7/site-packages/xgboost-0.6-py2.7.egg/xgboost/sklearn.py", line 465, in predict
    ntree_limit=ntree_limit)
  File "//anaconda/lib/python2.7/site-packages/xgboost-0.6-py2.7.egg/xgboost/core.py", line 939, in predict
    self._validate_features(data)
  File "//anaconda/lib/python2.7/site-packages/xgboost-0.6-py2.7.egg/xgboost/core.py", line 1179, in _validate_features
    data.feature_names))
ValueError: feature_names mismatch: ['f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12', 'f13', 'f14', 'f15', 'f16', 'f17', 'f18', 'f19', 'f20', 'f21', 'f22', 'f23', 'f24', 'f25', 'f26'] ['f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12', 'f13', 'f14', 'f15', 'f16', 'f17', 'f18', 'f19', 'f20', 'f21', 'f22', 'f23', 'f24']
expected f26, f25 in input data

任何指针将不胜感激!

【问题讨论】:

只是猜测,但您的训练数据中的某些行是否缺少 f338? 我在这里对完全相同的问题的回答***.com/questions/38740885/… 【参考方案1】:

您需要确保仅使用已训练过的特征对模型进行评分。执行此操作的常用方法是使用Pipeline 将矢量化器和模型打包在一起。这样它们将同时被训练,如果在测试数据中遇到新特征,向量化器将忽略它(还要注意你不需要在交叉的每个阶段重新创建模型-验证,您只需初始化一次,然后在每次折叠时重新调整它):

from sklearn.pipeline import make_pipeline    

xgb_model = make_pipeline(CountVectoriser(), xgb.XGBClassifier())
for train_index, test_index in kf:
    xgb_model.fit(X[train_index],y[train_index])
    predictions = xgb_model.predict(X[test_index])
    actuals = y[test_index]
    accuracy = accuracy_score(actuals, predictions)
    print accuracy

【讨论】:

这似乎合乎逻辑,我寄予厚望它会起作用,但由于某种原因它没有。我在现有问题中添加了一个工作示例来显示该问题。 可能是 CountVectoriser() 返回一个稀疏矩阵,而 XGBClassifier() 需要一个密集矩阵吗?然而,将其更改为密集的似乎会占用我的内存足迹...... 您的代码不会对我抛出错误...也许更新到最新版本的 sklearn?我在 Python 3.4,scikit 0.17.1

以上是关于多类文本分类期间 xgboost sklearn 中的 feature_names 不匹配的主要内容,如果未能解决你的问题,请参考以下文章

XGBoost 中多类分类的损失函数是啥?

用于文本分类的 SkLearn 模型

sklearn.metrics.roc_curve 用于多类分类

用于多类分类的 sklearn 指标

使用 sklearn 中的 OneVsRestClassifier 将自定义的二元分类调整为多类分类

在sklearn python中处理逻辑回归分类器中的极端不平衡多类