朴素贝叶斯(Naive Bayes)详细计算公式及代码实现

一. 朴素贝叶斯知识点
1.1 概念

  贝叶斯方法是以贝叶斯原理为基础,使用概率统计的知识对样本数据集进行分类。
  贝叶斯方法的特点是结合先验概率和后验概率,既避免了只使用先验概率的主观偏见,也避免了单独使用样本信息的过拟合现象。
  朴素贝叶斯方法是在贝叶斯算法的基础上进行了相应的简化,即假定给定目标值时属性之间相互条件独立。

1.2 优缺点

  优点:算法的逻辑性十分简单,并且算法较为稳定
     算法的健壮性比较好
  缺点:属性独立性的条件同时也是朴素贝叶斯分类器的不足之处。
     因为数据集的属性之间往往都存在着相互关联,会导致分类的效果大大降低。

1.3 应用

  文本分类,垃圾邮件分类,信用评估
  图像识别等方向

二.计算方法
2.1 计算公式

在这里插入图片描述
  在这里插入图片描述

2.2 例题

题目:
在这里插入图片描述
求:Outlook=Overcast,Temparature=Hot,Humidity=80,Wind=True时是否打球?
在这里插入图片描述

三.代码实现

数据集下载:data.txt

import operator
import math
import numpy as np

def readdata(filename):
    label = []  # 属性标签
    data = []  # 数据集
    i = 0
    with open(filename, 'r') as f:
        while True:
            line = f.readline()
            line = line.strip()
            listFromLine = line.split()
            if not line:
                break
            if i == 0:
                label = [listFromLine[1], listFromLine[2], listFromLine[3], listFromLine[4], listFromLine[5]]
            else:
                data.append(
                    [listFromLine[1], listFromLine[2], float(listFromLine[3]), listFromLine[4], listFromLine[5]])
            i += 1
    data1 = []
    data2 = []
    x = data[0][-1]
    for j in data:
        if j[-1] == x:
            data1.append(j)
        else:
            data2.append(j)

    return data, label


def beyes(Data, Label, Test):
    # 统计每种属性的取值可能,拉普拉斯修正用
    number = np.zeros(len(Label))
    for i in range(len(Label)):
        poss = []
        for j in range(len(Data)):
            if j == 0:
                poss.append(Data[j][i])
                number[i] += 1
            elif Data[j][i] not in poss:
                poss.append(Data[j][i])
                number[i] += 1
    # 结果的各个种类数
    kindnum = np.zeros(int(number[-1]))
    kind = []
    kind.append(Data[0][-1])
    for j in Data:
        if j[-1] == kind[0]:
            kindnum[0] += 1
        else:
            kindnum[1] += 1
            if j[-1] not in kind:
                kind.append(j[-1])
    # 计算概率
    probability = np.ones(int(number[-1]))
    for i in range(len(Label) - 1):
        if i == 2:
            aall1 = 0
            ssum1 = 0
            aall2 = 0
            ssum2 = 0
            for j in Data:
                if j[-1] == kind[0]:
                    aall1 += j[i]
                else:
                    aall2 += j[i]
            aver1 = aall1 / kindnum[0]  # 平均数
            aver2 = aall2 / kindnum[1]
            for j in Data:
                if j[-1] == kind[0]:
                    ssum1 += (j[i] - aver1) ** 2
                else:
                    ssum2 += (j[i] - aver2) ** 2
            s1 = ssum1 / kindnum[0]  # 方差
            s2 = ssum2 / kindnum[1]
            pro1 = np.exp(-(Test[i] - aver1) ** 2 / (2 * s1)) / (math.sqrt(2 * math.pi * s1))
            pro2 = np.exp(-(Test[i] - aver2) ** 2 / (2 * s2)) / (math.sqrt(2 * math.pi * s2))
            probability[0] = probability[0] * pro1
            probability[1] = probability[1] * pro2
        else:
            poss = []
            n1 = 0
            n2 = 0
            for j in Data:
                if j[i] == Test[i]:
                    if j[-1] == kind[0]:
                        n1 += 1
                    else:
                        n2 += 1
            probability[0] = probability[0] * (n1 + 1) / (kindnum[0] + number[i])
            probability[1] = probability[1] * (n2 + 1) / (kindnum[1] + number[i])

    print('--------------------------------------')
    print('Test=', Test, '是否打球的类别是', kind[0], '的概率是', probability[0])
    print('Test=', Test, '是否打球的类别是', kind[1], '的概率是', probability[1])
    if probability[0] > probability[1]:
        print('所以估计Test=', Test, '是否打球的结果是', kind[0])
    else:
        print('所以估计Test=', Test, '是否打球的结果是', kind[1])
    print('--------------------------------------')

