这是我的代码:
# 加载库import numpy as npfrom sklearn.naive_bayes import MultinomialNBfrom sklearn.feature_extraction.text import CountVectorizer# 创建文本text_data = np.array(['Tim is smart!', 'Joy is the best', 'Lisa is dumb', 'Fred is lazy', 'Lisa is lazy'])# 创建目标向量y = np.array([1,1,0,0,0])# 创建词袋count = CountVectorizer()bag_of_words = count.fit_transform(text_data) # # 创建特征矩阵X = bag_of_words.toarray()mnb = MultinomialNB(alpha = 1, fit_prior = True, class_prior = None)mnb.fit(X,y)print(count.get_feature_names())# 输出:['best', 'dumb', 'fred', 'is', 'joy', 'lazy', 'lisa', 'smart', 'the', 'tim']print(mnb.feature_log_prob_) # 输出 [[-2.94443898 -2.2512918 -2.2512918 -1.55814462 -2.94443898 -1.84582669 -1.84582669 -2.94443898 -2.94443898 -2.94443898] [-2.14006616 -2.83321334 -2.83321334 -1.73460106 -2.14006616 -2.83321334 -2.83321334 -2.14006616 -2.14006616 -2.14006616]]
我的问题是:
假设对于单词 “best”,类别 1 的概率是 class 1 : -2.14006616
。
计算这个分数的公式是什么?
我使用 LOG (P(best|y=class=1)) -> Log(1/2)
-> 得不到 -2.14006616
回答:
从文档中我们可以推断出 feature_log_prob_
对应于给定类别的特征的经验对数概率。让我们以特征 “best” 为例进行说明,对于类别 1
这个特征的 log
概率是 -2.14006616
(如你所指出的),如果我们将其转换为实际的概率分数,将会是 np.exp(1)**-2.14006616 = 0.11764
。再进一步了解 “best” 在类别 1
中的概率是如何以及为何是 0.11764
。根据多项式朴素贝叶斯的文档,我们看到这些概率是使用下面的公式计算的:
其中,分子大致对应于特征 “best” 在训练集中类别 1
中出现的次数(这是我们在这个例子中关注的),分母对应于类别 1
中所有特征的总数。我们还添加了一个小的平滑值 alpha
,以防止概率变为零,n
对应于特征的总数,即词汇表的大小。计算这些数字,对于我们这个例子有,
N_yi = 1 # "best" 在类别 `1` 中只出现一次N_y = 7 # 类别 `1` 中共有 7 个特征(所有词的计数)alpha = 1 # sklearn 的默认值n = 10 # 词汇表的大小所需概率 = (1+1)/(7+1*10) = 0.11764
你可以以类似的方式为任何给定的特征和类别进行计算。