04 朴素贝叶斯法——Python实现

一、题目:

在这里插入图片描述

二、算法思想:

输入:训练集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ( x 3 , y 3 ) , . . . , ( x N , y N ) } T=\begin{Bmatrix} (x_{1},y_{1}),(x_{2},y_{2}),(x_{3},y_{3}),...,(x_{N},y_{N}) \end{Bmatrix} T={(x1,y1),(x2,y2),(x3,y3),...,(xN,yN)};实例 x x x
输出:实例 x x x 的分类。
(1)计算先验概率和条件概率:
P ( Y = c k ) = ∑ i = 1 N I ( y i = c k ) N ,   k = 1 , 2 , 3 , . . . , K P(Y=c_{k})=\frac{\sum_{i=1}^{N}I(y_{i}=c_{k})}{N},\: k=1,2,3,...,K P(Y=ck)=Ni=1NI(yi=ck),k=1,2,3,...,K
P ( X ( j ) = a j l ∣ Y = c k ) = ∑ i = 1 N I ( x i ( j ) = a j l , y i = c k ) ∑ i = 1 N I ( y i = c k ) ,   k = 1 , 2 , 3 , . . . , K ; j = 1 , 2 , . . . , n ; l = 1 , 2 , . . . , S j P(X^{(j)}=a_{jl}|Y=c_{k})=\frac{\sum_{i=1}^{N}I(x_{i}^{(j)}=a_{jl},y_{i}=c_{k})}{\sum_{i=1}^{N}I(y_{i}=c_{k})},\: k=1,2,3,...,K;j=1,2,...,n;l=1,2,...,S_{j} P(X(j)=ajlY=ck)=i=1NI(yi=ck)i=1NI(xi(j)=ajlyi=ck),k=1,2,3,...,Kj=1,2,...,nl=1,2,...,Sj
(2)对给出的实例 x = { x ( 1 ) , x ( 2 ) , . . . , x ( n ) } x=\begin{Bmatrix} x^{(1)},x^{(2)},...,x^{(n)} \end{Bmatrix} x={x(1),x(2),...,x(n)}计算联合概率分布:
P ( Y = c k ) ∗ ∏ j = 1 n P ( X ( j ) = x ( j ) ∣ Y = c k ) ,   k = 1 , 2 , 3 , . . . , K P(Y=c_{k})*\prod_{j=1}^{n}P(X^{(j)}=x^{(j)}|Y=c_{k}),\: k=1,2,3,...,K P(Y=ck)j=1nP(X(j)=x(j)Y=ck),k=1,2,3,...,K
(3)根据最大值确定实例 x x x的类:
y = a r g   m a x c k P ( Y = c k ) ∗ ∏ j P ( X ( j ) = x ( j ) ∣ Y = c k ) . y=arg \: max_{c_{k}}P(Y=c_{k})*\prod_{j}^{}P(X^{(j)}=x^{(j)}|Y=c_{k}) . y=argmaxckP(Y=ck)jP(X(j)=x(j)Y=ck).

三、Python代码实现:

# author yuxy
#朴素贝叶斯算法实现
# 输入:训练数据集;实例x;
# 输出:实例x的分类。
# (1)计算先验概率和条件概率;
# (2)对于给定的实例x,计算后验概率(因为不同分类的后验概率的分母相同,所以可以简化为比较计算联合概率分布)
# (3)确定最大联合概率分布对应的类别即为实例x对应的类别。

import numpy as np
def prior_probability(dataSet, Y):
    """
    求先验概率的函数,返回
    :param dataSet: 训练数据集
    :param Y: y的所有可能取值
    :return: 一个容纳各个y值先验概率的数组
    """
    m=len(dataSet)
    n=len(dataSet[0])
    k=len(Y) #类别的个数
    res=[None for j in range(k)]
    p=0
    for ck in Y:
        sum=float(0)
        for i in range(m):
            if dataSet[i][n - 1] == ck:
                sum = sum + 1
        res[p]=sum / m
        p=p+1
    return res

def condition_probability(dataSet, Y, A):
    """
    求条件概率
    :param dataSet: 训练数据集
    :param Y: y所有可能的取值
    :param A1: 第一个特征向量
    :param A2:第二个特征向量
    :return: 返回条件概率集合
    """
    a,b=np.shape(dataSet) #训练数据集中的行和列(a行,b列)
    p=len(A1)
    q=len(A2)
    n=len(Y)
    m=p+q

    res=[[float(0)]*m for i in range(n)]  #创建存储条件概率的二维数组,n行m列
    #计算各个y标记的次数
    N=[0]*n
    for i in range(n):
        t=0
        for k in range(a):
            if dataSet[k][2] == Y[i]:
                t=t+1
        N[i] = t

    #计算条件概率
    for i in range(n):
        for j in range(m):
            sum1 = float(0)
            sum2 = float(0)
            sum3 = float(0)
            sum4 = float(0)
            for k in range(a):
                # 循环判断dataSet中满足条件的实例
                if dataSet[k][2] == Y[0]:
                    if j<3 and dataSet[k][0] == A[j]:
                        sum1 = sum1 + 1
                        res[0][j] = sum1 / N[0]
                    if j>=3 and dataSet[k][1] == A[j]:
                        sum3 = sum3 + 1
                        res[0][j] = sum3 / N[0]
                elif dataSet[k][2] == Y[1]:
                    if j<3 and dataSet[k][0]==A[j]:
                        sum2 = sum2 + 1
                        res[1][j] = sum2 / N[1]
                    if j>=3 and dataSet[k][1]==A[j]:
                        sum4 = sum4 + 1
                        res[1][j] = sum4 / N[1]
    return res

def joint_probability( Y, pri_probability, con_probability, x, A):
    """
    求联合概率
    :param Y: y的所有可能取值
    :param pri_probability: 先验概率矩阵
    :param con_probability: 联合概率矩阵
    :param x: 给定的实例x
    :return: 各个y值对应的联合概率
    """
    length=len(Y)
    res=[float(0)]*length
    for i in range(length):
        sum=float(1)
        for j in range(len(x)):
            sum = sum * con_probability[i][A.index(x[j])]
        sum = sum * pri_probability[i]
        res[i] =sum
    return res

def get_max(j_probability):
    """
    获取联合概率函数最大的类别,作为实例x的输出类别
    :param pri_probability: 联合概率函数值
    :param Y: 所有可能的x取值
    :return: 返回最大值的类别值
    """
    length=len(j_probability)
    max=float(0)
    index=0
    for i in range(length):
        if j_probability[i] > max:
            index=i
    return index



if __name__=='__main__':
    dataSet=([1,'S',-1],[1,'M',-1],[1,'M',1],[1,'S',1],[1,'S',-1],[2,'S',-1],[2,'M',-1],[2,'M',1],
             [2,'L',1],[2,'L',1],[3,'L',1],[3,'M',1],[3,'M',1],[3,'L',1],[3,'L',-1])
    Y=[1,-1]
    A1=[1,2,3]
    A2=['S','M','L']
    A = A1 + A2
    x = [2, 'S']
    pri_probability= prior_probability(dataSet, Y)
    con_probability=condition_probability(dataSet, Y, A)
    j_probability=joint_probability(Y, pri_probability, con_probability, x, A)
    print('训练样本集为:')
    for i in range(len(dataSet)):
        print(dataSet[i])
    print('实例x为:%s' % x)
    print('实例x的类别为:%s' % Y[get_max(j_probability)])

实验结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值