if __name__ == '__main__':
    # 读取数据集和属性标签
    Data, Label = readdata('data.txt')
    Test = ['Overcast', 'Hot', 80.0, 'TRUE']
    beyes(Data, Label, Test)

相关运行结果:
在这里插入图片描述

四.总结

  文章主要介绍了朴素贝叶斯进行分类的相关计算及代码实现。从上面可以看到,朴素贝叶斯在计算时会将每种可能的情况都会考虑到,然后根据计算出来的概率大小决定最后的结果。可以将该方法应用于表面肌电信号相关动作是别上。🌹🌹

  • 2
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,以下是基于Weka 3.8.6平台的朴素叶斯分类代码,不使用平台自带的NaiveBayes()函数,自我实现: ```java import weka.core.Instance; import weka.core.Instances; import weka.core.converters.ConverterUtils.DataSource; public class NaiveBayesClassifier { public static void main(String[] args) throws Exception { // 加载数据集 DataSource source = new DataSource("path/to/your/dataset.arff"); Instances dataset = source.getDataSet(); // 设置类别属性 if (dataset.classIndex() == -1) dataset.setClassIndex(dataset.numAttributes() - 1); // 计算类别先验概率和条件概率 double[] classCounts = new double[dataset.numClasses()]; double[][][] condProbs = new double[dataset.numAttributes()-1][dataset.numClasses()][]; for (int i = 0; i < dataset.numInstances(); i++) { Instance instance = dataset.instance(i); int classValue = (int)instance.classValue(); classCounts[classValue]++; for (int j = 0; j < dataset.numAttributes()-1; j++) { int attrValue = (int)instance.value(j); if (condProbs[j][classValue] == null) { condProbs[j][classValue] = new double[dataset.attribute(j).numValues()]; } condProbs[j][classValue][attrValue]++; } } for (int i = 0; i < dataset.numClasses(); i++) { for (int j = 0; j < dataset.numAttributes()-1; j++) { if (condProbs[j][i] != null) { for (int k = 0; k < condProbs[j][i].length; k++) { condProbs[j][i][k] = (condProbs[j][i][k] + 1) / (classCounts[i] + dataset.attribute(j).numValues()); } } } } // 对测试数据进行分类 for (int i = 0; i < dataset.numInstances(); i++) { Instance instance = dataset.instance(i); int predictClass = -1; double maxProb = Double.NEGATIVE_INFINITY; for (int j = 0; j < dataset.numClasses(); j++) { double prob = Math.log(classCounts[j]); for (int k = 0; k < dataset.numAttributes()-1; k++) { int attrValue = (int)instance.value(k); if (condProbs[k][j] != null) { prob += Math.log(condProbs[k][j][attrValue]); } } if (prob > maxProb) { maxProb = prob; predictClass = j; } } System.out.println("Instance " + i + " is classified as class " + predictClass); } } } ``` 其中,"path/to/your/dataset.arff"需要替换成你自己的数据集路径。这段代码首先计算了类别先验概率和条件概率,然后对每个测试实例进行分类,并输出分类结果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值