用一些不在训练集中的词预测分类(朴素贝叶斯)

Predicting Classifications with some Words not in the training set (Naive Bayes)

我创建了一个朴素贝叶斯模型来预测结果是 'negative' 还是 'positive'。我遇到的问题是 运行 一组新数据的模型,其中一些词不在模型中。我收到的预测新数据集的错误是:

ValueError:预期输入具有 6 个特征,却得到了 4 个

我读到我必须在我的模型中放置拉普拉斯平滑器并且 Bernoulli() 已经有一个默认的 alpha 1。我还能做些什么来修复我的错误?谢谢

from nltk.corpus import stopwords
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.naive_bayes import BernoulliNB
from sklearn import cross_validation
from sklearn.metrics import classification_report
import numpy as np
from sklearn.metrics import accuracy_score
import textblob as TextBlob



#scikit
comments = list(['happy','sad','this is negative','this is positive', 'i like this', 'why do i hate this'])
classes = list(['positive','negative','negative','positive','positive','negative'])


# preprocess creates the term frequency matrix for the review data set
stop = stopwords.words('english')
count_vectorizer = CountVectorizer(analyzer =u'word',stop_words = stop, ngram_range=(1, 3))
comments = count_vectorizer.fit_transform(comments)
tfidf_comments = TfidfTransformer(use_idf=True).fit_transform(comments)


# preparing data for split validation. 60% training, 40% test
data_train,data_test,target_train,target_test = cross_validation.train_test_split(tfidf_comments,classes,test_size=0.2,random_state=43)
classifier = BernoulliNB().fit(data_train,target_train)

#new data
comments_new = list(['positive','zebra','george','nothing'])
comments_new = count_vectorizer.fit_transform(comments_new)
tfidf_comments_new = TfidfTransformer(use_idf=True).fit_transform(comments_new)

classifier.predict(tfidf_comments_new)

您正在从 'comments' 个单词创建计数矩阵。在创建计数矩阵时,您 必须 使用您将在 problem.Imagine 中遇到的所有可能的词,创建成员矩阵时更简单的情况。每列表示特定单词,每行表示数据集中的特定示例(例如,电子邮件文本)。如果特定单词不在示例中,则矩阵为 0,如果在示例中,则为 1。显然,如果您为包含 100 个不同单词的电子邮件构建了这样的矩阵,则该矩阵将有 100 列。但是,如果在那之后你将尝试对新数据使用经过训练的分类器,其中你将有一些不在训练集中的新词 - 它只会失败。由于原始矩阵中没有列来保存这些新词的值。因此,再次说明,在文本矢量化过程中,您必须提供您将在训练和测试数据集中遇到的所有术语。

因此,不是针对 'comments' 调用 CountVectorizer 和 tfidfTransformer,而是必须将评论和 comments_new 加入一个列表,然后针对加入的列表调用 CountVectorizer 和 tfidfTransformer。

您不应使用 fit_transform 在新数据上拟合新的估计器,而应使用先前构建的 count_vectorizer,仅使用 transform。这将忽略所有不在字典中的单词。

我不同意 Maxim:虽然这对 CountVectorizer 没有影响,但在连接的数据集上使用 TfidfTransformer 会将信息从测试集泄漏到训练集,您需要避免这种情况。