文章代码来自博客贝叶斯分类器,在这篇博客代码的基础上稍作修改
用朴素贝叶斯法实现对水果分类:
文件结构:
bayes_classfier. py
#贝叶斯分类器
datasets={'banala':{'long':400,'not_long':100,'sweet':350,'not_sweet':150,'yellow':450,'not_yellow':50},
'orange':{'long':0,'not_long':300,'sweet':150,'not_sweet':150,'yellow':300,'not_yellow':0},
'other_fruit':{'long':100,'not_long':100,'sweet':150,'not_sweet':50,'yellow':50,'not_yellow':150}}
def count_total(data):
#计算各种水果的总数
count={}
total=0
for fruit in data :
count[fruit]=data[fruit]['yellow']+data[fruit]['not_yellow']
total+=count[fruit]
return count,total
#{'banala': 500, 'orange': 300, 'other_fruit': 200} 1000
def cal_base_rates(data):
#计算各种水果的先验概率,不同水果的占比
categories,total=count_total(data)
cal_base_rates={}
for label in categories:
priori_prob=categories[label]/total
cal_base_rates[label]=priori_prob
return cal_base_rates
#{'banala': 0.5, 'orange': 0.3, 'other_fruit': 0.2}
def likelihold_prob(data):
#计算各个特征值在已知水果下的概率
count,_=count_total(data)
likelihold={}
for fruit in data:
attr_prob={}
for attr in data[fruit]:
#计算各个特征值在已知水果下的概率
attr_prob[attr]=data[fruit][attr]/count[fruit]
likelihold[fruit]=attr_prob
return likelihold
#{'banala': {'long': 0.8, 'not_long': 0.2, 'sweet': 0.7, 'not_sweet': 0.3, 'yellow': 0.9, 'not_yellow': 0.1}, 'orange': {'long': 0.0, 'not_long': 1.0, 'sweet': 0.5, 'not_sweet':
# 0.5, 'yellow': 1.0, 'not_yellow': 0.0}, 'other_fruit': {'long': 0.5, 'not_long': 0.5, 'sweet': 0.75, 'not_sweet': 0.25, 'yellow': 0.25, 'not_yellow': 0.75}}
def evidence_prob(data):
#计算特征的概率对分类结果的影响
attrs=list(data['banala'].keys())
count,total=count_total(data)
evidence_prob={}
for attr in attrs:
attr_total=0
for fruit in data:
attr_total+=data[fruit][attr]
evidence_prob[attr]=attr_total/total
return evidence_prob
#{'long': 0.5, 'not_long': 0.5, 'sweet': 0.65, 'not_sweet': 0.35, 'yellow': 0.8, 'not_yellow': 0.2}
class navie_bayes_classifier:
#初始化贝叶斯分类器,实例化时会调用__ini__函数
def __init__(self,data=datasets):
self._data=datasets
self._labels=[key for key in self._data.keys()] #不同的水果
self._priori_prob=cal_base_rates(self._data) #水果先验概率
self._likelihole_prob=likelihold_prob(self._data) #各个特征值下水果的概率
self._evidence_prob=evidence_prob(self._data) #各种特征的概率
def get_label(self,length,sweetness,color):
self._attrs=[length,sweetness,color]
res={}
for label in self._labels:
prob=self._priori_prob[label] #取某水果占比率
#print(label ,"的占比率:",prob)
for attr in self._attrs:
#单个水果的某个特征概率除以总的某个特征概率 再乘以某水果占比率
#print(self._likelihole_prob[label][attr])
#print(self._evidence_prob[attr])
#print(self._likelihole_prob[label][attr]/self._evidence_prob[attr])
prob*=self._likelihole_prob[label][attr]/self._evidence_prob[attr]
#print(prob)
res[label]=prob
return res
generate_attires. py
#随机产生测试数据集来测试贝叶斯分类器的预测能力
import random
def rondom_attr(pair):
#生成0~1之间的随机数
return pair[random.randint(0,1)]
def gen_attrs():
#特征值的取值集合
sets=[('long','not_long'),('sweet','not_sweet'),('yellow','not_yellow')]
test_datasets=[]
for i in range(3):
#使用map函数来生成一组特征值
test_datasets.append(list(map(rondom_attr,sets)))
return test_datasets
classfication. py
#使用贝叶斯分类器对测试结果进行分类
import operator
import bayes_classfier
import generate_attires
def main():
test_datasets=generate_attires.gen_attrs()
#print(test_datasets)
classfier =bayes_classfier.navie_bayes_classifier()
for data in test_datasets:
print("特征值:",end='\t')
print(data)
print("预测结果:",end='\t')
res=classfier.get_label(*data)#表示多参传入
print(res)#预测属于哪种水果的概率
print('水果类别:',end='\t')
#对后验概率排序,输出概率最大的标签
print(sorted(res.items(),key=operator.itemgetter(1),reverse=True)[0][0])
if __name__ =='__main__':
main()
效果展示: