##【实验目的】
理解朴素贝叶斯算法原理,掌握朴素贝叶斯算法框架。
##【实验内容】
针对下表中的数据,编写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