2

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

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)
4

2 回答 2

5

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

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

于 2015-04-14T20:03:13.743 回答
0

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

因此,不是针对“评论”调用 CountVectorizer 和 tfidfTransformer,您必须将 comments 和 comments_new 加入一个列表,并针对加入的列表调用 CountVectorizer 和 tfidfTransformer。

于 2015-04-14T19:06:58.467 回答