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/pj8X 著作权归作者所有。请勿转载和采集!

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