处理sklearn MultinomialNB中的负值

19 投票
4 回答
39624 浏览
提问于 2025-04-18 09:27

我在使用sklearn里的MultinomialNB之前,先对我的文本输入进行了标准化处理,像这样:

vectorizer = TfidfVectorizer(max_df=0.5, stop_words='english', use_idf=True)
lsa = TruncatedSVD(n_components=100)
mnb = MultinomialNB(alpha=0.01)

train_text = vectorizer.fit_transform(raw_text_train)
train_text = lsa.fit_transform(train_text)
train_text = Normalizer(copy=False).fit_transform(train_text)

mnb.fit(train_text, train_labels)

不过,MultinomialNB不接受在LSA阶段生成的非负值。有没有什么办法可以解决这个问题呢?

4 个回答

0

试着创建一个流程,把“归一化”作为第一步,然后把“模型拟合”作为第二步。

from sklearn.preprocessing import MinMaxScaler
p = Pipeline([('Normalizing',MinMaxScaler()),('MultinomialNB',MultinomialNB())])
p.fit(X_train,y_train) 
0

我在NB上也遇到了同样的问题,确实使用sklearn.preprocessing.MinMaxScaler()这个方法,正如gobrewers14所建议的那样,是有效的。不过,这个方法实际上让我用决策树、随机森林和KNN模型的表现准确率下降了0.2%,而这些模型都是用同样标准化的数据集训练的。

0

试着在 fit() 里面做这个

train_text.np.todense() 
8

我建议你不要把朴素贝叶斯和SVD或其他矩阵分解方法一起使用,因为朴素贝叶斯是基于贝叶斯定理的,它假设特征之间是相互独立的,这种假设有点过于简单了。可以考虑使用其他分类器,比如随机森林。

我做过这个实验,结果如下:

vectorizer = TfidfVectorizer(max_df=0.5, stop_words='english', use_idf=True)
lsa = NMF(n_components=100)
mnb = MultinomialNB(alpha=0.01)

train_text = vectorizer.fit_transform(raw_text_train)
train_text = lsa.fit_transform(train_text)
train_text = Normalizer(copy=False).fit_transform(train_text)

mnb.fit(train_text, train_labels)

这是同样的情况,不过我用的是NMP(非负矩阵分解)代替SVD,结果准确率只有0.04%。

当我把分类器从MultinomialNB换成随机森林时,准确率达到了79%。

所以,要么换个分类器,要么就不要用矩阵分解。

撰写回答