朴素贝叶斯算法案例演示及Python实现

发布于:2025-07-04 ⋅ 阅读:(24) ⋅ 点赞:(0)

一、基本原理

朴素贝叶斯思想:依靠特征概率去预测分类,针对于代分类的样本,会求解在该样本出现的条件下,各个类别出现的概率,哪个类别概率最大则取哪个类别。其核心原理来自于贝叶斯公式:
P ( A ∣ B ) = P ( B ∣ A ) ∗ P ( A ) P ( B ) P(A|B)=\frac{P(B|A)*P(A)}{P(B)} P(AB)=P(B)P(BA)P(A)
其中, P ( A ) P(A) P(A)称之为先验概率, P ( A ∣ B ) P(A|B) P(AB)称之为后验概率。结合先验和后验概率的基本概念,可以将贝叶斯公式转化理解为:在事件B发生之后,事件A的发生的概率将发生调整,而调整的幅度则是这个调整因子 P ( B ∣ A ) P ( B ) \frac{P(B|A)}{P(B)} P(B)P(BA)。当这个调整因为为1时,则可以理解为事件B的发生不会对事件A造成任何影响,在统计学的角度上称事件A和事件B相互独立,即 P ( A B ) = P ( A ) P ( B ) P(AB)=P(A)P(B) P(AB)=P(A)P(B)

概念 定义
先验概率 基于常识或认识对于某个事件A发生的概率假定
后验概率 在某个事件B发生之后,对于事件A发生概率的修正假定

接下来,以生活中的案例进一步理解先验和后验概率。例如,一位股市小白预测大A明天下跌的概率是50%,那么这里的50%则是先验概率;再被多次割韭菜之后,这位小白则总结了一套规律,在得知大A今天上涨10%后,预测大A明天下跌概率为80%;那么这里的80%则为后验概率

刚刚介绍的均是贝叶斯公式相关的内容,接下来对【朴素】这一词进行深入说明。通常在该算法应用过程中,事件B作为特征,事件A作为类别,则可转化为
P ( 类别 ∣ 特征 ) = P ( 特征 ∣ 类别 ) ∗ P ( 类别 ) P ( 特征 ) P(类别|特征)=\frac{P(特征|类别)*P(类别)}{P(特征)} P(类别特征)=P(特征)P(特征类别)P(类别)

实际案例中,通常特征都会有多个,这里就有个前提假设条件,也正是朴素一词的来源,它是需要特征之间相互独立的,上述公式即可分解为
P ( 类别 ∣ 特征 ) = P ( 特 征 1 ∣ 类别 ) ∗ P ( 特 征 2 ∣ 类别 ) ∗ . . . P ( 特 征 n ∣ 类别 ) ∗ P ( 类别 ) P ( 特征 ) P(类别|特征)=\frac{P(特征_{1}|类别)*P(特征_2|类别)*...P(特征_n|类别)*P(类别)}{P(特征)} P(类别特征)=P(特征)P(1类别)P(2类别)...P(n类别)P(类别)

二、案例演示

以实际案例对朴素贝叶斯算法进行分类加深理解,现有一信贷用户数据集,特征包含三个方面:信用水平、收入水平、工作稳定性。类别为是否逾期还款。现根据如下数据,预测一名用户信用水平为Good,收入水平为Low,工作稳定性为Unstable,是否会逾期还款。数据如下所示

用户ID 信用水平 收入水平 工作稳定性 是否逾期还款
1 Bad Low Unstable Yes
2 Bad High Stable No
3 Bad Medium Stable Yes
4 Good Low Stable No
5 Good High Unstable Yes
6 Medium High Stable No
7 Medium Low Unstable Yes
8 Good Medium Stable No
9 Medium Medium Stable Yes
10 Bad High Unstable No
2.1 未平滑处理

(1)计算先验概率
P ( 是否逾期还款 = Y e s ) = 5 / 10 = 0.5 P ( 是否逾期还款 = N o ) = 5 / 10 = 0.5 P(是否逾期还款=Yes)=5/10=0.5\\ P(是否逾期还款=No)=5/10=0.5 P(是否逾期还款=Yes)=5/10=0.5P(是否逾期还款=No)=5/10=0.5
(2)计算条件概率
P ( 信用水平 = G o o d ∣ 是否逾期还款 = Y e s ) = 1 / 5 P ( 收入水平 = L o w ∣ 是否逾期还款 = Y e s ) = 2 / 5 P ( 工作稳定性 = U n s t a b l e ∣ 是否逾期还款 = Y e s ) = 3 / 5 P(信用水平=Good|是否逾期还款=Yes)=1/5\\ P(收入水平=Low|是否逾期还款=Yes)=2/5\\ P(工作稳定性=Unstable|是否逾期还款=Yes)=3/5 P(信用水平=Good是否逾期还款=Yes)=1/5P(收入水平=Low是否逾期还款=Yes)=2/5P(工作稳定性=Unstable是否逾期还款=Yes)=3/5

