目录
1. 必看知识
贝叶斯分类的内容其实并不复杂,主要就是一个贝叶斯公式。相比它的扩展内容就比较多,主要是一些概率论的知识。
概率论大佬可以跳过,直接阅读第二节内容。
1.1. 参数估计
参数估计:根据样本统计量的数值对总体参数进行估计的过程。
根据参数估计的性质不同,可以分为两种类型:点估计和区间估计
1.1.1. 点估计
点估计:根据样本统计量某一具体数值直接推断未知的总体参数。
对总体参数进行点估计常用两种方法:矩估计和最大似然估计,机器学习中常用的点估计是最大似然估计。
举个例子:在大街上随机抽取100个人,计算出他们的平均年龄是25岁,如果直接用25去代表所有人的平均年龄,这种估计方法就是点估计
但是很明显,这种估计方式存在不足。从例子上来看,大街上随便抽一个人的年龄是25岁,是有很大误差的。从理论上来说,总体参数是一个常数值,而样本统计量是一个随机变量,用随机变量去估计常数值时,误差是不可避免的。
1.1.2. 区间估计
区间估计:根据样本统计量的抽样分布特征,估计总体参数的一个区间,并同时给出总体参数落在此区间的可能性大小。
还是上面那个例子:如果用区间估计去推断用户年龄,则会有如下结果:根据样本数据,估计用户的平均年龄在22~28之间,置信程度为95%
1.2. 似然与概率
似然与概率在语义上似乎是一对同义词,但是在统计学中却是两个不同的概念。对了,似然的英文是 likelihood
1.2.1. 概率
概率是在特征环境下某件事情发生的可能性,也就是结果没有产生之前,我们根据已知环境下的参数θ来预测某件事情发生的可能性。
别懵,我来举例子:
就拿抛硬币来说,抛之前我们并不确定应该是哪一面朝上,但是根据众所周知的硬币性质θ可以推测正面朝上的概率是50%(反面同)
注意,这个概率只有在抛硬币之前才有意义,抛完之后的结果是确定的(1或0)
1.2.2. 似然
似然却刚好与概率相反,是在已经确定的结果下推测产生这个结果的可能参数θ。注意,是已经确定了结果的前提下。
还是抛硬币的例子:
随机抛一枚硬币100次,结果出现60次数字朝上,那我们去判断这枚硬币的时候发现这并不是一枚标准的硬币,因为数字朝上的概率60%>人头朝上的概率40%。
我们运用出现的结果去判断事情本身的性质(参数),也就是似然。
1.2.3. 表示
如果用θ表示事物本身的性质(参数),x表示事件的结果,那么概率可以表示为 P(x|θ),理解成在θ的前提下,事件x发生的概率。
对应的似然可以表示为£(θ|x),理解成已知事件结果x,求参数为θ对应的概率
即:£是关于θ的函数,而P是关于x的函数,两者从不同的角度描述一件事情
1.3. 最大似然估计
最大似然估计:MLE(maximum likelihood estimates)
先回到概率和似然的定义,概率描述的是在一定条件下某个事件发生的可能性,概率越大说明这件事情越有可能发生。
可是似然是针对已经发生的事情,取最大的意义在哪?
还是上面抛硬币的例子:100次中60次数字朝上,40次人头朝上,这时它的似然函数是:
£
(
θ
)
=
θ
60
(
1
−
θ
)
40
£(\theta) = \theta^{60}(1-\theta)^{40}
£(θ)=θ60(1−θ)40
此时抛硬币(100次中60次数字朝上)这件事情已经发生,它的概率是1,但是它的似然函数并不能达到1,退而求其次我们取似然函数的最大值,让它尽量的达到我们此时抛硬币的的结果,这就是最大似然估计。
ok,没懂的多读几遍这个例子,这个很重要。
1.4.最大后验估计
最大后验估计:MAP(maximum a posteriori estimation)
为了保持连贯性,这部分我先写出来,你们在看的时候可以先跳过这小节去看正文,回过头来在看最大后验估计。
上面的MLE其实是求一组能够使似然函数最大的参数θ,但是如果这个参数有一个先验概率呢?
就像在抛硬币的例子中,从生活经验中来看,硬币一般都是均匀的,所以θ=0.5的概率最大,那么这个时候应该怎么去估计参数?
这个时候需要用到MAP,MAP的基础是贝叶斯公式:
P
(
θ
∣
x
)
=
P
(
θ
)
∗
P
(
x
∣
θ
)
P
(
x
)
P(\theta|x) = \frac {P(\theta)*P(x|\theta)} {P(x)}
P(θ∣x)=P(x)P(θ)∗P(x∣θ)
对于这个函数:P(x|θ)就是钱买你说到的似然函数,p(θ)是先验概率,是指在没有任何数据的情况下对θ的主观判断(硬币是均匀的,所以θ=0.5)
p(x)是一个全概率公式,通常在数据中是一个已知结果,所以一般只计算分子。
1.5. 注意
再次来看抛硬币的例子,如果抛一枚硬币10次,有10次数字朝上,求正面朝上的概率θ
利用极大似然估计可以得到θ = 10/10=1.0,当样本数据不足的时候,MLE会产生严重的偏差
2. 贝叶斯原理
贝叶斯原理的初衷是为了解决一个逆向概率的问题。你可能要问了,什么是逆向概率?
逆向概率你可能不懂,我们先看一下一个例子
emm,从年初开始,一共有20天是下雨天,20天里面小一有15天是在家吃饭,其中有9顿是在家打火锅,有5天是不在家吃饭,这5天有一天是去外面吃火锅。刚好今天下雨了,小一在家吃饭的概率是多少呢?
答:当然是15/20=75%
小一今天吃火锅的概率?
答:分两种,一种是在家吃 9 / 15 = 60 % 9/15=60\% 9/15=60%,一种是不在家吃 1 / 5 = 20 % 1/5=20\% 1/5=20%
上面的问题就是正向概率,你可能还听过一个词:先验概率,对,它两一回事
对了,还有一个是条件概率, P ( 吃 火 锅 ∣ 在 家 吃 ) P(吃火锅|在家吃) P(吃火锅∣在家吃)表示在家吃的时候吃火锅
相应的逆向概率就是从反向推理事物发生的概率,也叫后验概率
如果今天打火锅,那今天在家的概率你能算对吗?
先来一起理一下思路:
我们知道,在家吃饭的概率 P ( 在 家 吃 ) = 15 / 20 = 75 % P(在家吃) = 15/20=75\% P(在家吃)=15/20=75%
在家吃火锅的概率 P ( 在 家 吃 火 锅 ) = 9 / 15 = 60 % P(在家吃火锅) = 9/15=60\% P(在家吃火锅)=9/15=60%
另外还有,不在家吃饭的概率 P ( 不 在 家 吃 ) = 5 / 20 = 25 % P(不在家吃) = 5/20=25\% P(不在家吃)=5/20=25%
不在家吃火锅的概率 P ( 不 在 家 吃 火 锅 ) = 1 / 5 = 20 % P(不在家吃火锅) = 1/5 = 20\% P(不在家吃火锅)=1/5=20%
这里,有两点需要注意一下:
- 在家吃火锅≠在家的时候吃火锅
- 不在家吃火锅≠不在家的时候吃火锅
因为后者是一个联合概率,表示(不)在家的条件下吃火锅
所以后者可以这样表示:
P ( 在 家 的 时 候 吃 火 锅 ) = P ( 在 家 吃 ) ∗ P ( 吃 火 锅 ∣ 在 家 吃 ) P(在家的时候吃火锅)=P(在家吃)*P(吃火锅|在家吃) P(在家的时候吃火锅)=P(在家吃)∗P(吃火锅∣在家吃)
P ( 不 在 家 的 时 候 吃 火 锅 ) = P ( 不 在 家 吃 ) ∗ P ( 吃 火 锅 ∣ 不 在 家 吃 ) P(不在家的时候吃火锅)=P(不在家吃)*P(吃火锅|不在家吃) P(不在家的时候吃火锅)=P(不在家吃)∗P(吃火锅∣不在家吃)
那么我们可以算出来,下雨天吃火锅的概率:
P
(
吃
火
锅
)
=
P
(
在
家
吃
)
∗
P
(
吃
火
锅
∣
在
家
吃
)
+
P
(
不
在
家
吃
)
∗
P
(
吃
火
锅
∣
不
在
家
)
=
50
%
P(吃火锅) = P(在家吃)*P(吃火锅|在家吃) + P(不在家吃) *P(吃火锅|不在家) = 50\%
P(吃火锅)=P(在家吃)∗P(吃火锅∣在家吃)+P(不在家吃)∗P(吃火锅∣不在家)=50%
回到我们的问题,今天吃火锅的条件下,在家吃的概率是:
P
(
在
家
吃
∣
吃
火
锅
)
=
P
(
在
家
的
时
候
吃
火
锅
)
P
(
吃
火
锅
)
=
P
(
在
家
吃
)
∗
P
(
吃
火
锅
∣
在
家
吃
)
P
(
不
在
家
吃
)
∗
P
(
吃
火
锅
∣
不
在
家
吃
)
=
75
%
∗
60
%
75
%
∗
60
%
+
25
%
∗
20
%
=
90
%
P(在家吃|吃火锅) = \frac {P(在家的时候吃火锅)} {P(吃火锅)} = \frac {P(在家吃)*P(吃火锅|在家吃)} {P(不在家吃)*P(吃火锅|不在家吃)} = \frac {75\%*60\%} {75\%*60\%+25\%*20\%} = 90\%
P(在家吃∣吃火锅)=P(吃火锅)P(在家的时候吃火锅)=P(不在家吃)∗P(吃火锅∣不在家吃)P(在家吃)∗P(吃火锅∣在家吃)=75%∗60%+25%∗20%75%∗60%=90%
我们也可以反向验证一下:
吃火锅一共10次,在家吃9次,不在家吃1次,所以在家吃的概率是90%
如果上面的例子你已经看懂了,那么今天的核心点你就已经掌握了
我们直接另 吃火锅=B,在家吃= A 1 A_1 A1,不在家吃= A 2 A_2 A2,整理一下就是大名鼎鼎的贝叶斯公式:
P
(
A
1
∣
B
)
=
P
(
A
1
)
∗
P
(
B
∣
A
1
)
P
(
A
1
)
∗
P
(
B
∣
A
1
)
+
P
(
A
2
)
∗
P
(
B
∣
A
2
)
P(A_1|B) = \frac {P(A_1)*P(B|A_1)} {P(A_1)*P(B|A_1) + P(A_2)*P(B|A_2)}
P(A1∣B)=P(A1)∗P(B∣A1)+P(A2)∗P(B∣A2)P(A1)∗P(B∣A1)
因为吃火锅只有两种情况,在家吃和在不在家吃,刚好对应了分母中的两种情况。
于是贝叶斯公式经常这样写:
P
(
A
1
∣
B
)
=
P
(
A
1
)
∗
P
(
B
∣
A
1
)
P
(
B
)
P(A_1|B) = \frac {P(A_1)*P(B|A_1)} {P(B)}
P(A1∣B)=P(B)P(A1)∗P(B∣A1)
3. 朴素贝叶斯分类
你可能要问了,贝叶斯我知道了,那朴素贝叶斯?朴素在哪?
之所以称为朴素贝叶斯,是因为它假设每个输入变量是独立的
就比如高富帅三个特征之间互不影响,帅的不一定高,高的不一定富
于是,求一个人高富帅的概率 P ( A B C ) = P ( A ) ∗ P ( B ) ∗ P ( C ) P(ABC)=P(A)*P(B)*P(C) P(ABC)=P(A)∗P(B)∗P(C)
朴素贝叶斯我也懂了,那它能做什么呢?
能做的事情就很多,我们只需要用数据训练一个贝叶斯模型,其实也就是先验概率和条件概率,然后贝叶斯就可以预测出后验概率来。
就好比今天小一要不要吃火锅呢?在家吃还是去外面吃呢?
你别看现在我们是用来做预测,其实贝叶斯最适合解决分类问题
举几个例子你就知道了:
垃圾邮件你应该有了解过,贝叶斯通过前期的系列训练,可以将未来的邮件进行分类(正常or垃圾)
世界杯比赛球队的输赢预测,也是通过贝叶斯实现的
在实际分类过程中,贝叶斯分类主要包括两种:离散数据的分类和连续数据的分类
离散数据的分类
离散数据的分类根据…
别急别急,你先告诉我什么是离散数据?
离散数据是有明确边界的数据,就像身高的高中低,成绩的排名1234等,像1~100之间的任何数组组成的数据集就是连续数据。
离散数据的分类是根据贝叶斯定理实现,特别是朴素贝叶斯的应用
看个例子呗,如果说现在有一个人的特征是:身高中、体重中、鞋码大 ,这个人是男的还是女的?请你来分个类
ok,我们先确定一下属性:
A 1 A_1 A1=身高中, A 2 A_2 A2=体重中, A 3 A_3 A3=鞋码小, B 1 B_1 B1=男, B 2 B_2 B2=女
我们的目的是计算 P ( B 1 ∣ A 1 A 2 A 3 ) P(B_1|A_1A_2A_3) P(B1∣A1A2A3)和 P ( B 2 ∣ A 1 A 2 A 3 ) P(B_2|A_1A_2A_3) P(B2∣A1A2A3),对应概率大的就是结果了
前面已知贝叶斯公式:
P ( B 1 ∣ A 1 A 2 A 3 ) = P ( B 1 ) ∗ P ( A 1 A 2 A 3 ∣ B 1 ) P ( A 1 A 2 A 3 ) P(B_1|A_1A_2A_3) = \frac {P(B_1)*P(A_1A_2A_3|B_1)} {P(A_1A_2A_3)} P(B1∣A1A2A3)=P(A1A2A3)P(B1)∗P(A1A2A3∣B1)
分母都一样,那
P
(
B
2
∣
A
1
A
2
A
3
)
=
P
(
B
2
)
∗
P
(
A
1
A
2
A
3
∣
B
2
)
P
(
A
1
A
2
A
3
)
P(B_2|A_1A_2A_3) = \frac {P(B_2)*P(A_1A_2A_3|B_2)} {P(A_1A_2A_3)}
P(B2∣A1A2A3)=P(A1A2A3)P(B2)∗P(A1A2A3∣B2)
我们直接比较分子就行了
又根据朴素贝叶斯
P
(
A
1
A
2
A
3
∣
B
1
)
=
P
(
A
1
∣
B
1
)
∗
P
(
A
2
∣
B
1
)
∗
P
(
A
3
∣
B
1
)
P(A_1A_2A_3|B_1) = P(A_1|B_1) * P(A2|B_1) * P(A_3|B_1)
P(A1A2A3∣B1)=P(A1∣B1)∗P(A2∣B1)∗P(A3∣B1)
直接计算
P ( B 1 ) ∗ P ( A 1 A 2 A 3 ∣ B 1 ) = 1 2 ∗ 1 2 ∗ 1 2 ∗ 0 4 = 0 P(B_1)*P(A_1A_2A_3|B_1) = \frac{1}{2} * \frac{1}{2} * \frac{1}{2} * \frac{0}{4} = 0 P(B1)∗P(A1A2A3∣B1)=21∗21∗21∗40=0
P ( B 2 ) ∗ P ( A 1 A 2 A 3 ∣ B 2 ) = 1 2 ∗ 1 4 ∗ 1 2 ∗ 1 2 = 1 32 P(B_2)*P(A_1A_2A_3|B_2) = \frac{1}{2} * \frac{1}{4} * \frac{1}{2} * \frac{1}{2} = \frac{1}{32} P(B2)∗P(A1A2A3∣B2)=21∗41∗21∗21=321
第二个结果对应的是女孩子,那就是她了
连续数据的分类
连续型数据的进行分类一般有两种方法,先看数据集:
一种方法是我们将连续型数据转换为离散型
比如说体重特征我们设置几个范围T1(100-120),T2(120-140)…这样子连续型数据映射在相应范围,实现离散化
按照上面离散化的处理方式即可
另一种方式是我们假设身高、体重、鞋码都是正态分布,通过样本计算出均值和方差
还记得正态分布的密度函数吗,我们把点的值带进去,就能得到相应的概率值。
4. 实战
在sklearn 中提供的贝叶斯分类算法有三种,分别是:高斯朴素贝叶斯(GaussianNB)、多项式朴素贝叶斯(MultinomialNB)和伯努利朴素贝叶斯(BernoulliNB)
先来看一下这三种算法的区别:
高斯分布:
高斯分布又叫正态分布,我们把一个随机变量 X服从数学期望为μ,方差为σ^2 的数据分布称为正态分布,当μ=0,σ=1是称为标准 正态分布(对应红色的线)
伯努利分布:
又称零一分布,是多重伯努利实验的概率分布。
多项式分布:
是二项分布的推广,二项分布是随机结果只有两个取值,多项式分布式指随机结果有多个取值
多项式朴素贝叶斯和伯努利朴素贝叶斯常用在文本分类问题中,高斯朴素贝叶斯主要用于连续变量中,且假设连续变量是服从正态分布的。
有关文本分类
今天的实战项目是针对新闻数据进行分类,说更直白点,就是文本分类
在文本分类的过程中,有一个很重要的内容:如何将普通的文本转换为计算机可以识别的向量
这里用到一个叫做TF-IDF的方法,先解释一下这个内容
TF-IDF 是一个统计方法,用来评估某个词语对于一个文件集或文档库中的其中一份文件的重要程度。
TF-IDF 由Term Frequency(词频)和Inverse Document Frequency(逆向文档频率)组成。即TF-IDF=TF*IDF
词频TF:
计算一个单词在文档中出现的次数,单词的重要性和TF成正比
逆向文档概率IDF:
指一个单词在文档中的区分度。如果一个单词出现在的文档数越少,就越能通过这个单词把该文档和其他文档区分开。即IDF越大单词的区分度越大
分母+1是因为有些单词不会存在在文档中,为了避免分母为 0,统一给单词出现的文档数都加 1
所以,TF和IDF越高的单词越适合分类,也就是在一个文档中出现次数较多,同时又很少出现在其他文档中的单词,适合进行分类
4.1. 开始实战
先来说说这次实战项目的相关背景
目前我们有部分新浪新闻数据,其中包括财经、IT、健康等等新闻类别,每个类别有若干篇新闻报道
我们的任务是预测新闻的类别
为了方便进行分词,我们还有一个停用词表
什么是停用词呢?
停用词是指在分类中没有用的词,这类词一般出现的频率TF很高,但是并不能很好的区分不同的文章(IDF低),例如“你、我、他”、一些介词、连接词等
4.2. 读取数据
读取数据,将每一个新闻文本和其对应的新闻类别进行对应
为了方便下一步进行分词,这里直接将数据存储在字典中
最终结构化的数据是这样的
4.3. 数据分词
针对每个新闻,我们这里直接使用结巴进行分词
使用结巴分词,需要提前安装jieba 这个包,win下直接pip install 即可
分词后的数据集是这样的
一共88条新闻,好像看的不是很清楚,我们拎出来第一条新闻仔细看下是如何分词的
4.4. 计算每个单词的权重
在sklearn 中直接使用 TfidfVectorizer类可以用来计算词的TF-IDF值
在这里面,我们可以传入停用词表,并且设置参数max_df
max_df代表单词在所有文档中出现的概率,如果这个概率很大,就说明这个词的区分度很小,一般不会用来作分词统计
"""使用停用词"""
list_stop_words = df_stop_words['stop_words'].to_list()
tfidf_vec = TfidfVectorizer(stop_words=list_stop_words, max_df=0.5)
因为我们前面是对整个数据集进行操作,所在在这一步需要将数据集进行拆分,然后再计算词的TF-IDF值
# 切分数据集
X_train, X_test, y_train, y_test = train_test_split(data['cut_content'], data['label'], test_size=0.2)
# 计算权重
X_train_features = tfidf_vec.fit_transform(X_train)
X_test_features = tfidf_vec.transform(X_test)
4.5. 建立模型
在文章的开始说到了三种朴素贝叶斯的分类算法,针对新闻数据集,很明显是一个多分类问题,所有我们选用多项式朴素贝叶斯
多项式朴素贝叶斯假设特征的先验概率为多项式分布,即:
P ( X j = x j l ∣ Y = C k ) = x j l + λ m k + n λ P(X_j = x_{jl} | Y = C_k) = \frac{x_{jl}+\lambda}{m_k+n\lambda} P(Xj=xjl∣Y=Ck)=mk+nλxjl+λ
即第k 个类别的第j 维特征的第l 个取值条件概率。mk是训练集中输出为第k 类的样本个数。
λ为一个大于0的常数,当训练样本很大的时候,加1的概率变化可以忽略,也同时避免了零概率的问题
对了,三种算法,各自有其不同的参数
多项式朴素贝叶斯有一个参数需要特别注意:alpha
-
当 alpha=1 时,使用的是 Laplace 平滑
-
当 0<alpha<1 时,使用的是 Lidstone 平滑
对于 Lidstone 平滑来说,alpha 越小,迭代次数越多,精度越高
ok,那我们直接进行建模
"""建立模型并进行训练"""
# 使用多项式朴素贝叶斯进行预测
clf = MultinomialNB(alpha=0.001).fit(X_train_features, y_train)
predict_label = clf.predict(X_test_features)
# 计算准确率
print('准确率为:', accuracy_score(y_test, predict_label))
贝叶斯模型的方法和其他模型是一样的
最终的计算结果是这样的
总结一下
理解贝叶斯算法之前先了解贝叶斯定理,也就是后验概率的计算;在此基础上,通过了解朴素贝叶斯的特性,对离散和连续数据进行分类操作。
相比而言,朴素贝叶斯简单很多,算法应用也很简单
贝叶斯算法的优缺点
优点:
-
对待预测样本进行预测,过程简单速度快
-
对于多分类问题同样有效,复杂度也并不会有大程度提升
-
在分布独立这个假设的情况下,贝叶斯分类器效果奇好
-
对于类别类的输入特征变量,效果奇好;对于连续型变量特征,默认符合正态分布
缺点:
-
测试集中的一个类别变量,训练集中没出现过,则概率为0,预测就没用了。
可以使用平滑操作(拉普拉斯平滑) -
朴素贝叶斯独立分布的假设,实际生活中很难完全独立
-
朴素贝叶斯不存在bagging、boosting等模型融合的方法(因为没有variance可以减少)