机器学习之朴素贝叶斯(含代码)

文章是机器学习笔记,转载请提前告知!

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(AB1)),后验概率就是“肉尝起来是酸的,求是加了醋还是变质”概率。

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)分类算法

  • 1
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值