P ( 信用水平 = G o o d ∣ 是否逾期还款 = N o ) = 2 / 5 P ( 收入水平 = L o w ∣ 是否逾期还款 = N o ) = 1 / 5 P ( 工作稳定性 = U n s t a b l e ∣ 是否逾期还款 = N o ) = 1 / 5 P(信用水平=Good|是否逾期还款=No)=2/5\\ P(收入水平=Low|是否逾期还款=No)=1/5\\ P(工作稳定性=Unstable|是否逾期还款=No)=1/5 P(信用水平=Good是否逾期还款=No)=2/5P(收入水平=Low是否逾期还款=No)=1/5P(工作稳定性=Unstable是否逾期还款=No)=1/5

(3)预测类别
考虑各特征概率不影响最终类别判断,在此忽略各特征概率计算
P ( 是否逾期还款 = Y e s ∣ 信用水平 = G o o d , 收入水平 = L o w , 工作稳定性 = U n s t a b l e ) ≈ P ( 信用水平 = G o o d ∣ 是否逾期还款 = Y e s ) ∗ P ( 收入水平 = L o w ∣ 是否逾期还款 = Y e s ) ∗ P ( 工作稳定性 = U n s t a b l e ∣ 是否逾期还款 = Y e s ) ∗ P ( 是否逾期还款 = Y e s ) = 1 / 5 ∗ 2 / 5 ∗ 3 / 5 ∗ 1 / 2 = 0.024 P(是否逾期还款=Yes|信用水平= Good,收入水平=Low,工作稳定性=Unstable) \approx \\P(信用水平=Good|是否逾期还款=Yes) *P(收入水平=Low|是否逾期还款=Yes)*\\P(工作稳定性=Unstable|是否逾期还款=Yes)*P(是否逾期还款=Yes)=1/5*2/5*3/5*1/2=0.024 P(是否逾期还款=Yes信用水平=Good,收入水平=Low,工作稳定性=Unstable)P(信用水平=Good是否逾期还款=Yes)P(收入水平=Low是否逾期还款=Yes)P(工作稳定性=Unstable是否逾期还款=Yes)P(是否逾期还款=Yes)=1/52/53/51/2=0.024

P ( 是否逾期还款 = N o ∣ 信用水平 = G o o d , 收入水平 = L o w , 工作稳定性 = U n s t a b l e ) ≈ P ( 信用水平 = G o o d ∣ 是否逾期还款 = N o ) ∗ P ( 收入水平 = L o w ∣ 是否逾期还款 = N o ) ∗ P ( 工作稳定性 = U n s t a b l e ∣ 是否逾期还款 = N o ) ∗ P ( 是否逾期还款 = N o ) = 2 / 5 ∗ 1 / 5 ∗ 1 / 5 ∗ 1 / 2 = 0.008 P(是否逾期还款=No|信用水平= Good,收入水平=Low,工作稳定性=Unstable) \approx \\P(信用水平=Good|是否逾期还款=No) *P(收入水平=Low|是否逾期还款=No)*\\P(工作稳定性=Unstable|是否逾期还款=No)*P(是否逾期还款=No)=2/5*1/5*1/5*1/2=0.008 P(是否逾期还款=No信用水平=Good,收入水平=Low,工作稳定性=Unstable)P(信用水平=Good是否逾期还款=No)P(收入水平=Low是否逾期还款=No)P(工作稳定性=Unstable是否逾期还款=No)P(是否逾期还款=No)=2/51/51/51/2=0.008

标准化后,逾期概率为75%,故判断这名用户将会逾期还款(信用水平为Good,收入水平为Low,工作稳定性为Unstable)

2.2 Laplace平滑处理

当预测样本出现了训练集未曾出现的特征组合时,那么在计算特征概率时,数值直接为0,直接影响最终分类识别。例如,如果训练集中无信用水平为Good+逾期为Yes的样本,则P(Good|Yes)=0,导致所有信用水平为Good的逾期样本将无法识别。此时,就需要对计算概率进行修正,修正方式如下:
P s m o o t h ( x i ∣ y ) = c o u n t ( x i , y ) + α c o u n t ( y ) + K ∗ α P_{smooth}(x_i|y)=\frac{count(x_i,y)+\alpha}{count(y)+K*\alpha} Psmooth(xiy)=count(y)+Kαcount(xi,y)+α
其中, α \alpha α为平滑参数,通常取1; K为当前特征的数量(例如信用水平有Bad/Good/Medium,则K=3)

(1) 平滑处理后的条件概率
P ( 信用水平 = G o o d ∣ 是否逾期还款 = Y e s ) = ( 1 + 1 ) / ( 3 + 5 ) = 1 / 4 P ( 收入水平 = L o w ∣ 是否逾期还款 = Y e s ) = ( 2 + 1 ) / ( 3 + 5 ) = 3 / 8 P ( 工作稳定性 = U n s t a b l e ∣ 是否逾期还款 = Y e s ) = ( 3 + 1 ) / ( 2 + 5 ) = 4 / 7 P(信用水平=Good|是否逾期还款=Yes)=(1+1)/(3+5)=1/4\\ P(收入水平=Low|是否逾期还款=Yes)=(2+1)/(3+5)=3/8\\ P(工作稳定性=Unstable|是否逾期还款=Yes)=(3+1)/(2+5)=4/7 P(信用水平=Good是否逾期还款=Yes)=(1+1)/(3+5)=1/4P(收入水平=Low是否逾期还款=Yes)=(2+1)/(3+5)=3/8P(工作稳定性=Unstable是否逾期还款=Yes)=(3+1)/(2+5)=4/7

P ( 信用水平 = G o o d ∣ 是否逾期还款 = N o ) = ( 1 + 2 ) / ( 3 + 5 ) = 3 / 8 P ( 收入水平 = L o w ∣ 是否逾期还款 = N o ) = ( 1 + 1 ) / ( 3 + 5 ) = 1 / 4 P ( 工作稳定性 = U n s t a b l e ∣ 是否逾期还款 = N o ) = ( 1 + 1 ) / ( 2 + 5 ) = 2 / 7 P(信用水平=Good|是否逾期还款=No)=(1+2)/(3+5)=3/8\\ P(收入水平=Low|是否逾期还款=No)=(1+1)/(3+5)=1/4\\ P(工作稳定性=Unstable|是否逾期还款=No)=(1+1)/(2+5)=2/7 P(信用水平=Good是否逾期还款=No)=(1+2)/(3+5)=3/8P(收入水平=Low是否逾期还款=No)=(1+1)/(3+5)=1/4P(工作稳定性=Unstable是否逾期还款=No)=(1+1)/(2+5)=2/7

(2) 平滑处理预测

P ( 是否逾期还款 = Y e s ∣ 信用水平 = G o o d , 收入水平 = L o w , 工作稳定性 = U n s t a b l e ) ≈ P ( 信用水平 = G o o d ∣ 是否逾期还款 = Y e s ) ∗ P ( 收入水平 = L o w ∣ 是否逾期还款 = Y e s ) ∗ P ( 工作稳定性 = U n s t a b l e ∣ 是否逾期还款 = Y e s ) ∗ P ( 是否逾期还款 = Y e s ) = 1 / 4 ∗ 3 / 8 ∗ 4 / 7 ∗ 1 / 2 ≈ 0.0268 P(是否逾期还款=Yes|信用水平= Good,收入水平=Low,工作稳定性=Unstable) \approx \\P(信用水平=Good|是否逾期还款=Yes) *P(收入水平=Low|是否逾期还款=Yes)*\\P(工作稳定性=Unstable|是否逾期还款=Yes)*P(是否逾期还款=Yes)=1/4*3/8*4/7*1/2\approx0.0268 P(是否逾期还款=Yes信用水平=Good,收入水平=Low,工作稳定性=Unstable)P(信用水平=Good是否逾期还款=Yes)P(收入水平=Low是否逾期还款=Yes)P(工作稳定性=Unstable是否逾期还款=Yes)P(是否逾期还款=Yes)=1/43/84/71/20.0268

P ( 是否逾期还款 = N o ∣ 信用水平 = G o o d , 收入水平 = L o w , 工作稳定性 = U n s t a b l e ) ≈ P ( 信用水平 = G o o d ∣ 是否逾期还款 = N o ) ∗ P ( 收入水平 = L o w ∣ 是否逾期还款 = N o ) ∗ P ( 工作稳定性 = U n s t a b l e ∣ 是否逾期还款 = N o ) ∗ P ( 是否逾期还款 = N o ) = 3 / 8 ∗ 1 / 4 ∗ 2 / 7 ∗ 1 / 2 ≈ 0.0133 P(是否逾期还款=No|信用水平= Good,收入水平=Low,工作稳定性=Unstable) \approx \\P(信用水平=Good|是否逾期还款=No) *P(收入水平=Low|是否逾期还款=No)*\\P(工作稳定性=Unstable|是否逾期还款=No)*P(是否逾期还款=No)=3/8*1/4*2/7*1/2\approx0.0133 P(是否逾期还款=No信用水平=Good,收入水平=Low,工作稳定性=Unstable)P(信用水平=Good是否逾期还款=No)P(收入水平=Low是否逾期还款=No)P(工作稳定性=Unstable是否逾期还款=No)P(是否逾期还款=No)=3/81/42/71/20.0133

