用于文本分类任务的最佳scikit分类器

时间:2013-07-02 06:34:00

标签: python classification scikit-learn

我正在使用scikit对短语进行文本分类。一些例子是:

"Yes" - label.yes
"Yeah" - label.yes
...
"I don't know" - label.i_don't_know
"I am not sure" - label.i_don't_know
"I have no idea" - label.i_don't_know

使用TfidfVectorizer和MultinomialNB分类器,一切运行良好。

添加新文本/标签对时出现问题:

"I" - label.i

预测“I”的类仍会返回label.i_don't_know,即使文本正好在这样的训练数据中,这可能是因为unigram“I”  在label.i_don't_know中比在label.i中更常出现。

是否有一个分类器可以在此任务上提供相当或更好的性能,并保证正确返回训练数据元素的预测?

此代码进一步说明了问题:

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB

#instantiate classifier and vectorizer
clf=MultinomialNB(alpha=.01)
vectorizer =TfidfVectorizer(min_df=1,ngram_range=(1,2))

#Apply vectorizer to training data
traindata=['yes','yeah','i do not know','i am not sure','i have no idea','i'];
X_train=vectorizer.fit_transform(traindata)

#Label Ids
y_train=[0,0,1,1,1,2];

#Train classifier
clf.fit(X_train, y_train)

print clf.predict(vectorizer.transform(['i']))

代码输出标签1,但正确的分类是标签2.

1 个答案:

答案 0 :(得分:6)

问题不在于分类器,而在于矢量化器。 TfidfVectorizer有一个参数token_pattern : string,它是一个“正则表达式,表示什么构成”标记“,仅在tokenize =='word'时使用。默认正则表达式选择 2或更多的标记字母字符(标点符号被完全忽略,并始终被视为标记分隔符)。“ (重点补充)。标记器会抛出单词i,从而产生一个空文档。 Naive Bayes然后将其归类为类1,因为这是训练数据中最常见的类。

根据数据的不同,您可能需要考虑使用Naive Bayes的统一先验。


进一步暗示为什么事情可能无效:

您的管道设置方式可能还有其他奇怪之处。我发现检查每个阶段的输入和输出(标记化器,矢量化器,分类器等)很有用。投入一些时间编写单元测试可以为您节省大量时间。

一旦您满意一切正常,请尝试在测试数据上评估您的分类器。我怀疑你的课程之间有很多重叠,特别是label.i_don't_knowlabel.i。如果是这种情况,分类器将表现不佳。