试编程实现拉普拉斯修正的朴素贝叶斯分类器和半朴素贝叶斯分类器中的AODE分类器,并以⻄瓜数据集3.0为训练集,对P.151“测1”样本进⾏判别。
编号 色泽 根蒂 敲声 纹理 脐部 触感 密度 含糖率 好瓜
0 1 青绿 蜷缩 浊响 清晰 凹陷 硬滑 0.697 0.460 是
1 2 乌黑 蜷缩 沉闷 清晰 凹陷 硬滑 0.774 0.376 是
2 3 乌黑 蜷缩 浊响 清晰 凹陷 硬滑 0.634 0.264 是
3 4 青绿 蜷缩 沉闷 清晰 凹陷 硬滑 0.608 0.318 是
4 5 浅白 蜷缩 浊响 清晰 凹陷 硬滑 0.556 0.215 是
5 6 青绿 稍蜷 浊响 清晰 稍凹 软粘 0.403 0.237 是
6 7 乌黑 稍蜷 浊响 稍糊 稍凹 软粘 0.481 0.149 是
7 8 乌黑 稍蜷 浊响 清晰 稍凹 硬滑 0.437 0.211 是
8 9 乌黑 稍蜷 沉闷 稍糊 稍凹 硬滑 0.666 0.091 否
9 10 青绿 硬挺 清脆 清晰 平坦 软粘 0.243 0.267 否
10 11 浅白 硬挺 清脆 模糊 平坦 硬滑 0.245 0.057 否
11 12 浅白 蜷缩 浊响 模糊 平坦 软粘 0.343 0.099 否
12 13 青绿 稍蜷 浊响 稍糊 凹陷 硬滑 0.639 0.161 否
13 14 浅白 稍蜷 沉闷 稍糊 凹陷 硬滑 0.657 0.198 否
14 15 乌黑 稍蜷 浊响 清晰 稍凹 软粘 0.360 0.370 否
15 16 浅白 蜷缩 浊响 模糊 平坦 硬滑 0.593 0.042 否
16 17 青绿 蜷缩 沉闷 稍糊 稍凹 硬滑 0.719 0.103 否
读取数据
D_keys = {
'色泽': ['青绿', '乌黑', '浅白'],
'根蒂': ['蜷缩', '硬挺', '稍蜷'],
'敲声': ['清脆', '沉闷', '浊响'],
'纹理': ['稍糊', '模糊', '清晰'],
'脐部': ['凹陷', '稍凹', '平坦'],
'触感': ['软粘', '硬滑'],
}
Class, labels = '好瓜', ['是', '否']
#读取数据
def loadData(filename):
dataSet=pd.read_csv(filename)
dataSet.drop(columns=['编号'],inplace=True)
return dataSet
#配置测1数据
def load_data_test():
array=['青绿','蜷缩','浊响','清晰','凹陷','硬滑',0.697,0.460,'']
dic={a: b for a,b in zip(dataSet.columns,array)}
return dic
def calculate_D(dataSet):
D=[]
for label in labels:
temp=dataSet.loc[dataSet[ Class ]==label]
D.append(temp)
return D8
计算先验概率:
#计算先验概率
def calculate_Pc(Dc,D):
D_size= D.shape[0]
Dc_size=Dc.shape[0]
N=len(labels)
return (Dc_size+1)/(D_size+N)
计算条件概率:
#计算条件概率
##当属性为离散型
def calculate_Pcx_D(key, value, Dc):
Dc_size = Dc.shape[0]
Dcx_size = Dc[key].value_counts()[value]
Ni = len(D_keys[key])
return (Dcx_size+1) / (Dc_size+Ni)
##当属性为连续型
def calculate_Pcx_C(key, value, Dc):
mean,var=Dc[key].mean(),Dc[key].var()
exponent = math.exp(-(math.pow(value - mean, 2) / (2 * var)))
return (1 / (math.sqrt(2 * math.pi * var)) * exponent)
计算后验概率:
#计算概率
def calculate_probability(label, Dc, dataSet, data_test):
prob = calculate_Pc(Dc, dataSet)
for key in Dc.columns[:-1]:
value = data_test[key]
if key in D_keys:
prob *= calculate_Pcx_D(key, value, Dc)
else:
prob *= calculate_Pcx_C(key, value, Dc)
return prob
进行预测
def predict(dataSet, data_test):
# mu, sigma = dataSet.mean(), dataSet.var()
Dcs = calculate_D(dataSet)
max_prob = -1
for label, Dc in zip(labels, Dcs):
prob = calculate_probability(label, Dc, dataSet, data_test)
if prob > max_prob:
best_label = label
max_prob = prob
print(label, prob)
return best_label
主函数
if __name__ == '__main__':
# 读取数据
filename = 'tree.txt'
dataSet = loadData(filename)
data_test = load_data_test()
label = predict(dataSet, data_test)
print('预测结果:', label)
加载数据
def loadData(filename):
data=pd.read_csv(filename)
return data
AODE分类器
def aode(data,testsample):
D=data['编号'].count() #数据集data的数量
Category = data['好瓜'].unique() #数据集的类别
N=len(Category) #数据集类别数量
# 将离散属性和连续属性分离
Discrete_attribute=data.columns[1:-3]
Continuous_attribute=data.columns[-3:-1]
res=pd.Series([1.0,1.0],index=Category)
for k in Category:
Pcxis=0 #最后的总和
for i in Discrete_attribute:
Ni=len(data[i].unique()) #第i个属性可能的取值数
Dcxi=data[(data[i]==testsample[i][0])&(data['好瓜']==k)] #取出满足D中第i个属性取值为测试样例第i个属性的值且类别为k的数据集
Pcxi = (len(Dcxi)+1)/(D+N*Ni)
Pjcim=1 #P(xj|c,xi)的乘积
for j in Discrete_attribute:
Nj=len(data[j].unique()) #第j个属性可能的取值数
Dcij=data[(data[i]==testsample[i][0])&(data['好瓜']==k)&(data[j]==testsample[j][0])]
Pjci=(len(Dcij)+1)/(len(Dcxi)+Nj)
Pjcim=Pjci*Pjcim
Pcxis=Pcxis+Pcxi*Pjcim
res[k]=Pcxis
return res
主函数
if __name__=='__main__':
data=loadData("tree.txt")
testsample = pd.DataFrame(np.mat(['青绿', '蜷缩', '浊响', '清晰', '凹陷', '硬滑', 0.697, 0.460]),
columns=['色泽', '根蒂', '敲声', '纹理', '脐部', '触感', '密度', '含糖率'], index=[0])
result=aode(data,testsample)
print(result)