import pandas
import math
import numpy
##读取训练数据 特征部分(机器人传感器收集的112个顾客气色,气味,脉象,体温等特征
X=pandas.read_csv('train_X.csv')
#读取训练数据 实际结果部分(上述112位顾客真实的怀孕状态,0代表女娃,1代表男孩,2表示没有怀孕
y=pandas.read_csv('train_y.csv')
class NavieBayes(object):
def fit(self,x,y):
self.x=x.values
self.y=y.values
print('y',self.y.flatten())
##计算气色,气味,脉相,体温在条件为s下的概率
#所有结果下的 x0s=[] 存放列数据; means=[] 平均值;stds=[] 标准差
self.means = []; self.stds = []
# 得到结果为s的数据集
nums = []
for s in range(3):
nums.append(self.getClass(s))
x0=[];mean=[];std=[] #计算某s类结果下平均值,标准差
for i in range(len(self.x[0])): #代表数据的第i列
x0.append(self.getColumn(nums[s], i)) # 得到s类结果下第i列数据
mean.append(numpy.mean(x0[i])) #平均值
std.append(numpy.std(x0[i])) #标准差
#存放平均值,标准差 means[0]为结果为0下的平均值means[0][0] 0下气色的平均值
#means[结果][特征]
self.means.append(mean)
self.stds.append(std)
# 得到结果类别, 就是把这个文档中所有结果不重复的放在一个列表里面
#调用self.ySet[i]
self.ySet = set(self.y.flatten())
# for re in self.y:
# self.ySet = self.ySet | set(re) # 取两个集合的并集
self.ySet = list(self.ySet)
# 计算结果为0,1,2在结果中的频率p(0), p(1), p(2)
# @ self.getClass(0) 结果为0的数据, self.y总的结果数据
self.py = []
for n in self.ySet: # n为结果类别
self.py.append(len(self.getClass(n)) / float(len(self.y)))
#预测怀孕结果
def predict(self,test):
# 计算test,数据为0的概率p(0|xi)
#数组相对应元素相乘需要用nummpy.array()
test=numpy.array(test)
#数组中的每个元素都加一个常数 numpy.log(self.trainNB()[0])
p = []; #n中结果对应的概率
for n in self.ySet:
m=0 ; #m为存放结果n,对应的索引位置
# 计算test,数据为n的概率p(n|xi)
p.append(self.sum1(numpy.log(test * self.gausDisFunction(test, n))) + numpy.log(self.py[m]))
m=m+1
#储存预测结果
re=[]
for j in range(len(test)): # j 为测试数据的数量
pj=self.getColumn(p,j) # 得到数据j 的概率
print('pj数据j的概率',pj)
ni=self.getMax(pj)
print('概率最大结果的索引ni',ni)
#概率最大的结果self.ySet[ni]
re.append(self.ySet[ni])
return re
#得到数组中最大值的索引
def getMax(self,nums):
n0=0;max=nums[0]
for n in nums:
if n>max:
max=n
n0+=1
return n0
#二维数组中,内数组求和
def sum1(self,nums):
sum1=[]
for nu in nums:
sum1.append(sum(nu))
return sum1
#取出数组(list1)中的某一(num)列
def getColumn(self,list1,num):
lis=[]
for li in list1:
lis.append(li[num])
return lis
#数据分类,把训练数据按结果分类(0,1,2)
#得到结果为s的数据集
def getClass(self,s):
nums=[]
for i in range(len(self.y)):
if self.y[i]==s:
#把结果为s的数据存放到nums中
nums.append(self.x[i])
return nums
#高斯分布计算连续概率,
# #@s为某类结果,test为测试文档
def gausDisFunction(self,test,s):
# #返回某类结果条件下,数据的概率
# #返回多个的结果
y0 = []
for te in test:
y1 = []
for j in range(len(te)):
y1.append(numpy.exp(-(te[j] - self.means[s][j]) ** 2 / (2 * self.stds[s][j] ** 2)) / (math.sqrt(2 * math.pi) * self.stds[s][j]))
y0.append(y1)
# 返回某类结果条件下,数据test的概率
return numpy.array(y0)
# 测试
doctor= NavieBayes()
doctor.fit(X,y)
#下面使用38位顾客的数据测试机器人诊断效果
#读取38位顾客的气色,气味,脉象,体温等特征数据
test_X=pandas.read_csv('test_X.csv')
#诊断! 结果存放到result数组中
result=doctor.predict(test_X.values)
print('预测结果',result)
#打印输出诊断结果,与实际的结果比较
#读取38位顾客怀孕状态的实际值(0代表女娃,1代表男孩,2表示没有怀孕)
test_y=pandas.read_csv('test_y.csv')
# print('实际结果',test_y.values)
labels=['女娃','男孩','没有怀孕']
i=0
#正确的诊断数
predictOKNum=0
print("编号,诊断值,实际值")
while i<test_y.shape[0]:
#第i个诊断结果与实际的第i个结果比较,相等表示诊断正确
if result[i]==(test_y.values[i,0]): #test_y.values 为二维数组
predictOKNum=predictOKNum+1
okOrNo="准确"
else:
okOrNo = "错误"
print("%s,%s,%s,%s"%(i+1,labels[result[i]],labels[test_y.values[i,0]],okOrNo))
i=i+1
print("诊断正确率:%s" % (predictOKNum/i))
改进后的朴素贝叶斯测试怀孕结果
最新推荐文章于 2023-11-01 20:54:35 发布