目录
一、数据预处理
1.转换出Outcome这个字段
把class中的b'tested_positive'和b'tested_negative'转换为Outcome中的1和0
并且drop掉class这个字段
diabetes_data['OutCome'] = diabetes_data['class'].map(lambda s: 1 if s == "b'tested_positive'" else 0)
diabetes_data.drop(labels = ["class"], axis = 1, inplace = True)
Python之Lambda表达式和if not...else用法_全栈测试开发日记的博客-CSDN博客
2.describe()
count 告诉我们特征中非空行的数量。
mean 告诉我们该特征的平均值。
std 告诉我们该特征的标准偏差值。
min 告诉我们该特征的最小值。
25%、50% 和 75% 是每个特征的百分位数/四分位数。 这个四分位信息有助于我们检测异常值。
max 告诉我们该特征的最大值。
print(diabetes_data.describe())
print(diabetes_data.describe().T)
3.查找缺失值
以下列或变量的零值无效:葡萄糖、血压、皮肤厚度、胰岛素、体重指数
把他们都改成NaN类型
diabetes_data_copy = diabetes_data.copy(deep = True)
diabetes_data_copy[['plas','pres','skin','insu','mass']] = diabetes_data_copy[['plas','pres','skin','insu','mass']].replace(0,np.NaN)
## showing the count of Nans
print(diabetes_data_copy.isnull().sum())
4.缺失值填补
mean_byOutcome('plas')
diabetes_data_copy.loc[(diabetes_data_copy['Outcome'] == 0) & (diabetes_data_copy['plas'].isnull()), 'plas'] = mean_byOutcome('plas')['plas'][0]
diabetes_data_copy.loc[(diabetes_data_copy['Outcome'] == 1) & (diabetes_data_copy['plas'].isnull()), 'plas'] = mean_byOutcome('plas')['plas'][1]
二、特征分析
1.热力图分析Outcome与其他数据的相关性
从图中可以看出患病率跟plas(口服葡萄糖耐量试验中 2 小时的血浆葡萄糖浓度)相关性很大
跟pres(舒张压 )和skin(三头肌皮褶厚度)的相关性较小
2.探究preg和患病率的关系
preg没有缺失值
可以看出当怀孕次数大于7次甚至更多时,患病的概率比较高。
3.探究plas与患病率的关系
plas有5个缺失值 用了中值填补
#探究plas与患病率的关系 plas有5个缺失值 用了中值填补 跨度太大 采用histplot
diabetes_data_copy["plas"] = diabetes_data_copy["plas"].fillna(diabetes_data_copy["plas"].median())
print(diabetes_data_copy.isnull().sum())
g = sns.FacetGrid(diabetes_data_copy, col='Outcome')
g = g.map(sns.histplot, "plas")
plt.show()
跨度太大了 于是不用柱状图 改为hist图
当把两个图叠起来时,可以明显看出ples(口服葡萄糖耐量试验中 2 小时的血浆葡萄糖浓度)在一百以下的人患病率更低
4.探究pres与患病率的关系
探究pres与患病率的关系 pres有35个缺失值 使用中值填补
也是因为跨度较大 采用histplot
#探究pres与患病率的关系 pres有35个缺失值 使用中值填补
diabetes_data_copy["pres"] = diabetes_data_copy["pres"].fillna(diabetes_data_copy["pres"].median())
print(diabetes_data_copy.isnull().sum())
g = sns.FacetGrid(diabetes_data_copy, col='Outcome')
g = g.map(sns.histplot, "pres")
plt.show()
g = sns.kdeplot(diabetes_data_copy["pres"][(diabetes_data_copy["Outcome"] == 0) & (diabetes_data_copy["pres"].notnull())], color="Red", shade = True)
g = sns.kdeplot(diabetes_data_copy["pres"][(diabetes_data_copy["Outcome"] == 1) & (diabetes_data_copy["pres"].notnull())], ax =g, color="Blue", shade= True)
g.set_xlabel("pres")
g.set_ylabel("prevalence rate")
g = g.legend(["Not ill","ill"])#注意这里的顺序和上面绘图的顺序保持一致
plt.show()
可以看出pres跟患病率的相关性不大
5.探究skin与患病率的关系
skin的缺失值比较多
g = sns.heatmap(diabetes_data_copy[["preg","plas","pres","skin","insu","mass","pedi","age"]].corr(),annot=True, fmt = ".2f", cmap = "coolwarm")
plt.show()
通过热力图可以看出skin和mass、pres、plas三种数据相关性较大
# Filling missing value of skin
index_NaN_age = list(diabetes_data_copy["skin"][diabetes_data_copy["skin"].isnull()].index)
#注意这里的空置表示方式:dataset['skin'][dataset.skin.isnull()].index,属性后面紧跟着一个[筛选条件].index,返回的是raw序号.
for i in index_NaN_age :
skin_med = diabetes_data_copy["skin"].median()#非空skin 值的中位数
skin_pred = diabetes_data_copy["skin"][((diabetes_data_copy['mass'] == diabetes_data_copy.iloc[i]["mass"]) & (diabetes_data_copy['pres'] == diabetes_data_copy.iloc[i]["pres"]) & (diabetes_data_copy['plas'] == diabetes_data_copy.iloc[i]["plas"]))].median()#在所有的记录中,寻找与Age为空值记录,SibSp\Parch\Pclass都想同的记录,例如有5条,取这5条记录中Age的中位数填充空的Age值
if not np.isnan(skin_pred) :
diabetes_data_copy['skin'].iloc[i] = skin_pred
else :
diabetes_data_copy['skin'].iloc[i] = skin_med
print(diabetes_data_copy.isnull().sum())
在三头肌皮褶厚度20mm左右有一个不患病的高峰值
6.探究insu与患病率的关系
insu跟plas、mass、age相关性比较大
根据这三个值来填补mass的空缺值
可以看出insu在150左右的地方存在不患病的峰值
#insu的缺失值比较多
g = sns.heatmap(diabetes_data_copy[["preg","plas","pres","skin","insu","mass","pedi","age"]].corr(),annot=True, fmt = ".2f", cmap = "coolwarm")
plt.show()
# Filling missing value of insu
index_NaN_age = list(diabetes_data_copy["insu"][diabetes_data_copy["insu"].isnull()].index)
#注意这里的空置表示方式:dataset['skin'][dataset.skin.isnull()].index,属性后面紧跟着一个[筛选条件].index,返回的是raw序号.
for i in index_NaN_age :
insu_med = diabetes_data_copy["insu"].median()#非空skin 值的中位数
insu_pred = diabetes_data_copy["insu"][((diabetes_data_copy['mass'] == diabetes_data_copy.iloc[i]["mass"]) & (diabetes_data_copy['plas'] == diabetes_data_copy.iloc[i]["plas"]) & (diabetes_data_copy['age'] == diabetes_data_copy.iloc[i]["age"]))].median()#在所有的记录中,寻找与Age为空值记录,SibSp\Parch\Pclass都想同的记录,例如有5条,取这5条记录中Age的中位数填充空的Age值
if not np.isnan(insu_pred) :
diabetes_data_copy['insu'].iloc[i] = insu_pred
else :
diabetes_data_copy['insu'].iloc[i] = insu_med
print(diabetes_data_copy.isnull().sum())
g = sns.kdeplot(diabetes_data_copy["insu"][(diabetes_data_copy["Outcome"] == 0) & (diabetes_data_copy["insu"].notnull())], color="Red", shade = True)
g = sns.kdeplot(diabetes_data_copy["insu"][(diabetes_data_copy["Outcome"] == 1) & (diabetes_data_copy["insu"].notnull())], ax =g, color="Blue", shade= True)
g.set_xlabel("insu")
g.set_ylabel("Frequency")
g = g.legend(["Not ill","ill"])#注意这里的顺序和上面绘图的顺序保持一致
plt.show()
7.探究mass与患病率的关系
中值填补
mass在25以下时,患病率比较低,在35左右之后患病率高。
8.探究pedi和患病率的关系
没有缺失值
可以看出在0到0.5间有一个不患病的峰值
g = sns.kdeplot(diabetes_data_copy["pedi"][(diabetes_data_copy["Outcome"] == 0) & (diabetes_data_copy["pedi"].notnull())], color="Red", shade = True)
g = sns.kdeplot(diabetes_data_copy["pedi"][(diabetes_data_copy["Outcome"] == 1) & (diabetes_data_copy["pedi"].notnull())], ax =g, color="Blue", shade= True)
g.set_xlabel("pedi")
g.set_ylabel("Frequency")
g = g.legend(["Not ill","ill"])#注意这里的顺序和上面绘图的顺序保持一致
plt.show()
9.探究age与患病率的关系
从图中可以得出结论,年龄越小越不容易患病
三、建模以及预测
因为泰坦尼克号的建模实在没怎么懂
所以参考了利用python机器学习库进行Kaggle皮马印第安人糖尿病预测分析_Gerard_mok的博客-CSDN博客
这一篇csdn来做
将数据集拆分为80%的训练集和20%的测试集。训练集有614条数据,用于训练模型。测试集有154条数据,用于模型结果预测。
print(diabetes_data_copy.Outcome.value_counts())
from sklearn.preprocessing import StandardScaler
sc_X = StandardScaler()
source_x = pd.DataFrame(sc_X.fit_transform(diabetes_data_copy.drop(['Outcome'], axis = 1),), columns = ['preg',
'plas',
'pres',
'skin',
'insu',
'mass',
'pedi',
'age'])
from sklearn.model_selection import train_test_split
source_y = diabetes_data_copy.Outcome
train_X, test_X, train_y, test_y = train_test_split(source_x,
source_y,
train_size = .8,
random_state = 0)
选用逻辑回归算法训练模型,导入算法并且导入评估算法
# 选用逻辑回归算法训练模型,导入算法并且导入评估算法
from sklearn.linear_model import LogisticRegression
# 训练模型
log_mod = LogisticRegression()
log_mod.fit(train_X, train_y)
preds = log_mod.predict(test_X)
from sklearn.metrics import confusion_matrix, accuracy_score
# 评估模型
confusion_matrix(test_y, preds) #混淆模型
print(accuracy_score(test_y, preds))
得出的结果是