标准化后,逾期概率为66.7%,故仍判断这名用户还是会逾期还款

三、Python实现

接下来以Python的方式实现上述2种处理方式

# 朴素贝叶斯
import numpy as np
import pandas as pd
data = pd.DataFrame(
    {
    'credit_history':['Bad','Bad','Bad','Good','Good','Medium','Medium','Good','Medium','Bad']
    ,'income_level':['Low','High','Medium','Low','High','High','Low','Medium','Medium','High']
    ,'job_stablity':['Unstable','Stable','Stable','Stable','Unstable','Stable','Unstable','Stable'
                     ,'Stable','Unstable']
    ,'is_delay':['Yes','No','Yes','No','Yes','No','Yes','No','Yes','No']
    }

)

def cal_prob(data_list,label_list,alpha):
    all_label       = set(np.unique(label_list))
    category,counts = np.unique(data_list,return_counts=True)
    retain_label    = all_label.difference(category)
    n = len(all_label)
    count_dict = dict(zip(category,counts))
    for label in retain_label:
        if count_dict.get(label) is None:
            count_dict[label]=0
    
    prob_dict = {key:(value+alpha)/(sum(count_dict.values())+alpha*n) for key,value in count_dict.items()}
    
    return prob_dict


delay_prob       = cal_prob(data['is_delay'],[],0)

# 不使用拉普拉斯平滑处理
credict_yes_prob = cal_prob(data[data['is_delay']=='Yes']['credit_history'],[],0)
income_yes_prob  = cal_prob(data[data['is_delay']=='Yes']['income_level'],[],0)
job_yes_stablity = cal_prob(data[data['is_delay']=='Yes']['job_stablity'],[],0)

credict_no_prob = cal_prob(data[data['is_delay']=='No']['credit_history'],[],0)
income_no_prob  = cal_prob(data[data['is_delay']=='No']['income_level'],[],0)
job_no_stablity = cal_prob(data[data['is_delay']=='No']['job_stablity'],[],0)

credict_yes_prob_smooth = cal_prob(data[data['is_delay']=='Yes']['credit_history'],data['credit_history'],1)
income_yes_prob_smooth  = cal_prob(data[data['is_delay']=='Yes']['income_level'],data['income_level'],1)
job_yes_stablity_smooth = cal_prob(data[data['is_delay']=='Yes']['job_stablity'],data['job_stablity'],1)

credict_no_prob_smooth = cal_prob(data[data['is_delay']=='No']['credit_history'],data['credit_history'],1)
income_no_prob_smooth  = cal_prob(data[data['is_delay']=='No']['income_level'],data['income_level'],1)
job_no_stablity_smooth = cal_prob(data[data['is_delay']=='No']['job_stablity'],data['job_stablity'],1)

# 未平滑处理:推测一个人信用GOOD,收入水平Low,工作Unstable 情况下是否会逾期还款
predict_yes_delay = delay_prob['Yes']*credict_yes_prob['Good']*income_yes_prob['Low']*job_yes_stablity['Unstable']
predict_no_delay = delay_prob['No']*credict_no_prob['Good']*income_no_prob['Low']*job_no_stablity['Unstable']

# 拉普拉斯平滑处理:推测一个人信用GOOD,收入水平Low,工作Unstable 情况下是否会逾期还款
predict_yes_delay_smooth = delay_prob['Yes']*credict_yes_prob_smooth['Good']*income_yes_prob_smooth['Low']*job_yes_stablity_smooth['Unstable']
predict_no_delay_smooth = delay_prob['No']*credict_no_prob_smooth['Good']*income_no_prob_smooth['Low']*job_no_stablity_smooth['Unstable']


print('未平滑处理,标准化逾期概率:{}%'.format(round(100*predict_yes_delay/(predict_yes_delay+predict_no_delay),2)))
print('平滑处理,标准化逾期概率:{}%'.format(round(100*predict_yes_delay_smooth/(predict_yes_delay_smooth+predict_no_delay_smooth),2)))

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到