首页 > 编程语言 >实验三:朴素贝叶斯算法实验

实验三:朴素贝叶斯算法实验

时间:2022-11-13 10:55:15浏览次数:40  
标签:posting propertyConditionalProbabilityNegative list 贝叶斯 浊响 算法 实验 硬滑 data

##【实验目的】

理解朴素贝叶斯算法原理,掌握朴素贝叶斯算法框架。

 

##【实验内容】

针对下表中的数据,编写python程序实现朴素贝叶斯算法(不使用sklearn包),对输入数据进行预测;
熟悉sklearn库中的朴素贝叶斯算法,使用sklearn包编写朴素贝叶斯算法程序,对输入数据进行预测;

 

##【实验报告要求】

对照实验内容,撰写实验过程、算法及测试结果;
代码规范化:命名规则、注释;
查阅文献,讨论朴素贝叶斯算法的应用场景。

 

色泽 根蒂 敲声 纹理 脐部 触感 好瓜
青绿 蜷缩 浊响 清晰 凹陷 碍滑
乌黑 蜷缩 沉闷 清晰 凹陷 碍滑
乌黑 蜷缩 浊响 清晰 凹陷 碍滑
青绿 蜷缩 沉闷 清晰 凹陷 碍滑
浅白 蜷缩 浊响 清晰 凹陷 碍滑
青绿 稍蜷 浊响 清晰 稍凹 软粘
乌黑 稍蜷 浊响 稍糊 稍凹 软粘
乌黑 稍蜷 浊响 清晰 稍凹 硬滑
乌黑 稍蜷 沉闷 稍糊 稍凹 硬滑
青绿 硬挺 清脆 清晰 平坦 软粘
浅白 硬挺 清脆 模糊 平坦 硬滑
浅白 蜷缩 浊响 模糊 平坦 软粘
青绿 稍蜷 浊响 稍糊 凹陷 硬滑
浅白 稍蜷 沉闷 稍糊 凹陷 硬滑
乌黑 稍蜷 浊响 清晰 稍凹 软粘
浅白 蜷缩 浊响 模糊 平坦 硬滑
青绿 蜷缩 沉闷 稍糊 稍凹 硬滑

 

一、针对下表中的数据,编写python程序实现朴素贝叶斯算法(不使用sklearn包),对输入数据进行预测:

