机器学习之朴素贝叶斯(含代码)
文章是机器学习笔记,转载请提前告知!
文章目录
1、概率论知识补充
1.1 先验概率和后验概率
先验概率(prior probability)是指根据以往经验和分析得到的概率,它往往作为"由因求果"问题中的"因"出现的概率。 [ 1 ] [1] [1]
后验概率是指在得到“结果”的信息后重新修正的概率,是“执果寻因”问题中的"果"。先验概率与后验概率有不可分割的联系,后验概率的计算要以先验概率为基础。 [ 2 ] [2] [2]
为了方便理解,我们使用以下事件加以说明: [ 3 ] [3] [3]
事件B1,B2可以看作“因”,事件A可以看作“果”,那么先验概率可以是求“肉加了醋后尝起来是酸的”概率(
P
(
A
∣
B
1
)
P(A|B1)
P(A∣B1)),后验概率就是“肉尝起来是酸的,求是加了醋还是变质”概率。
1.2 贝叶斯定理
贝叶斯定理就是通过先验概率求后验概率的过程。仍然以上面的事件为例:
我们根据经验知道的是放醋和肉变质的概率,我们也知道放醋肉尝起来酸和变质肉尝起来酸的概率,现在肉尝起来是酸的,要求是放了醋还是肉变质的概率。
觉得有点绕的可以再去看看后面的示例。
2、朴素贝叶斯
朴素贝叶斯公式推导过程不再赘述。
2.1 算法流程
我们先规定好输入输出:
结果有k个分类,数据集有j个特征,每个特征有
S
j
S_{j}
Sj个取值
步骤:
(1)计算先验概率和条件概率:
(2)对于给定的实例
计算:
(3)确定x的分类:
2.2 拉普拉斯平滑
前面在计算先验概率和条件概率的时候有可能会出现结果为0的情况,影响最后分类的结果,解决办法就是贝叶斯估计:
常取
λ
=
1
\lambda=1
λ=1,这时称为拉普拉斯平滑。
2.3 算法示例
几乎讲朴素贝叶斯,都会有这个示例。
和李航老师《统计学习方法》中的示例相同,我就直接把那边的求解过程搬过来了。
刚好能拿这个示例和之前的算法流程相互对照着理解。
3、算法实现(python)
3.1 代码设计
代码只简单实现朴素贝叶斯。
3.2 算法验证
为了检验算法性能,使用NASADefect数据集中的CM1进行实验并记录结果。
import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import KBinsDiscretizer
from sklearn.model_selection import train_test_split
#规范化用到的范围
FEATURE_RANGE_MIN=0.0
FEATURE_RANGE_MAX=10.0
filename='/Users/schillerxu/Documents/sourcecode/python/pandas/CM1.csv'
original_data=pd.read_csv(filename)
#数据集特征
feasures=original_data.columns
#数据集标签列
labels=original_data[feasures[-1]]
#对于无法转化为数字的,pandas按照字符串处理
#这里需要将label转化为0和1
class_map={"b'N'":0,"b'Y'":1}
labels=labels.map(class_map)
#数据需要预处理,包括规范化和离散化
original_data=original_data.iloc[:,0:-1]
#数据因为维度和计量单位不同,需要缩放至同一个范围
minmax=MinMaxScaler(feature_range=(FEATURE_RANGE_MIN,FEATURE_RANGE_MAX))
data=minmax.fit_transform(original_data)
#离散化
discretize_size=[5]*37
enc=KBinsDiscretizer(n_bins=discretize_size,encode='ordinal',strategy='uniform')
data=enc.fit_transform(data)
data=pd.DataFrame(data,dtype=int,columns=feasures[:-1])
#分离训练和测试数据
train_data,test_data,y_train,y_test=train_test_split(data,labels,test_size=0.2,random_state=42)
train_data['Defective']=labels
#defect prediction里面都是把有缺陷的模块当作正类
#无缺陷的模块当作负类
#拉普拉斯平滑
train_po_rate=(y_train.sum()+1)/(y_train.size+labels.size)
train_ne_rate=1-train_po_rate
train_po_ins=train_data[train_data['Defective']==1]
#保存正实例下的条件概率
rates_po=[]
for i in range(len(feasures)-1):
feasture_array=data[feasures[i]].unique()
rates=dict()
for f in feasture_array:
r=(train_po_ins[train_po_ins[feasures[i]]==f].index.size+1)/(train_po_ins.index.size+feasture_array.size)
rates[f]=r
rates_po.append(rates)
train_ne_ins=train_data[train_data['Defective']==0]
#保存负实例下的条件概率
rates_ne=[]
for i in range(len(feasures)-1):
#feasture_array=train_data[feasures[i]].unique()
#这样写是有问题的,可能某个特征的某个值不一定出现在训练数据里面
feasture_array=data[feasures[i]].unique()
rates=dict()
for f in feasture_array:
r=(train_ne_ins[train_ne_ins[feasures[i]]==f].index.size+1)/(train_ne_ins.index.size+feasture_array.size)
rates[f]=r
rates_ne.append(rates)
predict_result=[]
for i in range(len(test_data)):
ins=test_data.iloc[i,:]
p=train_po_rate
for j in range(len(feasures)-1):
rates=rates_po[j]
p=p*rates[ins[feasures[j]]]
n=train_ne_rate
for j in range(len(feasures)-1):
rates=rates_ne[j]
n=n*rates[ins[feasures[j]]]
if p>n:
predict_result.append(1)
else:
predict_result.append(0)
cor=0
for i in range(len(predict_result)):
if y_test.iloc[i]==predict_result[i]:
cor+=1
print(cor)
print(cor/len(predict_result))
代码没有封装成函数,拖延了一个月才开始写,正确率在88%左右。
4、参考资料
[
1
]
[1]
[1]百度百科-先验概率
[
2
]
[2]
[2]百度百科-后验概率
[
3
]
[3]
[3][贝叶斯公式的直观理解(先验概率/后验概率)
[
4
]
[4]
[4]手写朴素贝叶斯(naive_bayes)分类算法
本文地址:https://blog.csdn.net/u012949658/article/details/109231441
上一篇: Python监控线上异常图片地址自动告警!有省了一笔人力资源
下一篇: flask框架写接口