import numpy as np

def nb(x, X, Y, laplace=True): '朴素贝叶斯分类器' 'x 待预测样本' 'X 训练样本特征值' 'Y 训练样本标记' 'laplace 是否采用'拉普拉斯修正',默认为真'

C = list(set(Y))   # 所有可能标记
p = []             # 存储概率值

print('===============朴素贝叶斯分类器===============')

for c in C:
    Xc = [X[i] for i in range(len(Y)) if Y[i]==c]   # c类样本子集
    pc = (len(Xc)+laplace) / (len(X)+laplace*len(C))  # 类先验概率
    
    print('P(c=%s)=%.3f;

P(xi|c=%s)='%(c,pc,c), end='')

    logp = np.log(pc)      # 对数联合概率P(x,c)
    
    for i in range(len(x)):
        if type(x[i]) != type(X[0][i]):
            print('样本数据第%d个特征的数据类型与训练样本数据类型不符,无法预测!'%(i+1))
            return None
        
        if type(x[i]) == str:
            # 若为字符型特征,按离散取值处理
            Xci = [1 for xc in Xc if xc[i]==x[i]]   # c类子集中第i个特征与待预测样本一样的子集
            pxc = (len(Xci)+laplace) / (len(Xc) + laplace * len(set([x[i] for x in X])))  # pxc为类条件概率P(xi|c)
            print('%.3f'%pxc, end=',')
        
        elif type(x[i]) == float:
            # 若为浮点型特征,按高斯分布处理
            Xci = [xc[i] for xc in Xc]
            u = np.mean(Xci)
            sigma = np.std(Xci, ddof=1)
            pxc = 1 / np.sqrt(2 * np.pi) / sigma * np.exp(-(x[i]-u)**2 / 2 / sigma**2)
            print('%.3f(~N(%.3f,%.3f^2))'%(pxc,u,sigma), end=',')
        
        else:
            print('目前只能处理字符型和浮点型数据,对于其他类型有待扩展相应功能。')
            return None
        
        logp += np.log(pxc)
        p.append(logp)
    
    print(';

log(P(x,c=%s))=log(%.3E)=%.3f '%(c,np.exp(logp),logp))

predict = C[p.index(max(p))]
print('===============预测结果:%s类==============='%predict)
return predict
朴素贝叶斯分类器 Python 实现 - 代码详解与优化

原文地址: https://www.cveoy.top/t/topic/pj8W 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录