在这里,我们使用一份皮马印第安女性的医学数据,用来预测其是否会得糖尿病。文件一共有768个样本,我们先剔除缺失值,然后选出20%的样本作为测试样本。
特征分别是:
怀孕次数
口服葡萄糖耐量试验中血浆葡萄糖浓度
舒张压(mm Hg)
三头肌组织褶厚度(mm)
2小时血清胰岛素(μU/ ml)
体重指数(kg/(身高(m))^ 2)
糖尿病系统功能
年龄(岁)
(注:特征值为0表示缺失值)
标签是:
是否患有糖尿病,0代表没有糖尿病,1代表患有糖尿病
在开始之前,先回顾一下朴素贝叶斯算法:
假设训练集特征数为i,记作xi,目标为k个类别,记为Ck,样本数为n,新样本特征记作xnew_sample。
1,计算出先验概率P(Ck),即每个类别在训练集中的概率;
2,分别计算出训练集中每个特征在每个类别下的条件概率P(xi|Ck),具体分为以下三种情况;
a)如果特征数据是离散值,那么我们假设其符合多项式分布,代入公式
;
b)如果特征数据是布尔类型的离散值,那么我们假设其符合伯努利分布,代入公式
;
c)如果特征数据是连续值,那么我们假设其符合高斯分布。只需要求出这个特征在每个类别下的平均值μk和方差σk2,然后代入公式
;
3,对于需要预测类别的新样本,分别计算每个类别下的极大后验概率:
(我们在实际计算中为防止数据下溢,将连乘运算取对数变成相加运算);
4,对上述极大后验概率进行比较,最大的那个对应的类别即为结果;
首先导入pandas和numpy库,读取csv文件,然后去除缺失值:
importpandas as pdimportnumpy as np
data=pd.read_csv(r"C:\Users\ccav\pima-indians-diabetes.data.csv",header=None,\
names=["怀孕次数","口服葡萄糖耐量试验中血浆葡萄糖浓度",\"舒张压(mm Hg)","三头肌组织褶厚度(mm)",\"2小时血清胰岛素(μU/ ml)","体重指数(kg/(身高(m))^ 2)",\"糖尿病系统功能","年龄(岁)","是否患有糖尿病"])
data.iloc[:,0:8]=data.iloc[:,0:8].applymap(lambda x:np.NaN if x==0 else x) #把属性值为0的地方转换成NaN
data=data.dropna(how="any",axis=0) #去除有缺失值的行
经过处理还只剩336个有效样本:
print(len(data))336
通过查看,我们发现在这336个有效样本中,225个是没有糖尿病人的样本,111个是患有糖尿病人的样本,显然原数据里两个类别的样本是不均衡的。这个问题可以通过不同的采样方法解决,但是鉴于简便起见,我们随机选取大约20%的样本用于测试:
#随机选取80%的样本作为训练样本
data_train=data.sample(frac=0.8,random_state=4,axis=0)#剩下的作为测试样本