拉普拉斯修正的朴素贝叶斯分类器及AODE分类器

来源:互联网 发布:js数组lenght属性 编辑:程序博客网 时间:2024/06/05 15:54

下面的一些原理来着周志华老师的西瓜书。

***************************************************************************************************************

拉普拉斯修正的朴素贝叶斯分类器主要目的是为了避免遇到某些特征属性为空时,使得相关后验概率为0的情况。其相关计算公式如下:


其中Dc表示训练集中第c类样本的集合,P(c)表示c类的先验概率,N表示标签的类别数;Dcxi表示第i个属性上位属性xi的集合,Ni表示第i个属性的类别数。

判别函数如下(公式1):

AODE是一种基于集成学习机制、更为强大的独依赖分类器,为半朴素贝叶斯分类器。其相关的计算公式如下:



通过以上的两个关键函数12,判断各个关键概率的大小来判断类别。当连乘过小的时候,可采用开方或者取对数的方式。

使用的数据如下:编号色泽根蒂敲声纹理脐部触感密度含糖量好瓜1青绿蜷缩浊响清晰凹陷硬滑0.6970.46是2乌黑蜷缩沉闷清晰凹陷硬滑0.7740.376是3乌黑蜷缩浊响清晰凹陷硬滑0.6340.264是4青绿蜷缩沉闷清晰凹陷硬滑0.6080.318是5浅白蜷缩浊响清晰凹陷硬滑0.5560.215是6青绿稍蜷浊响清晰稍凹软粘0.4030.237是7乌黑稍蜷浊响稍糊稍凹软粘0.4810.149是8乌黑稍蜷浊响清晰稍凹硬滑0.4370.211是9乌黑稍蜷沉闷稍糊稍凹硬滑0.6660.091否10青绿硬挺清脆清晰平坦软粘0.2430.267否11浅白硬挺清脆模糊平坦硬滑0.2450.057否12浅白蜷缩浊响模糊平坦软粘0.3430.099否13青绿稍蜷浊响稍糊凹陷硬滑0.6390.161否14浅白稍蜷沉闷稍糊凹陷硬滑0.6570.198否15乌黑稍蜷浊响清晰稍凹软粘0.360.37否16浅白蜷缩浊响模糊平坦硬滑0.5930.042否17青绿蜷缩沉闷稍糊稍凹硬滑0.7190.103否



# -*- coding: utf-8 -*-"""Created on Wed Jan  4 21:05:48 2017@author: ZQ"""import numpy as npfrom math import pi as PIdef loadData(filename):    file = open(filename)    lines = file.readlines()    data = []    for line in lines[1:]:        d = line.strip().split('\t')        d = d[1:]        data.append(d)    return np.array(data)#所有计算采用拉普拉斯修正,朴素贝叶斯分类   #计算先验概率def calcpro(data):    data_count = len(data)    s_l = set(data[:,-1])    N = len(s_l)    yes_count = 0    for vec in data:        if vec[-1] == '是':            yes_count += 1    return (yes_count+1)/(data_count+N)#用于计算标签的条件概率def calcLabelpro(data,i,value):    data_yes_len = 0    fec_yes = 0    fec_no = 0    s_f = set(data[:,i])    Ni = len(s_f)    for vec in data:        if vec[-1] == '是':            data_yes_len += 1        if vec[i] == value:                        if vec[-1] == '是':                fec_yes += 1            else:                fec_no += 1    #print(fec_yes,fec_no,data_yes_len)    return (fec_yes+1)/(data_yes_len+Ni),(fec_no+1)/(len(data)-data_yes_len+Ni)#高斯概率密度def gass(x,u,d):    pro = (2*PI)**0.5*d**0.5    pro = 1/pro    pro = pro*np.exp(-(x-u)**2/(2*d))    return pro#用于计算连续数值的概率密度def calcNumpro(data,i,value):    data_yes = []    data_no = []    for vec in data:        if vec[-1] == '是':            data_yes.append(vec[i])        else:            data_no.append(vec[i])                num_yes = list(map(float,data_yes))    num_no = list(map(float,data_no))    num_yes = np.array(num_yes)    num_no = np.array(num_no)    #print(num_yes.mean(),num_yes.var()**0.5)    #计算均值与方差    mean_yes = num_yes.mean()    var_yes = num_yes.var()    mean_no = num_no.mean()    var_no = num_no.var()        pro_yes = gass(value,mean_yes,var_yes)    pro_no = gass(value,mean_no,var_no)        return pro_yes,pro_nodef Bayes(train_data,test_data):    #获得先验概率    pro_yes = calcpro(train_data)    pro_no = 1 - pro_yes    for i in range(len(test_data)-1):        if i < 6:           py,pn = calcLabelpro(data,i,test_data[i])           pro_yes = pro_yes*py           pro_no = pro_no*pn        else:            py,pn = calcNumpro(data,i,float(test_data[i]))            pro_yes = pro_yes*py            pro_no = pro_no*pn    if pro_yes > pro_no:        print('是')    else:        print('否')    print(test_data[-1])    #AODE分类器,未实现连续属性(使用每个属性作为超父来构建SPODE)#首先计算P(C,Xi)def calcP_C_Xi(data,i,value):    D = len(data)    label_set = set(data[:,-1])    N = len(label_set)    i_set = set(data[:,i])    Ni = len(i_set)    Xi_yes_count = 0    Xi_no_count = 0    for vec in data:        if vec[i] == value:            if vec[-1] == '是':                Xi_yes_count += 1            else:                Xi_no_count += 1    P_y = (Xi_yes_count+1)/(D + N*Ni)    P_n = (Xi_no_count+1)/(D + N*Ni)    return P_y,P_n#其次计算P(Xj|C,Xi)def calcP_Xj_C_Xi(data,j,i,value_j,value):    j_set = set(data[:,j])    Nj = len(j_set)    Xi_y_count = 0    Xi_n_count = 0    Xij_y_count = 0    Xij_n_count = 0    for vec in data:        if vec[i] == value:            if vec[-1] == '是':                Xi_y_count += 1            else:                Xi_n_count += 1            if vec[j] == value_j:                if vec[-1] == '是':                    Xij_y_count += 1                else:                    Xij_n_count += 1    p_y = (Xij_y_count + 1)/(Xi_y_count + Nj)    p_n = (Xij_n_count + 1)/(Xi_n_count + Nj)    return p_y,p_ndef AODE(train_data,test_data):    p_y_list = []    p_n_list = []    p_y = 1    p_n = 1    for i in range(6):        P_c_Xi_y,P_c_Xi_n = calcP_C_Xi(data,i,test_data[i])        for j in range(6):                        P_c_Xji_y,P_c_Xji_n = calcP_Xj_C_Xi(data,j,i,test_data[j],test_data[i])            p_y = p_y * P_c_Xji_y            p_n = p_n * P_c_Xji_n        p_y_list.append(p_y*P_c_Xi_y)        p_n_list.append(p_n*P_c_Xi_n)    if sum(p_y_list) > sum(p_n_list):        print('是')    else:        print('否')    print(test_data[-1])if __name__ == '__main__':    data = loadData('watermelon3.0.txt')    test_data = data[3,:]    Bayes(data,test_data)    AODE(data,test_data)



0 0
原创粉丝点击