机器学习笔记6:朴素贝叶斯

朴素贝叶斯简介

朴素贝叶斯(Naive Bayes)是一种基于概率统计的分类方法,其分类依据是计算给定样本属于某一类别的概率,概率最大的类别即该样本的类别。朴素贝叶斯的朴素(Naive)之处在于算法认为所有特征值的概率都相互独立的,这是算法的前提,因此这是一种相对简单的模型。

学习贝叶斯之前,我们需要对概率论中的条件概率有一些认识,不熟悉的同学可以先学习相关资料。假设我们有一个点$p_x​$,其属于$c_i​$的概率为$P(c_i \vert p_x)​$,如果有。

$$
\large
P(c_i \vert p_x) \gt P(c_j \vert p_x)
$$

该$p_x$属于$c_i$,否则$p_x$属于$c_j$。

使$D$表示一个元组(tuple)的训练集,并与分类标签(class labels)相关,一般来说,每个元组用一个$n$维属性向量表示,$X=(x_1,x_2,\cdots,x_n)$,$n$个属性描述了元组的$n$个度量,表述为$A_1,A_2,\cdots,A_n$。

假定有$m$个类型,$C_1,C_2,\cdots,C_m$。给定一个元组$X$,分类器会将$X$划分为后验概率最高的所属类别。也就是说,朴素贝叶斯分类器预测$X$属于类型$C_i$当前仅当。

$$
\large
P(C_i \vert X) \gt P(C_j \vert X) \enspace\enspace for \enspace 1 \le j \le m,j \ne i .
$$

这样,我们最大化$P(C_i \vert X)$。式中最大化的$C_i$被称为最大后验假设(maximum posteriori hypothesis)。由贝叶斯定理可知。

$$
\large
P(C_i \vert X) = \frac {P(X \vert C_i)P(C_i)} {P(X)}
$$

由于$P(X)$对于所有分类都是定值,只有$P(X \vert C_i)P(C_i)$需要最大化。如果类型先验概率未知,则一般假定分类相等,即$P(C_1)=P(C_2)= \cdots =P(C_m)$,然后我们最大化$P(X \vert C_i)$。其他情况下,最大化$P(X \vert C_i)P(C_i)$。

注意分类先验概率可以估算为$\frac{\vert C_{i,D} \vert}{\vert D \vert}$。

其中$\vert C_{i,D} \vert$是$D$中类型$C_i$的一些训练元组。

前面提到,朴素贝叶斯的朴素(Naive)之处在于算法认为所有特征值的概率都相互独立的。因此对于$P(X \vert C_i)$,可以作如下展开。

$$
\large
\prod_{k=1}^n P(x_k \vert C_i) = P(x_1|C_i) \times P(x_2|C_i) \times \cdots \times P(x_n|C_i)
$$

变换后,再求$P(X \vert C_i)P(C_i)$的最大化就直观了。

Python实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# -*- coding: utf-8 -*-
"""
Naive Bayes Classifier
by Charles Ouyang
2016.06.22
"""
def bayes_classifier(data_set, categories, vec):
"""
bayes classifier
:param data_set: training data set
:param categories:
:param vec:
:return: category
"""
result_p = 0
result_c = None
category_sum_count = 0
for category in categories:
category_sum_count += categories[category]
for category in categories:
cur_p = 1
cur_p *= float(categories[category]) / category_sum_count
for feature in vec:
if data_set[feature] is None:
continue
cur_p *= float(data_set[feature][category]) / categories[category]
if result_p < cur_p:
result_p = cur_p
result_c = category
return result_c
if __name__ == '__main__':
test_data = {}
test_data.setdefault('data_set', {
'python': {'bad': 0, 'good': 6},
'the': {'bad': 2, 'good': 3},
'money': {'bad': 3, 'good': 4}
})
test_data.setdefault('categories', {'bad': 5, 'good': 13})
print(bayes_classifier(test_data['data_set'], test_data['categories'], ['the']))

朴素贝叶斯的优劣

优点:在数据较少的情况下仍然有效,可以处理多类别问题。
缺点:对于输入数据的准备方式较为敏感。
使用数据类型:标称型数据。

参考

  1. 机器学习实战 - Peter Harrington - 亚马逊中国
  2. Data Mining - 韩家炜 - 亚马逊中国