笔记:朴素贝叶斯算法

朴素贝叶斯算法

贝叶斯原理作为数学基础,解决了概率论中“逆向概率”的问题,基于这一理论基础设计出了贝叶斯分类器,而朴素贝叶斯分类假设属性是相互独立的前提条件下所设计的贝叶斯分类器中的一种。

朴素贝叶斯的算法思路

朴素贝叶斯算法大致分为:

  1. 数据处理阶段:抽取特征属性,对数据进行分类标注,形成数据集,分类器的质量很大程度上由特征属性、特征属性划分及训练样本质量决定。

  2. 训练:计算每个类别在训练样本中的出现频率及每个特征属性划分对每个类别的条件概率,输入是特征属性和训练样本,输出是分类器。

  3. 测试:对模型进行测试。

朴素贝叶斯的优缺点

朴素贝叶斯的主要优点有:
  1. 朴素贝叶斯模型有稳定的分类效率。
  2. 对小规模的数据表现很好,能处理多分类任务,适合增量式训练。
  3. 对缺失数据不太敏感。
朴素贝叶斯的主要缺点有:
  1. 理论上,朴素贝叶斯模型与其他分类方法相比具有最小的误差率,在属性个数比较多或者属性之间相关性较大时,分类效果不好。在属性相关性较小时,朴素贝叶斯性能最为良好。对于这一点,有半朴素贝叶斯之类的算法通过考虑部分关联性适度改进。
  2. 需要先验概率,但先验概率很多时候取决于假设。
  3. 分类决策存在一定的错误率。
  4. 对输入数据的表达形式敏感。

朴素贝叶斯算法处理wine的实现

#需要的头文件
import math
import time
import numpy as np
from collections import Counter
from sklearn import preprocessing
from sklearn.model_selection import train_test_split 

#计算属于各类的概率
def calcProbDensity(meanLabel, stdLabel, test_X):
    numAttributes = len(test_X)
    MultiProbDensity = 1.0
    #print ("this is calcPD")
    # print meanLabel
    # print stdLabel
    for i in range(numAttributes):
        MultiProbDensity *= np.exp(-np.square(test_X[i] - meanLabel[i]) / (2.0 * np.square(stdLabel[i]))) / (np.sqrt(2.0 * math.pi) * stdLabel[i])
    #print (MultiProbDensity)
    return MultiProbDensity


 # 计算先验概率P(c)
def calcPriorProb(Y_train): 
    i, j = 0, 0
    global labelValue, classNum
    numSamples = Y_train.shape[0]  # 读取Y_train的第一维度的长度,比如多少行。
    labelValue = np.zeros((numSamples, 1))  # 用前i行来保存标签值
    # print "laV:",labelValue
    Y_train_counter = sum(Y_train.tolist(), [])  # 将Y_train转化为可哈希的数据结构
    cnt = Counter(Y_train_counter)  # 计算标签值的类别个数{1,2,3}及各类样例的个数
    # print "cnt",cnt
    for key in cnt:
        labelValue[i] = key
        i += 1
    classNum = i
    # print "laV2:",labelValue
    # print classNum
    Pc = np.zeros((classNum, 1))  # 不同类的先验概率
    eachLabelNum = np.zeros((classNum, 1))  # 每类样例数,多少行多少列,这里是classNum行1列
    for key in cnt:
        Pc[j] = float(cnt[key]) / numSamples #这里加float是为了避免/整除号使Pc=0
        eachLabelNum[j] = cnt[key]
        j += 1
    return labelValue, eachLabelNum, classNum, Pc


def trainBayes(X_train, Y_train):
    startTime = time.time()
    numTrainSamples, numAttributes = X_train.shape
    print ("trainBayes")
    # print numAttributes,numTrainSamples
    labelValue, eachLabelNum, classNum, Pc = calcPriorProb(Y_train)
    meanlabelX, stdlabelX = [], []  # 存放每一类样本在所有属性上取值的均值和方差
    for i in range(classNum):
        k = 0
        labelXMaxtrix = np.zeros((int(eachLabelNum[i]), numAttributes))
        for j in range(numTrainSamples):
            if Y_train[j] == labelValue[i]:
                labelXMaxtrix[k] = X_train[j, :]
                k += 1
        meanlabelX.append(np.mean(labelXMaxtrix, axis=0).tolist())  # 求该矩阵的列均值与无偏标准差,append至所有类
        stdlabelX.append(np.std(labelXMaxtrix, ddof=1, axis=0).tolist())
    meanlabelX = np.array(meanlabelX).reshape(classNum, numAttributes)
    stdlabelX = np.array(stdlabelX).reshape(classNum, numAttributes)
    print('---Train completed.Took %f s.' % ((time.time() - startTime)))
    return meanlabelX, stdlabelX, Pc


def predict(X_test, Y_test, meanlabelX, stdlabelX, Pc):
    numTestSamples = X_test.shape[0]
    matchCount = 0
    for m in range(X_test.shape[0]):
        x_test = X_test[m, :]  # 轮流取测试样本
        pred = np.zeros((classNum, 1))  # 对不同类的概率
        print ("Pc:", Pc)
        for i in range(classNum):
            pred[i] = calcProbDensity(meanlabelX[i, :], stdlabelX[i, :], x_test) * Pc[i]  # 计算属于各类的概率
            # print i
        print (pred)
        predict1 = labelValue[np.argmax(pred)]  # 取最大的类标签,np.argmax(pred)返回最大数据所在的index
        print (predict1, "####", Y_test[m])
        if predict1 == Y_test[m]:
            matchCount += 1
        print ("matchCount", matchCount, numTestSamples)
    accuracy = float(matchCount) / numTestSamples #这里加float是为了避免/整除号使accuracy=0
    # print accuracy
    return accuracy

if __name__ == '__main__':
    #载入葡萄酒数据集
    print('Step 1.下载数据')
    data = np.loadtxt("wine.dat",delimiter=',') 
    print("Step 2.拆分数据集(训练和测试)")
    x = data[:,0:13]
    y = data[:,13].reshape(178,1)
    #包含数据标准化
    X_train,X_test,Y_train,Y_test = train_test_split(x,y,test_size=0.4) #拆分数据集
    scaler = preprocessing.StandardScaler().fit(X_train)    #数据标准化
    X_train = scaler.transform(X_train)
    X_test = scaler.transform(X_test)
    
    #训练
    print("Step 3.训练")
    meanlabelX,stdlabelX,Pc = trainBayes(X_train,Y_train)
    
    #测试
    print("Step 4.测试")
    accuracy = predict(X_test,Y_test,meanlabelX,stdlabelX,Pc)
    
    #打印分类的准确度
    print("Step 5.打印分类的准确度")
    print(str(accuracy*100)+"%")

训练结果

训练结果

阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cy-landy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值