哈哈哈,我又回来了,终于快到了喜大普奔的假期时间,让我们一起快乐的写博客吧。收,回正题。今天我们要来手撕一下Naive Bayes Classifier(朴素贝叶斯分类器)。为什么说手撕呢,是因为这次我们要自己实现Naive Bayes Classifier 除了对数据的处理以外,都不会使用任何外部库,来一次硬刚!
我们能否在医疗记录数据集上建立分类器模型,进而预测被研究对象是否患糖尿病?
长期以来,研究人员对 Pima Indians(此处暂译作皮马印第安人)都有极大的研究兴趣,因为他们是世界上糖尿病发病率最高的人群之一。记录皮马印第安人医疗数据及是否患有糖尿病的数据集 pima-indians-diabetes.csv 也成为了一个著名的数据集。
该数据集最初归National Institute of Diabetes and Digestive and Kidney Diseases所有,记录了怀孕次数、血压、BMI、年龄等信息。
在本次实验中,我们将在训练集上建立 Naive Bayes 分类器,并在测试集上评估模型的精度。
之前在ISL-Chap2剩余部分笔记的贝叶斯分类器部分大略提过一下贝叶斯分类器,但是由于那篇文章的重点在如何衡量模型好坏,所以主要描述了bayers error rate(衡量贝叶斯分类器的好坏)。这一次,我们来详细写一下贝叶斯分类器的原理。
首先,我们先回顾一下 Naive Bayes Classifier 的目的。既然是分类器,要做的就是根据一部分信息( X ⃗ \vec{X} X)预测其对应的 label ( Y Y Y)。拿我们这次的实际问题举例,就是把一个人的怀孕次数、血压、BMI、年龄等信息作为输入,扔进训练好的Naive Bayes Classifier 中,让它预测这个人有没有患糖尿病。
理解了分类器的目的以后,让我们换一个角度来思考这个问题。如果我们用概率的思维方式来思考这件事,其实也就变成了,我们要找到给定某个 X ⃗ \vec{X} X的情况下,label取哪个值的概率更高。拿这次的实际问题举例,假定我们现在有了一个人的怀孕次数、血压、BMI、年龄的数据,构成了向量 X ⃗ = ( 1 , 74 , 25.6 , 30 ) \vec{X}=(1, 74, 25.6, 30) X=(1,74,25.6,30), 我们想要知道她是患糖尿病的概率大还是不患糖尿病的概率大(Y=1还是Y=0的概率大)。
抽象一点,用数学公式表示,也就是找到使得 P ( Y ∣ X ⃗ ) P(Y|\vec{X}) P(Y∣X)最大的Y。
但是这里就出现问题了, P ( Y ∣ X ⃗ ) P(Y|\vec{X}) P(Y∣X)是多少鸭,我们不知道鸭。憋着急,现在就轮到贝叶斯定理闪亮登场了。
P ( A ∣ B ) = P ( A ) × P ( B ∣ A ) P ( B ) {\displaystyle P(A|B)={\frac {P(A)\times P(B|A)}{P(B)}}} P(A∣B)=P(B)P(A)×P(B∣A)
PS:不了解贝叶斯定理的盆友请手动翻到后面贝叶斯定理的部分哈。
把我们的 P ( Y ∣ X ⃗ ) P(Y|\vec{X}) P(Y∣X)带进去也就变成了
P ( Y ∣ X ⃗ ) = P ( Y ) × P ( X ⃗ ∣ Y ) P ( X ⃗ ) {\displaystyle P(Y|\vec{X})={\frac {P(Y)\times P(\vec{X}|Y)}{P(\vec{X})}}} P(Y∣X)=P(X)P(Y)×P(X∣Y)
我们现在的任务是找出给定 X ⃗ \vec{X} X的情况下哪个 Y Y Y的 P ( Y ∣ X ⃗ ) P(Y|\vec{X}) P(Y∣X)最大,但是 P ( X ⃗ ) P(\vec{X}) P(X)是一个常数,所以其实不需要比较。
那么我们的任务也就变成了:
找到使 P ( Y ) × P ( X ⃗ ∣ Y ) P(Y)\times P(\vec{X}|Y) P(Y)×P(X∣Y)最大,即使 ( ∏ i P ( x ( i ) ∣ y ) ) × P ( y ) (\prod_iP(x^{(i)} |y))\times P(y) (i∏P(x(i)∣y))×P(y)最大的 y y y。(我们假设其相互独立)
这里需要提示一下,在实际操作中我们如果真的把这么多小于1的 float 乘起来,由于精度的问题,很有可能就会得到 0。所以为了避免这种情况,我们对整个式子取 l o g log log。这样式子就变成了:
( ∑ i l o g p ( x ( i ) ∣ y ) ) + l o g p ( y ) (\sum_ilog p(x^{(i)}|y)) + logp(y) (i∑logp(x(i)∣y))+logp(y)
走到这里,我们就可以开始建模了。把式子拆开来看,我们需要给 l o g p ( y ) log p(y) logp(y)以及每个 l o g p ( x ( i ) ∣ y ) logp(x^{(i)}|y) logp(x(i)∣y)建模。
l o g p ( y ) log p(y) logp(y)比较好办,只要在 training set 里面数一下就好了(有多少人患糖尿病,有多少人未患糖尿病)
l o g p ( x ( i ) ∣ y ) logp(x^{(i)}|y) logp(x(i)∣y)会相对复杂一点,因为我们并不知道它的分布究竟是怎样的。但是我们其实可以不用太担心这个小模型的精度,因为我们的最终目的其实是把 y y y 分开。也就是说,只要取正确那一类的得分大于取其他类的得分就好。(本次实验中,我们对所有的 p ( x ( i ) ∣ y ) p(x^{(i)}|y) p(x(i)∣y) 使用Gaussian distribution,也就是正态分布)
f ( x ) = 1 σ 2 π   e − ( x − μ ) 2 2 σ 2 f(x) = {1 \over \sigma\sqrt{2\pi} }\,e^{- {{(x-\mu )^2 \over 2\sigma^2}}} f(x)=σ2π1e−2σ2(x−μ)2
P ( A ∣ B ) = P ( A ) × P ( B ∣ A ) P ( B ) {\displaystyle P(A|B)={\frac {P(A)\times P(B|A)}{P(B)}}} P(A∣B)=P(B)P(A)×P(B∣A)
其实它的推导并不麻烦,这里我们通过条件概率公式来推导
已知:
P ( A ∣ B ) = P ( A ∩ B ) P ( B ) {\displaystyle P(A|B)={\frac {P(A\cap B)}{P(B)}}} P(A∣B)=P(B)P(A∩B)
也就可以得出:
P ( A ∩ B ) = P ( A ) × P ( B ∣ A ) = P ( B ) × P ( A ∣ B ) {P(A\cap B) = P(A)\times P(B|A) = P(B)\times P(A|B)} P(A∩B)=P(A)×P(B∣A)=P(B)×P(A∣B)
接下来把 P ( B ) P(B) P(B)移一下项,就可以得到贝叶斯公式啦。
这里我会把思路捋一遍,就不贴代码了,如果有实在需要代码的盆友,请私信。
calculate p(y=1), p(y=0)
for i in [0,9]:
select 20% as test set, the rest as a training set
use training set calculate:
mu(i), sigma(i), y=1
mu(i), sigma(i), y=0
in test set calculate:
p(y=0|x), p(y=1|x)
compare p(y=0|x) and p(y=1|x), choose the higher one as prediction
compare real label(test set) and prediction(test set) to calculate accuracy
caculate average of accuracy
1.WHY ARE THE PIMA INDIANS SICK? STUDIES ON ARIZONA TRIBE SHOW EXCESSIVE RATES OF DIABETES, OBESITY AND KIDNEY DISEASE
https://www.washingtonpost.com/archive/lifestyle/wellness/1993/03/30/why-are-the-pima-indians-sick-studies-on-arizona-tribe-show-excessive-rates-of-diabetes-obesity-and-kidney-disease/1f978958-e73b-483a-9af9-47d9efdad534/?noredirect=on&utm_term=.435be284734b
2.pima-indians-diabetes.csv
https://www.kaggle.com/kumargh/pimaindiansdiabetescsv
3.ISL-Chap2剩余部分笔记(回归问题、分类问题,如何衡量模型的好坏)
https://blog.csdn.net/qq_31584013/article/details/85511593
4.条件概率
https://zh.wikipedia.org/wiki/条件概率