import numpy as np
import pandas as pd
data_list = [
['青绿', '蜷缩', '浊响', '清晰', '凹陷', '碍滑', 'YES'],
['乌黑', '蜷缩', '沉闷', '清晰', '凹陷', '碍滑', 'YES'],
['乌黑', '蜷缩', '浊响', '清晰', '凹陷', '碍滑', 'YES'],
['青绿', '蜷缩', '沉闷', '清晰', '凹陷', '碍滑', 'YES'],
['浅白', '蜷缩', '浊响', '清晰', '凹陷', '碍滑', 'YES'],
['青绿', '稍缩', '浊响', '清晰', '稍凹', '软粘', 'YES'],
['乌黑', '稍缩', '浊响', '清晰', '稍凹', '软粘', 'YES'],
['乌黑', '稍缩', '浊响', '清晰', '稍凹', '硬滑', 'YES'],
['乌黑', '稍缩', '沉闷', '稍糊', '稍凹', '硬滑', 'NO'],
['青绿', '硬挺', '清脆', '清晰', '平坦', '软粘', 'NO'],
['浅白', '硬挺', '清脆', '模糊', '平坦', '硬滑', 'NO'],
['浅白', '蜷缩', '浊响', '模糊', '平坦', '软粘', 'NO'],
['青绿', '稍缩', '浊响', '稍糊', '凹陷', '硬滑', 'NO'],
['浅白', '稍缩', '沉闷', '稍糊', '凹陷', '硬滑', 'NO'],
['乌黑', '稍缩', '浊响', '清晰', '稍凹', '软粘', 'NO'],
['浅白', '蜷缩', '浊响', '模糊', '稍凹', '硬滑', 'NO'],
['青绿', '蜷缩', '沉闷', '稍糊', '稍凹', '硬滑', 'NO']
]
classes_list = ['色泽','根蒂','敲声','纹理','脐部','触感','好瓜']
property_list = [
'青绿','乌黑','浅白',
'蜷缩','稍蜷','硬挺',
'浊响','沉闷','清脆',
'清晰','稍糊','模糊',
'凹陷','平坦','稍凹',
'硬滑','软粘',]
import pandas as pd
import numpy as np
class NaiveBayes:
def __init__(self):
self.model = {}
# def calEntropy(self, y):
# valRate = y.value_counts().apply(lambda x : x / y.size)
# valEntropy = np.inner(valRate, np.log2(valRate)) * -1
# return valEntropy
def fit(self, xTrain, yTrain = pd.Series()):
if not yTrain.empty:#如果不传,自动选择最后一列作为分类标签
xTrain = pd.concat([xTrain, yTrain], axis=1) #按列合并
self.model = self.buildNaiveBayes(xTrain)
return self.model
def buildNaiveBayes(self, xTrain):
yTrain = xTrain.iloc[:,-1] #获取特征
yTrainCounts = yTrain.value_counts()# 得到各个特征对应的概率
yTrainCounts = yTrainCounts.apply(lambda x : (x + 1) / (yTrain.size + yTrainCounts.size)) #使用了拉普拉斯平滑 分别计算YES和NO的概率
# print("1111:",yTrainCounts)
# print("@@@")
retModel = {} #使用拉普拉斯的模型
for nameClass, val in yTrainCounts.items():
retModel[nameClass] = {'PClass': val, 'PFeature':{}}
# print("@@")
# print(retModel)
# print("@@")
propNamesAll = xTrain.columns[:-1] #训练数据
# print("@@")
# print(xTrain[propNamesAll])
# print("@@")
allPropByFeature = {}
for nameFeature in propNamesAll:
allPropByFeature[nameFeature] = list(xTrain[nameFeature].value_counts().index)#获取每列的特征
# print("@@")
# print(allPropByFeature)
# print("@@")
for nameClass, group in xTrain.groupby(xTrain.columns[-1]): #根据最后一列分组
for nameFeature in propNamesAll:
eachClassPFeature = {}
propDatas = group[nameFeature]
propClassSummary = propDatas.value_counts()# 频次汇总 得到各个特征对应的概率
for propName in allPropByFeature[nameFeature]:
if not propClassSummary.get(propName):
propClassSummary[propName] = 0#如果有属性没有,那么自动补0
Ni = len(allPropByFeature[nameFeature])
propClassSummary = propClassSummary.apply(lambda x : (x + 1) / (propDatas.size + Ni))#使用了拉普拉斯平滑 计算条件概率
for nameFeatureProp, valP in propClassSummary.items():
eachClassPFeature[nameFeatureProp] = valP
retModel[nameClass]['PFeature'][nameFeature] = eachClassPFeature
# print("@@")
# print(propClassSummary)
# print("@@")
return retModel
def predictBySeries(self, data):
curMaxRate = None
curClassSelect = None
for nameClass, infoModel in self.model.items():
rate = 0
rate += np.log(infoModel['PClass'])
PFeature = infoModel['PFeature'] #每个特征的概率
for nameFeature, val in data.items():
propsRate = PFeature.get(nameFeature)
if not propsRate:
continue
rate += np.log(propsRate.get(val, 0))#使用log加法避免很小的小数连续乘,接近零
#print(nameFeature, val, propsRate.get(val, 0))
#print(nameClass, rate)
if curMaxRate == None or rate > curMaxRate:
curMaxRate = rate
curClassSelect = nameClass
# print("@@")
# print(PFeature)
# print("@@")
return curClassSelect
def predict(self, data):
if isinstance(data, pd.Series): #对比类型
return self.predictBySeries(data)
return data.apply(lambda d: self.predictBySeries(d), axis=1)
dataTrain = data_df
naiveBayes = NaiveBayes()
treeData = naiveBayes.fit(dataTrain)
import json
print(json.dumps(treeData, ensure_ascii=False))
pd = pd.DataFrame({'预测值':naiveBayes.predict(dataTrain), '正取值':dataTrain.iloc[:,-1]})
print(pd)
print('正确率:%f%%'%(pd[pd['预测值'] == pd['正取值']].shape[0] * 100.0 / pd.shape[0]))
{"NO": {"PClass": 0.5263157894736842, "PFeature": {"0": {"浅白": 0.4166666666666667, "青绿": 0.3333333333333333, "乌黑": 0.25}, "1": {"稍缩": 0.4166666666666667, "蜷缩": 0.3333333333333333, "硬挺": 0.25}, "2": {"浊响": 0.4166666666666667, "沉闷": 0.3333333333333333, "清脆": 0.25}, "3": {"稍糊": 0.4166666666666667, "模糊": 0.3333333333333333, "清晰": 0.25}, "4": {"稍凹": 0.4166666666666667, "平坦": 0.3333333333333333, "凹陷": 0.25}, "5": {"硬滑": 0.5833333333333334, "软粘": 0.3333333333333333, "碍滑": 0.08333333333333333}}}, "YES": {"PClass": 0.47368421052631576, "PFeature": {"0": {"乌黑": 0.45454545454545453, "青绿": 0.36363636363636365, "浅白": 0.18181818181818182}, "1": {"蜷缩": 0.5454545454545454, "稍缩": 0.36363636363636365, "硬挺": 0.09090909090909091}, "2": {"浊响": 0.6363636363636364, "沉闷": 0.2727272727272727, "清脆": 0.09090909090909091}, "3": {"清晰": 0.8181818181818182, "稍糊": 0.09090909090909091, "模糊": 0.09090909090909091}, "4": {"凹陷": 0.5454545454545454, "稍凹": 0.36363636363636365, "平坦": 0.09090909090909091}, "5": {"碍滑": 0.5454545454545454, "软粘": 0.2727272727272727, "硬滑": 0.18181818181818182}}}}
预测值 正取值
0 YES YES
1 YES YES
2 YES YES
3 YES YES
4 YES YES
5 YES YES
6 YES YES
7 YES YES
8 NO NO
9 NO NO
10 NO NO
11 NO NO
12 NO NO
13 NO NO
14 YES NO
15 NO NO
16 NO NO
sklearn包中的朴素贝叶斯
from sklearn.model_selection import train_test_split
import numpy as np
data_list = [#青绿 0 乌黑 1 浅白 2 蜷缩 0 稍缩 1 硬挺 2 浊响 0 沉闷 1 清脆 2 清晰 0 稍糊 1 模糊 2 平坦 0 稍凹 1 凹陷 2 碍滑 0 软粘 1 硬滑 2
[0, 0, 0, 0, 2, 0, 1],
[1, 0, 1, 0, 2, 0, 1],
[1, 0, 0, 0, 2, 0, 1],
[0, 0, 1, 0, 2, 0, 1],
[2, 0, 0, 0, 2, 0, 1],
[0, 1, 0, 0, 1, 1, 1],
[1, 1, 0, 0, 1, 1, 1],
[1, 1, 0, 0, 1, 2, 1],
[1, 1, 1, 1, 1, 2, 0],
[0, 2, 2, 0, 0, 1, 0],
[2, 2, 2, 2, 0, 2, 0],
[2, 0, 0, 2, 0, 1, 0],
[0, 1, 0, 1, 2, 2, 0],
[2, 1, 1, 1, 2, 2, 0],
[1, 1, 0, 0, 1, 1, 0],
[2, 0, 0, 2, 1, 2, 0],
[0, 0, 1, 1, 1, 2, 0]
]
target = np.array([0,1,2,3,4,5,6],dtype='float32')
data = np.array(data_list,dtype='float32')
from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(data.T,target,random_state=1) #按比例分割数据
nb_clf = GaussianNB() #实例化模型
nb_clf.fit(x_train,y_train) #模型训练
a=nb_clf.predict(x_test) #预测
acc_score = nb_clf.score(x_test,y_test) #查看模型分数