提问者:小点点

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


我正在使用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

使用TFIDFvectorier和多项式NB分类器,一切都运行得很好。

当我添加一个新的文本/标签对时,问题发生了:

"I" - label.i

预测类的“I”仍然返回标签。我不知道,即使文本正好在这样的训练数据中,这可能是因为单字“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个答案

匿名用户

问题不在于分类器,而在于向量器。TfidfVectorzer有一个参数token_pattern: string,这是一个表示什么构成令牌的正则表达式,仅在令牌化=='word'时使用。默认的regexp选择2个或更多字母字符的令牌(标点符号完全被忽略,并始终被视为令牌分隔符)。"(着重部分增加)。标记器抛出单词i,导致空文档。朴素贝叶斯然后将其分类为类1,因为这是训练数据中最频繁的类。

根据数据,您可能需要考虑使用朴素先验的朴素贝叶斯。

关于为什么事情可能不起作用的进一步提示:

您的管道设置方式可能还有其他一些奇怪之处。我发现检查每个阶段(标记器、向量器、分类器等)的输入和输出非常有用。从长远来看,花一些时间编写单元测试将为您节省大量时间。

一旦你对一切工作正常感到满意,试着在测试数据上评估你的分类器。我怀疑类之间有相当大的重叠,特别是标签。i_don't_know标签。i。如果是这种情况,分类器将表现不佳。