实验三:朴素贝叶斯算法实验
实验三:朴素贝叶斯算法实验
【实验目的】
理解朴素贝叶斯算法原理,掌握朴素贝叶斯算法框架。
【实验内容】
- 针对下表中的数据,编写python程序实现朴素贝叶斯算法(不使用sklearn包),对输入数据进行预测;
- 熟悉sklearn库中的朴素贝叶斯算法,使用sklearn包编写朴素贝叶斯算法程序,对输入数据进行预测;
【实验报告要求】
- 对照实验内容,撰写实验过程、算法及测试结果;
- 代码规范化:命名规则、注释;
- 查阅文献,讨论朴素贝叶斯算法的应用场景。
色泽 | 根蒂 | 敲声 | 纹理 | 脐部 | 触感 | 好瓜 |
---|---|---|---|---|---|---|
青绿 | 蜷缩 | 浊响 | 清晰 | 凹陷 | 碍滑 | 是 |
乌黑 | 蜷缩 | 沉闷 | 清晰 | 凹陷 | 碍滑 | 是 |
乌黑 | 蜷缩 | 浊响 | 清晰 | 凹陷 | 碍滑 | 是 |
青绿 | 蜷缩 | 沉闷 | 清晰 | 凹陷 | 碍滑 | 是 |
浅白 | 蜷缩 | 浊响 | 清晰 | 凹陷 | 碍滑 | 是 |
青绿 | 稍蜷 | 浊响 | 清晰 | 稍凹 | 软粘 | 是 |
乌黑 | 稍蜷 | 浊响 | 稍糊 | 稍凹 | 软粘 | 是 |
乌黑 | 稍蜷 | 浊响 | 清晰 | 稍凹 | 硬滑 | 是 |
乌黑 | 稍蜷 | 沉闷 | 稍糊 | 稍凹 | 硬滑 | 否 |
青绿 | 硬挺 | 清脆 | 清晰 | 平坦 | 软粘 | 否 |
浅白 | 硬挺 | 清脆 | 模糊 | 平坦 | 硬滑 | 否 |
浅白 | 蜷缩 | 浊响 | 模糊 | 平坦 | 软粘 | 否 |
青绿 | 稍蜷 | 浊响 | 稍糊 | 凹陷 | 硬滑 | 否 |
浅白 | 稍蜷 | 沉闷 | 稍糊 | 凹陷 | 硬滑 | 否 |
乌黑 | 稍蜷 | 浊响 | 清晰 | 稍凹 | 软粘 | 否 |
浅白 | 蜷缩 | 浊响 | 模糊 | 平坦 | 硬滑 | 否 |
青绿 | 蜷缩 | 沉闷 | 稍糊 | 稍凹 | 硬滑 | 否 |
1.编写python程序实现朴素贝叶斯算法(不使用sklearn包):
#输入数据集
datasets=[['青绿','蜷缩','浊响','清晰','凹陷','碍滑','是'],
['乌黑','蜷缩','沉闷','清晰','凹陷','碍滑','是'],
['乌黑','蜷缩','浊响','清晰','凹陷','碍滑','是'],
['青绿','蜷缩','沉闷','清晰','凹陷','碍滑','是'],
['浅白','蜷缩','浊响','清晰','凹陷','碍滑','是'],
['青绿','稍蜷','浊响','清晰','稍凹','软粘','是'],
['乌黑','稍蜷','浊响','稍糊','稍凹','软粘','是'],
['乌黑','稍蜷','浊响','清晰','稍凹','硬滑','是'],
['乌黑','稍蜷','沉闷','稍糊','稍凹','硬滑','否'],
['青绿','硬挺','清脆','清晰','平坦','软粘','否'],
['浅白','硬挺','清脆','模糊','平坦','硬滑','否'],
['浅白','蜷缩','浊响','模糊','平坦','软粘','否'],
['青绿','稍蜷','浊响','稍糊','凹陷','硬滑','否'],
['浅白','稍蜷','沉闷','稍糊','凹陷','硬滑','否'],
['乌黑','稍蜷','浊响','清晰','稍凹','软粘','否'],
['浅白','蜷缩','浊响','模糊','平坦','硬滑','否'],
['青绿','蜷缩','沉闷','稍糊','稍凹','硬滑','否']
]
#数据集标题
labels=['色泽','根蒂','敲声','纹理','脐部','触感','好瓜']
import pandas as pd
#将数据集转换为DataFrame数据
data=pd.DataFrame(datasets,columns=labels)
data
# data为样本数据和分类结果;cls_val是分类字符,是/否
#求先验概率函数
def prob1(data,cls_val):
cnt=0.0
for index,row in data.iterrows():
if row[-1]==cls_val:
cnt+=1
return cnt/len(data)
# 统计每种属性的取值可能,拉普拉斯修正用
def prob2(data,cls_val):
cnt=0.0
for index,row in data.iterrows():
if row[-1]==cls_val:
cnt+=1
return (cnt+1)/(len(data)+len(set(data['好瓜'])))
# 计算条件概率
# data为样本数据和分类结果;cls_val是分类字符,是/否;attr_index是属性的序号;attr_val是属性的取值;s是属性的特征数目
def conditionp1(data,cls_val,attr_index,attr_val):
cnt1=0.0
cnt2=0.0
for index,row in data.iterrows():
if row[-1]==cls_val:
cnt1+=1
if row[attr_index]==attr_val:
cnt2+=1
return cnt2/cnt1
# 统计每种属性的取值可能,拉普拉斯修正用
def conditionp2(data,cls_val,attr_index,attr_val,s):
cnt1=0.0
cnt2=0.0
for index,row in data.iterrows():
if row[-1]==cls_val:
cnt1+=1
if row[attr_index]==attr_val:
cnt2+=1
return (cnt2+1)/(cnt1+s)
# 利用后验概率计算先验概率
# data为样本数据和分类结果;testlist是新样本数据列表;cls_y、cls_n是分类字符,是/否;s是属性的特征数目
def nb(data,testlist,cls_y,cls_n):
py=prob1(data,cls_y)
pn=prob1(data,cls_n)
for i,val in enumerate(testlist):
py*=conditionp1(data,cls_y,i,val)
pn*=conditionp1(data,cls_n,i,val)
if (py==0) or (pn==0):
py=prob2(data,cls_y)
pn=prob2(data,cls_n)
for i,val in enumerate(testlist):
s=len(set(data[data.columns[i]]))
py*=conditionp2(data,cls_y,i,val,s)
pn*=conditionp2(data,cls_n,i,val,s)
if py>pn:
result=cls_y
else:
result=cls_n
return {cls_y:py,cls_n:pn,'好瓜':result}
#测试结果
tsvec = ['青绿','蜷缩','沉闷','稍糊','稍凹','硬滑']
prob = nb(data,tsvec,'是','否')
print("测试结果:",prob)
2.使用sklearn包编写朴素贝叶斯算法程序:
dataset=[['0','0','0','0','0','0','1'],
['1','0','1','0','0','0','1'],
['1','0','0','0','0','0','1'],
['0','0','1','0','0','0','1'],
['2','0','0','0','0','0','1'],
['0','1','0','0','1','1','1'],
['1','1','0','1','1','1','1'],
['1','1','0','0','1','2','1'],
['1','1','1','1','1','2','0'],
['0','2','2','0','2','1','0'],
['2','2','2','2','2','2','0'],
['2','0','0','2','2','1','0'],
['0','1','0','1','0','2','0'],
['2','1','1','1','0','2','0'],
['1','1','0','0','1','1','0'],
['2','0','0','2','2','2','0'],
['0','0','1','1','1','2','0']
]
#青绿:0 乌黑:1 浅白:2
# 蜷缩 0 稍蜷 1 硬挺 2
# 浊响 0 沉闷 1 清脆 2
# 清晰 0 稍糊 1 模糊 2
# 凹陷 0 稍凹 1 平坦 2
# 碍滑 0 软粘 1 硬滑 2
# 是 1 否 0
labels=['色泽','根蒂','敲声','纹理','脐部','触感','好瓜']
# 样本数据
import pandas as pd
# 将数据集转换为DataFrame数据
data1 = pd.DataFrame(datasets1, columns=labels)
from sklearn.model_selection import train_test_split # 将原始数据划分为数据集与测试集两个部分
from sklearn.naive_bayes import BernoulliNB
X = data1.iloc[:, :-1]
y = data1.iloc[:, -1]
# X_train训练样本, X_test测试样本, y_train训练样本分类, y_test测试样本分类
# X样本数据分类集, y分类结果集, test_size=3测试样本数量,random_state=1 生成数据随机
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=3, random_state=None)
clf = BernoulliNB()
clf.fit(X, y)
# 返回预测的精确性
clf.score(X_test, y_test)
# 查看预测结果
clf.predict(X_test)
# 输入测试样本 ['青绿','蜷缩','浊响','清晰','凹陷','硬滑']
tt = ['0', '0', '0', '0', '0', '2']
tt = pd.DataFrame(tt)
test = tt.T
3.查阅文献,讨论朴素贝叶斯算法的应用场景:
朴素贝叶斯算法的优点:
- 对待预测样本进行预测,过程简单速度快(想想邮件分类的问题,预测就是分词后进行概率乘积,在log域直接做加法更快)。
- 对于多分类问题也同样很有效,复杂度也不会有大程度上升。
- 在分布独立这个假设成立的情况下,贝叶斯分类器效果奇好,会略胜于逻辑回归,同时我们需要的样本量也更少一点。
- 对于类别类的输入特征变量,效果非常好。对于数值型变量特征,我们是默认它符合正态分布的。
朴素贝叶斯算法的缺点:
- 对于测试集中的一个类别变量特征,如果在训练集里没见过,直接算的话概率就是0了,预测功能就失效了。当然,我们前面的文章提过我们有一种技术叫做『平滑』操作,可以缓解这个问题,最常见的平滑技术是拉普拉斯估测。
- 那个…咳咳,朴素贝叶斯算出的概率结果,比较大小还凑合,实际物理含义…恩,别太当真。
- 朴素贝叶斯有分布独立的假设前提,而现实生活中这些predictor很难是完全独立的。
朴素贝叶斯算法的应用场景:
- 文本分类/垃圾文本过滤/情感判别:这大概会朴素贝叶斯应用做多的地方了,即使在现在这种分类器层出不穷的年代,在文本分类场景中,朴素贝叶斯依旧坚挺地占据着一席之地。原因嘛,大家知道的,因为多分类很简单,同时在文本数据中,分布独立这个假设基本是成立的。而垃圾文本过滤(比如垃圾邮件识别)和情感分析(微博上的褒贬情绪)用朴素贝叶斯也通常能取得很好的效果。
- 多分类实时预测:这个是不是不能叫做场景?对于文本相关的多分类实时预测,它因为上面提到的优点,被广泛应用,简单又高效。
- 推荐系统:是的,你没听错,是用在推荐系统里!!朴素贝叶斯和协同过滤是一对好搭档,协同过滤是强相关性,但是泛化能力略弱,朴素贝叶斯和协同过滤一起,能增强推荐的覆盖度和效果。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律