带有拉普拉斯平滑的Naive Bayes python代码实现
今天,数据分析课讲到了朴素贝叶斯算法,想起以前用MATLAB写过一次,但是时间过得太久,代码早就不知道哪去了,正好最近本人在专攻python,也是为了提升一下python能力,所以一时兴起,在下课之后,以朴素贝叶斯的基本思路,对照着老师课后留的作业题目,自己用python码了码,因为本文只是一个学习笔记作用,也无关于什么算法讲解,再加上时间有限(作业巨多呀),下面就简单说明这个算法中的思路关键点和python实现代码。
首先针对朴素贝叶斯的作用需要明确一下:分类,比如我们可以把它用到文本分类、垃圾文本过滤、情感预测、推荐系统等领域,那么首先,我们在我们依据贝叶斯原理进行分类时,最应该清楚的就是贝叶斯原理:
其次呢,要了解到几个关键点是:
-
独立性、条件独立性概念;
-
独立≠不相关,一定要明确区分二者,不相关,代表着两个变量之间的正负变化关系;
-
拉普拉斯平滑,这个平滑处理主要要解决的是:零概率问题的出现
(上次错误的发生也是由于这个导致的,千万注意,分量x的拉普拉斯平滑操作,会导致样本量的变化,从而也就导致了最终右边的分类的先验概率发生变化,所以需要对y进行拉普拉斯平滑操作,我们这么理解,y难道就不会出现零概率的情况了吗?这么想,相信你会很容易理解的)那么接下来我将以这道例题来进行python代码的演示:
例题:由下表训练集学习一个朴素贝叶斯分类器,并确定x=(2, Small)的类别y。表中X1,X2为特征,取值的集合分别为X1={1, 2, 3},X2={Small, Medium, Large},Y为类标记,Y={1, -1}。
表:训练集
ID | X1 | X2 | Y | ID | X1 | X2 | Y |
---|---|---|---|---|---|---|---|
1 | 1 | Small | -1 | 8 | 2 | Medium | 1 |
2 | 1 | Medium | -1 | 9 | 2 | Large | 1 |
3 | 1 | Medium | 1 | 10 | 2 | Large | 1 |
4 | 1 | Small | 1 | 11 | 3 | Large | 1 |
5 | 1 | Small | -1 | 12 | 3 | Medium | 1 |
6 | 2 | Small | -1 | 13 | 3 | Medium | 1 |
7 | 2 | Medium | -1 | 14 | 3 | Large | 1 |
那么这道题的手算过程我就不演示了,主要看代码部分(由于写的比较仓促,里面的代码不够简洁,但思路还算清晰,可以解决所有关于这道题的情况判断):
废话不多说,直接贴代码:
import numpy as np
import pandas as pd
# 训练集14组(X1,X2,Y)
a = np.array([[1, "Small", -1], [1, "Medium", -1], [1, "Medium", 1],
[1, "Small", 1], [1, "Small", -1], [2, "Small", -1],
[2, "Medium", -1], [2, "Medium", 1], [2, "Large", 1],
[2, "Large", 1], [3, "Large", 1], [3, "Medium", 1],
[3, "Medium", 1], [3, "Large", 1]])
b = pd.DataFrame(a, columns=['X1', 'X2', 'Y'])
# 多计数器
count_x1 = np.zeros((3, 2))
count_x2 = np.zeros((3, 2))
# 概率值(1,-1)
p_y1 = 0
p_y2 = 0
# 测试集
test = pd.Series({
'X1': 2, 'X2': 'Small'})
# P(YK|X1,X2)=P(X1|YK)*P(X2|YK)*P(YK)/P(X)
# 计数器统计训练集相应数据
for index, row in b.iterrows():
if row['Y'] == "1":
if row['X1'] == "1":
count_x1[0][0] += 1
elif row['X1'] == "2":
count_x1[1][0] += 1
else:
count_x1[2][0] += 1
if row[