import numpy as np
"""
    load_data_set():
    功能:载入数据集
    输入:无
    返回:
        posting_list:数据集;(西瓜数据集3.0 ; 西瓜书p84中间图表格)
        classes_list:各属性的类别
        property_list:各个属性的属性值集合列表
"""
def load_data_set():
    posting_list = [
        # 色泽    根蒂    敲声    纹理    脐部    触感    密度    含糖率  好瓜
        ['青绿', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '0.697', '0.460', 'YES'],
        ['乌黑', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', '0.774', '0.376', 'YES'],
        ['乌黑', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '0.634', '0.264', 'YES'],
        ['青绿', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', '0.608', '0.318', 'YES'],
        ['浅白', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '0.556', '0.215', 'YES'],
        ['青绿', '稍缩', '浊响', '清晰', '稍陷', '软粘', '0.403', '0.237', 'YES'],
        ['乌黑', '稍缩', '浊响', '清晰', '稍陷', '软粘', '0.481', '0.149', 'YES'],
        ['乌黑', '稍缩', '浊响', '清晰', '稍陷', '硬滑', '0.437', '0.211', 'YES'],
        ['乌黑', '稍缩', '沉闷', '稍糊', '稍凹', '硬滑', '0.666', '0.091', 'NO'],
        ['青绿', '硬挺', '清脆', '清晰', '平坦', '软粘', '0.243', '0.267', 'NO'],
        ['浅白', '硬挺', '清脆', '模糊', '平坦', '硬滑', '0.245', '0.057', 'NO'],
        ['浅白', '蜷缩', '浊响', '模糊', '平坦', '软粘', '0.343', '0.099', 'NO'],
        ['青绿', '稍缩', '浊响', '稍糊', '凹陷', '硬滑', '0.639', '0.161', 'NO'],
        ['浅白', '稍缩', '沉闷', '稍糊', '凹陷', '硬滑', '0.657', '0.198', 'NO'],
        ['乌黑', '稍缩', '浊响', '清晰', '稍凹', '软粘', '0.360', '0.370', 'NO'],
        ['浅白', '蜷缩', '浊响', '模糊', '稍陷', '硬滑', '0.593', '0.042', 'NO'],
        ['青绿', '蜷缩', '沉闷', '稍糊', '稍凹', '硬滑', '0.719', '0.103', 'NO']]

    # 各属性值对应的属性列表,未用到
    classes_list = ['色泽', '根蒂', '敲声', '纹理', '脐部', '触感', '密度', '含糖率', '好瓜']

    # 各个属性的属性值集合列表
    property_list = [
        '青绿', '乌黑', '浅白',
        '蜷缩', '稍缩', '硬挺',
        '浊响', '沉闷', '清脆',
        '清晰', '稍糊', '模糊',
        '凹陷', '稍陷', '稍凹',
        '硬滑', '软粘']
    return posting_list, property_list



"""
    getNums(posting_list,col,rows,nums):
    功能:取值函数,从数据集中取出某一列(密度或者含糖率样本)多行的值,返回一维数组,及其长度
    输入:posting_list:数据集;col:所取数据集的列号;rows:所取数据集的开始行号;nums:取的数据行数;
    输出:Nums:浮点型数据列表
"""


def getNums(posting_list, col, rows, nums):
    Nums = [0] * nums
    for n in range(0, nums):
        Nums[n] = float(posting_list[rows + n][col])
    return Nums


"""
    train_naive_bayes(posting_list,property_list):
    功能:训练数据,即计算数据集的类条件概率,类先验概率
    输入:posting_list:数据集;property_list:各个属性的属性值集合构成的列表
    输出:propertyConditionalProbabilityPositive:正样本(好瓜)类条件概率
          propertyConditionalProbabilityNegative:负样本类条件概率
"""


def train_naive_bayes(posting_list, property_list):
    # 总的样本数目
    trainNum = len(posting_list)
    # 正样本数目
    pSampleNum = 0
    for sample in posting_list:
        if sample[-1] == 'YES':
            pSampleNum += 1
    # 先验概率
    prioClass = pSampleNum / trainNum
    # 存储正样本类条件概率
    propertyConditionalProbabilityPositive = []
    propertyConditionalProbabilityNegative = []

    # 通过遍历各个属性的属性值集合列表来求其属于 正/负样本的类条件概率,property_list含所有的属性值(无含糖率和密度)
    for propertyy in property_list:
        # 拉普拉斯平滑,防止为0,
        # 触感属性只有两个值:硬滑和软粘;拉普拉斯平滑时,该属性正/负样本数目即分母加2,其他属性正/负样本数目即其分母加3
        if (propertyy == "硬滑") or (propertyy == "软粘"):
            pSampleNumLap = pSampleNum + 2
            nSampleNumLap = trainNum - pSampleNum + 2
        else:
            pSampleNumLap = pSampleNum + 3
            nSampleNumLap = trainNum - pSampleNum + 3

        # 拉普拉斯平滑,初始化为1
        posNumPropertyPositive = 1
        negNumPropertyPositive = 1

        # 遍历数据集的每一个样本
        for rows in range(0, len(posting_list)):
            # 如果此时的属性值在样本中
            if propertyy in posting_list[rows]:
                # 如果该样本为正样本
                if posting_list[rows][-1] == 'YES':
                    # 计算此属性值的正样本数目
                    posNumPropertyPositive += 1

                else:
                    # 计算此属性值的负样本数目
                    negNumPropertyPositive += 1
        # 计算此属性值的正/负类条件概率
        propertyConditionalProbabilityPositive.append(posNumPropertyPositive / pSampleNumLap)
        propertyConditionalProbabilityNegative.append(negNumPropertyPositive / nSampleNumLap)

    # 最后计算正/负样本的 密度和含糖率 的均值和标准差,添加到类条件概率的后面。为了后续通过概率密度函数计算概率
    propertyConditionalProbabilityPositive.append(np.mean(getNums(posting_list, 6, 0, pSampleNum)))
    propertyConditionalProbabilityPositive.append(np.var(getNums(posting_list, 6, 0, pSampleNum)) ** (1 / 2))

    propertyConditionalProbabilityNegative.append(np.mean(getNums(posting_list, 6, pSampleNum, trainNum - pSampleNum)))
    propertyConditionalProbabilityNegative.append(
        np.var(getNums(posting_list, 6, pSampleNum, trainNum - pSampleNum)) ** (1 / 2))

    propertyConditionalProbabilityPositive.append(np.mean(getNums(posting_list, 7, 0, pSampleNum)))
    propertyConditionalProbabilityPositive.append(np.var(getNums(posting_list, 7, 0, pSampleNum)) ** (1 / 2))

    propertyConditionalProbabilityNegative.append(np.mean(getNums(posting_list, 7, pSampleNum, trainNum - pSampleNum)))
    propertyConditionalProbabilityNegative.append(
        np.var(getNums(posting_list, 7, pSampleNum, trainNum - pSampleNum)) ** (1 / 2))
    # 方差标准差装进类条件概率列表中,大致如下:
    # [青绿的正类条件概率,乌黑的正类条件概率,浅白的正类条件概率,蜷缩的正类条件概率,'稍缩的正类条件概率,硬挺的正类条件概率,
    #  浊响的正类条件概率,沉闷的正类条件概率,清脆的正类条件概率,清晰的正类条件概率,稍糊的正类条件概率,模糊的正类条件概率,
    #  凹陷的正类条件概率,稍陷的正类条件概率,稍凹的正类条件概率,硬滑的正类条件概率,软粘的正类条件概率,
    #  正类别的密度的均值,正类别的密度方差,
    #  正类别的含糖率均值,正类别的含糖率方差]
    return propertyConditionalProbabilityPositive, propertyConditionalProbabilityNegative


"""
    classify_naive_bayes(data,propertyConditionalProbabilityPositive,property_list,propertyConditionalProbabilityNegative):
    功能:求正负类别的概率,返回1或者0, 1表示为正样本
    输入:data:想要测试的数据,格式见底部说明。propertyConditionalProbabilityPositive正类条件概率;propertyConditionalProbabilityNegative负类条件概率
    输出:返回1或者0;其中1代表正样本(好瓜),0代表负样本
"""


def classify_naive_bayes(data, propertyConditionalProbabilityPositive, property_list,
                         propertyConditionalProbabilityNegative):
    probabilityPos = 0
    probabilityNeg = 0
    # 遍历测试数据的属性, 其密度和含糖率不在循环中计算
    for propertyData in data[:-1]:
        if propertyData in property_list:
            # 取该属性的下标
            index = property_list.index(propertyData)
            # 取该属性值的正/负样本类条件概率 值,并取对数,然后加起来来求正负样本各自的概率。 取对数为了防止下溢,将乘法转为加法计算。
            probabilityPos += np.log(propertyConditionalProbabilityPositive[index])
            probabilityNeg += np.log(propertyConditionalProbabilityNegative[index])

    # 对于连续属性密度和含糖率,通过概率密度函数计算其属于正/负样本的概率。
    probabilityPos += np.log(((2 * np.pi) ** (-1 / 2) * propertyConditionalProbabilityPositive[-4]) ** (-1)) + (
                -1 / 2) * ((float(data[-2]) - propertyConditionalProbabilityPositive[-4]) ** 2) / (
                                  propertyConditionalProbabilityPositive[-3] ** 2)
    probabilityPos += np.log(((2 * np.pi) ** (-1 / 2) * propertyConditionalProbabilityPositive[-2]) ** (-1)) + (
                -1 / 2) * ((float(data[-1]) - propertyConditionalProbabilityPositive[-2]) ** 2) / (
                                  propertyConditionalProbabilityPositive[-1] ** 2)
    probabilityNeg += np.log(((2 * np.pi) ** (-1 / 2) * propertyConditionalProbabilityNegative[-4]) ** (-1)) + (
                -1 / 2) * ((float(data[-2]) - propertyConditionalProbabilityNegative[-4]) ** 2) / (
                                  propertyConditionalProbabilityNegative[-3] ** 2)
    probabilityNeg += np.log(((2 * np.pi) ** (-1 / 2) * propertyConditionalProbabilityNegative[-2]) ** (-1)) + (
                -1 / 2) * ((float(data[-1]) - propertyConditionalProbabilityNegative[-2]) ** 2) / (
                                  propertyConditionalProbabilityNegative[-1] ** 2)

    # 对算出来的正负概率进行比较,大的为正样本
    if probabilityPos > probabilityNeg:
        return True
    else:
        return False


if __name__ == "__main__":
    # 载入数据
    posting_list, property_list = load_data_set()
    # 预训练
    propertyConditionalProbabilityPositive, propertyConditionalProbabilityNegative = train_naive_bayes(posting_list,
                                                                                                       property_list)
    # 朴素贝叶斯求类别
    # 输入数据集中前两个负样本例子
    data = ['青绿', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '0.697', '0.460']
    result = classify_naive_bayes(data, propertyConditionalProbabilityPositive, property_list,
                                  propertyConditionalProbabilityNegative)
    print("data:{}".format(data))
    print('预测负样本集: {}'.format(result))

    data = ['乌黑', '蜷缩', '沉闷', '清晰', '凹陷', '硬滑', '0.774', '0.376']
    print("data:{}".format(data))
    result = classify_naive_bayes(data, propertyConditionalProbabilityPositive, property_list,
                                  propertyConditionalProbabilityNegative)
    print('预测负样本集: {}'.format(result))

    # 输入数据集中前两个负样本例子
    data = ['乌黑', '稍缩', '沉闷', '稍糊', '稍凹', '硬滑', '0.666', '0.091']
    result = classify_naive_bayes(data, propertyConditionalProbabilityPositive, property_list,
                                  propertyConditionalProbabilityNegative)
    print("data:{}".format(data))
    print('预测负样本集 : {}'.format(result))

    data = ['青绿', '硬挺', '清脆', '清晰', '平坦', '软粘', '0.243', '0.267']
    result = classify_naive_bayes(data, propertyConditionalProbabilityPositive, property_list,
                                  propertyConditionalProbabilityNegative)
    print("data:{}".format(data))
    print('预测负样本集:{}'.format(result))

    # 西瓜书p151 列子
    data = ['青绿', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', '0.697', '0.460']
    result = classify_naive_bayes(data, propertyConditionalProbabilityPositive, property_list,
                                  propertyConditionalProbabilityNegative)
    print("data:{}".format(data))
    print('预测结果:{}'.format(result))

 

#预测结果:

 

二、熟悉sklearn库中的朴素贝叶斯算法,使用sklearn包编写朴素贝叶斯算法程序,对输入数据进行预测:

import warnings
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import BernoulliNB
import pandas as pd
warnings.filterwarnings('ignore')
def load_data_set():
    # 西瓜数据集3.0讲数据数值化string-float32
    posting_list = [
        # 色泽    根蒂    敲声    纹理    脐部    触感    密度    含糖率  好瓜
        [0, 0, 0, 0, 0, 0, '0.697', '0.460', 1],
        [1, 0, 1, 0, 0, 0, '0.774', '0.376', 1],
        [1, 0, 0, 0, 0, 0, '0.634', '0.264', 1],
        [0, 0, 1, 0, 0, 0, '0.608', '0.318', 1],
        [2, 0, 0, 0, 0, 0, '0.556', '0.215', 1],
        [0, 1, 0, 0, 1, 1, '0.403', '0.237', 1],
        [1, 1, 0, 0, 1, 1, '0.481', '0.149', 1],
        [1, 1, 0, 0, 1, 0, '0.437', '0.211', 1],
        [1, 1, 1, 1, 2, 0, '0.666', '0.091', 0],
        [0, 2, 2, 0, 3, 1, '0.243', '0.267', 0],
        [2, 2, 2, 2, 3, 0, '0.245', '0.057', 0],
        [2, 0, 0, 2, 3, 1, '0.343', '0.099', 0],
        [0,1, 0, 1, 0, 0, '0.639', '0.161', 0],
        [2, 1, 1, 1, 0, 0, '0.657', '0.198', 0],
        [1, 1, 0, 0, 2, 1, '0.360', '0.370', 0],
        [2, 0, 0, 2, 1, 0, '0.593', '0.042', 0],
        [0, 0, 1, 1, 2, 0, '0.719', '0.103', 0]]

    # 各属性值对应的属性列表,未用到
    classes_list = ['色泽', '根蒂', '敲声', '纹理', '脐部', '触感', '密度', '含糖率', '好瓜']

    # 各个属性的属性值集合列表
    property_list = [
        '青绿', '乌黑', '浅白',
        '蜷缩', '稍缩', '硬挺',
        0, 1, 2,
        0, 1, 2,
        0, 1, 2,
        0, 1]
    return posting_list, property_list

if __name__ == '__main__':
    data,result = load_data_set()
    data1 = np.array(data,dtype='float32')
    target = np.array([0,1,2,3,4,5,6,7,8],dtype='float32')
    print("data:{},result:{},type:{}".format(data1,result,data1.dtype))
    Xtrain, Xtest, Ytrain, Ytest = train_test_split(data1.T, target, test_size=0.3, random_state=420)
    clf = BernoulliNB()
    clf.fit(data1.T,target)
    # 查看分数
    acc_score = clf.score(Xtest, Ytest)  # 返回预测的精确性
    # 查看预测结果
    Y_pred = clf.predict(Xtest)

 

#预测结果:

 

#朴素贝叶斯公式:

 

 

标签:posting,propertyConditionalProbabilityNegative,list,贝叶斯,浊响,算法,实验,硬滑,data
From: https://www.cnblogs.com/duyidan/p/16883468.html

相关文章

  • 实验一 阅读并思考
    请阅读北航陈彦吉同学的这篇博客中的各参考资料,并回答如下问题:(1)回顾你过去将近3年的学习经历当初你报考的时候,是真正喜欢计算机这个专业吗?答:是的,正是因为感兴趣才......
  • 分组加密算法的CPA安全性证明
    分组加密算法的CPA安全性证明CPA安全模型构造分组加密算法令\(F\)是伪随机函数,定义一个消息长度为\(n\)的对称加密方案如下:Gen:输入:安全参数\(n\),输出\(k\),\(k\)是一......
  • [回溯算法]leetcode40. 组合总和 II(c实现)
    题目给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中......
  • 每日算法题之买卖股票的最好时机(一)
    买卖股票的最好时机(一)描述假设你有一个数组prices,长度为n,其中prices[i]是股票在第i天的价格,请根据这个价格数组,返回买卖股票能获得的最大收益1.你可以买入一次股票和......
  • 软件工程——实验二-结对编程
    现有一新建办公大厦,共有21层,共有四部电梯,所有电梯基本参数如下表所示,其使用规定如下:①楼层号为0~20,其中0号为地下一层②有楼层限制的电梯不在相应楼层停靠,如单双层......
  • IP核之MMCM/PLL实验
    1)实验平台:正点原子达芬奇FPGA开发板2)摘自【正点原子】达芬奇之FPGA开发指南3)购买链接:https://detail.tmall.com/item.htm?id=6243354965054)全套实验源码+手册+视频下......
  • 实验6:开源控制器实践——RYU
    (一)基本要求1.搭建下图所示SDN拓扑,协议使用OpenFlow1.0,并连接Ryu控制器。 a.建立拓扑sudomn--topo=single,3--mac--controller=remote,ip=127.0.0.1,port=8080......
  • 实验5:开源控制器实践——POX
    一.基础要求1.使用命令创建拓扑:sudomn--topo=single,3--mac--controller=remote,ip=127.0.0.1,port=6633--switchovsk,protocols=OpenFlow102.Hub模块1)开启pox./p......
  • 朴素贝叶斯实验
    【实验目的】理解朴素贝叶斯算法原理,掌握朴素贝叶斯算法框架。【实验内容】1.针对下表中的数据,编写python程序实现朴素贝叶斯算法(不使用sklearn包),对输入数据进行预测;......
  • HMM算法python实现
    基础介绍,后5项为基础5元素Q=['q0','q1','q2','q3']#状态集合States,共N种状态V=['v0','v1']#观测集合Observatio......