联合概率:包含多个条件,且所有条件同时成立的概率
记作:P(A,B)
条件概率:就是事件A在另外一个事件B已经发生条件下的发生概率
记作:P(A|B)
贝叶斯定理:
贝叶斯公式的理解:
百度百科吸毒者检测例子:
贝叶斯定理在检测吸毒者时很有用。假设一个常规的检测结果的敏感度与可靠度均为99%,也就是说,当被检者吸毒时,每次检测呈阳性(+)的概率为99%。而被检者不吸毒时,每次检测呈阴性(-)的概率为99%。从检测结果的概率来看,检测结果是比较准确的,但是贝叶斯定理却可以揭示一个潜在的问题。假设某公司将对其全体雇员进行一次鸦片吸食情况的检测,已知0.5%的雇员吸毒。我们想知道,每位医学检测呈阳性的雇员吸毒的概率有多高?令“D”为雇员吸毒事件,“N”为雇员不吸毒事件,“+”为检测呈阳性事件。
对于上述例子,
P(D):雇员吸毒的概率,0.5%
P(N):雇员不吸毒概率,1-P(D)=99.5%
P(+|D):吸毒的雇员检测为阳性(确认吸毒)的概率,99%
P(+|N):不吸毒的雇员检测为阳性(误认为吸毒)的概率,1%
P(+):雇员检测出阳性的概率,不考虑其他因素。P(+)为吸毒的雇员检测为阳性(确认吸毒)的概率(0.5% x 99% = 0.00495)+ 不吸毒的雇员检测为阳性(误认为吸毒)的概率(99.5% x 1% = 0.00995) = 0.0149,数学公式如下:
P(D|+):被检测为阳性的雇员确实吸毒的概率
在计算这个概率前,我们知道雇员吸毒且被检测为阳性的概率为:P(+,D)=P(D)P(+|D)=0.495%
同时:雇员吸毒且被检测为阳性的概率=雇员检测出阳性的概率×被检测为阳性的雇员确实吸毒的概率,即:
P(+,D)=P(+)P(D|+)=0.495% →P(D|+)=0.495/0.0149=33.22%
可以发现尽管检测可靠性达到了99%,但这样的检测结果让人堪忧,其中有的人都被错误的判断为吸毒了。
这时如果我们让被检测为阳性的雇员再次检测,此次检测我们将使用第一次检测为阳性的雇员,那么之前的P(D)要改为刚计算出的33.22%,
P(+,D)=P(D)P(+|D)=0.328878
P(D|+) = P(+,D)/P(+) = 98.01%
此时可靠性高多了,如果让此人再次复检,再重复使用贝叶斯定理计算,会得到此人吸毒的概率为99.98%(99.9794951%)已经超过了检测的可靠度。
在这个例子的情况下,计算条件概率(雇员在检测为阳性事件发生的前提下雇员吸毒事件的概率)的公式为:
即贝叶斯公式。
朴素贝叶斯
上面我们介绍了贝叶斯公式,接下来我们讨论何为朴素贝叶斯。
现在我们来关注另一个流传于网络的案例(判断女神对你的喜欢情况):
上表为7个男性的职业、体型、是否被女神喜欢的样本。
根据上表中的信息,小明体型超重的产品经理,他现在比较关注自己是否被女神喜欢。即P(喜欢|产品,超重)=?
∵贝叶斯公式
∴
对于上述7个样本中,我们发现由于样本数量太小,并不存在即使产品又超重的样本,即P(产品,超重)=0、P(产品,超重|喜欢)=0,这导致了无法计算结果。但是在现实生活中这样的人肯定存在,这两个概率都不可能为0。
这时侯小明又想知道被女神喜欢的概率,又不想去收集更多的样本。通常这种又要马儿跑又要马儿不吃草的做法是不对的,但是朴素贝叶斯可以帮助小明解决这个问题。
朴素贝叶斯,简单理解,就是假定了特征与特征之间相互独立的贝叶斯公式。
也就是说,朴素贝叶斯,之所以朴素,就在于假定了特征与特征相互独立。
因此按照朴素贝叶斯的方式,我们认为体型与职业这两个特征之间相互独立
P(产品, 超重) = P(产品) * P(超重) =2/7*3/7=6/49
P(产品, 超重|喜欢) = P(产品|喜欢) * P(超重|喜欢) =1/2*1/4=1/8
P(喜欢|产品, 超重) = P(产品, 超重|喜欢)P(喜欢)/P(产品, 超重) =7/12
基于7个样本的信息,我们就可以告诉小明,你被女神喜欢的概率为58.33%。
朴素贝叶斯 的新闻分类
读入sklearn的20newsgroups数据,这里已经下载好了,使用data_home指定数据路径:
train_data = fetch_20newsgroups(subset='train',data_home='jupyter_data')
test_data = fetch_20newsgroups(subset='test',data_home='jupyter_data')
特征处理,将文本转为TF-IDF向量,文档中的每个单词出现的次数在文档的总字数的比例:
vectorizer = TfidfVectorizer()
vectors_train = vectorizer.fit_transform( train_data.data) vectors_test=vectorizer.transform( test_data.data)
训练模型,平滑参数设置0.1:
model=MultinomialNB(alpha=0.1) model.fit( vectors_train,newsgroups_train.target)
预测和评估:
pred= model.predict(vectors_test) print(f1_score(newsgroups_test.target,pred,average='macro')) print(accuracy_score(newsgroups_test.target,pred))
结果:
0.81388938732554 0.8263409453000531