糖尿病预测分析:探索Pima印第安人数据集中的奥秘

引言

       糖尿病是一种全球性的慢性代谢性疾病,对患者的生活质量和健康产生深远的影响。为了更好地理解和预测糖尿病的发病机制,我们选择了著名的Pima印第安人糖尿病数据集,通过数据分析和机器学习技术,试图揭示其中隐藏的规律和特征。

数据探索

数据集概览

      我们从UCI机器学习库中获取了Pima印第安人糖尿病数据集,该数据集一共有768行,9列,包含了8个生理特征和一个目标变量(是否患有糖尿病)。通过对数据的初步探索,我们获得了关于患糖尿病和非患糖尿病样本的分布比例以及各特征的基本统计信息。

数据可视化

       通过绘制直方图和相关矩阵热力图,我们深入了解了患糖尿病和非患糖尿病样本中特征之间的关系。特别是,我们关注了 'plasma_glucose_concentration'、'bmi' 等关键特征的分布差异,为后续的分析奠定了基础。

数据预处理

缺失值处理  

       在数据预处理阶段,我们采用了两种不同的缺失值处理方式:删除包含缺失值的行和填充缺失值。这一步骤旨在准备数据,使其更适合机器学习模型的训练。以下是进行缺失值处理的代码:

# (11)替换零值
columns = ['serum_insulin', 'bmi', 'plasma_glucose_concentration', 'diastolic_blood_pressure', 'triceps_thickness']
for col in columns:
    pima[col].replace([0], [None], inplace=True)

# (14)删除含有缺失值的行
pima_dropped = pima.dropna()

# (23)使用中位数填充缺失值
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(strategy="median")
pima_imputed = pd.DataFrame(imputer.fit_transform(pima), columns=pima_column_names)

机器学习建模

K最近邻(KNN)分类器

       我们选择了KNN分类器作为预测模型,通过使用网格搜索优化参数,找到了最优的模型参数组合。通过对填充缺失值和删除缺失值两种数据集进行训练和评估,我们比较了模型在不同数据集上的性能表现。以下是此模块代码:

# 使用KNN模型进行网格搜索优化
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
import warnings
warnings.filterwarnings('ignore')

# 定义了KNN模型的参数范围
knn_params = {'n_neighbors': [1, 2, 3, 4, 5, 6, 7]}

# 实例化了一个KNN分类器
knn = KNeighborsClassifier()

# 使用网格搜索优化
grid = GridSearchCV(knn, knn_params)
grid.fit(X_train, y_train)

# 输出了网格搜索得到的最佳模型的准确率和对应的最佳参数
print("最佳准确率:", grid.best_score_)
print("最佳参数:", grid.best_params_)

结果与讨论

          我们选择了KNN分类器作为预测模型,通过使用网格搜索优化参数,找到了最优的模型参数组合。通过对填充缺失值和删除缺失值两种数据集进行训练和评估,我们比较了模型在不同数据集上的性能表现。

总结与展望

         通过本次研究,我们深入探讨了Pima印第安人糖尿病数据集,通过数据可视化和机器学习模型揭示了潜在的糖尿病预测因素。我们的研究为糖尿病的早期干预和预防提供了一定的理论支持,并为未来的研究提出了一些可行的方向。

       在未来,我们可以考虑引入更多特征和更复杂的模型,以提高预测的准确性。同时,将模型应用于更大规模的数据集,验证其在真实场景中的稳定性和泛化能力,为糖尿病研究和预防工作提供更有力的支持。

      通过这次研究,我们希望为广大研究者和从业者提供一个深入了解糖尿病预测分析的案例,为未来相关研究和实践工作提供启示。

完整代码

#(1)导入库:导入了进行数据处理的必要库,并设置了内联绘图的环境。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
plt.style.use('fivethirtyeight')

#加载数据集,添加标题
pima_column_names = ['times_pregnant', 'plasma_glucose_concentration', 'diastolic_blood_pressure', 'triceps_thickness',
                    'serum_insulin', 'bmi', 'pedigree_function', 'age', 'onset_diabetes']

# 源数据的csv文件没有列名,需手动添加
path ='D:\pima-indians-diabetes.csv'
# header=0 少一行
pima = pd.read_csv(path,header=0,names=pima_column_names)
pima.head()

# (2)用于显示数据集 pima的行数和列数
pima.shape

# (3)计算一下空准确率:输出目标变量 'onset_diabetes' 中每个类别的相对频率(归一化计数),以及类别标签(onset_diabetes)
pima['onset_diabetes'].value_counts(normalize=True)

# (4)对plasma_glucose_concentration(血浆葡萄糖浓度)列绘制直方图(0,1出现的频率)
col = 'plasma_glucose_concentration'
# 不患糖尿病(bins=10 指定了直方图的箱数,alpha=0.5 设置了透明度)
plt.hist(pima[pima['onset_diabetes']==0][col],bins=10,alpha=0.5,label='non-diabetes')
# 患糖尿病
plt.hist(pima[pima['onset_diabetes']==1][col],bins=10,alpha=0.5,label='diabetes')
plt.legend(loc='upper right')
plt.xlabel(col)
plt.ylabel('Frequency')
plt.title('Histogram of {}'.format(col))

# (5)绘制其他列的直方图(bmi:身体质量数 diastolic_blood_pressure:心脏舒张压 plasma_glucose_concentration:血浆葡萄糖浓度)
cols = ['bmi','diastolic_blood_pressure','plasma_glucose_concentration']

for col in cols:
    # 不患糖尿病
    plt.hist(pima[pima['onset_diabetes']==0][col],bins=10,alpha=0.5,label='non-diabetes')
    # 患糖尿病
    plt.hist(pima[pima['onset_diabetes']==1][col],bins=10,alpha=0.5,label='diabetes')
    plt.legend(loc='upper right')
    plt.xlabel(col)
    plt.ylabel('Frequency')
    plt.title('Histogram of {}'.format(col))
    plt.show()

# (6)pima.corr() 计算了数据集中所有数值型特征之间的相关性sns.heatmap() 函数绘制了相关矩阵的热力图,热力图中不同颜色对应不同的相关性亮色表示正相关,暗色表示负相关。
sns.heatmap(pima.corr())

# (7)计算了数据集之间的相关性每个特征与目标变量的皮尔逊相关系数,值越接近1表示正相关,越接近-1表示负相关。
pima.corr()['onset_diabetes'].sort_values(ascending=False)

# (8)计算数据集 pima 中每个特征的缺失值数量
pima.isnull().sum()

# (9)查看数据的基本描述性统计(均值、标准差、最小值、25% 分位数、中位数(50% 分位数)、75% 分位数和最大值)
pima.describe()

# (10)手动将每列的0替换成None,将实际的0值标记为缺失值
print(pima['serum_insulin'].isnull().sum())

# 用None手动替换0
pima['serum_insulin']=pima['serum_insulin'].map(lambda x:x if x!=0 else None)

# 检查替换后的缺失值数量
print(pima['serum_insulin'].isnull().sum())

# (11)直接对所有列操作
columns = ['serum_insulin', 'bmi', 'plasma_glucose_concentration', 'diastolic_blood_pressure', 'triceps_thickness']
for col in columns:
    pima[col].replace([0], [None], inplace=True)

# 查看缺失值情况
pima.isnull().sum()

# (12)查看数据集 pima 的前几行,以查看对列中的0值替换为None的效果
pima.head()

# (13)不包含有缺失值的列,提供没有缺失值的列的统计摘要
pima.describe() 

# (14)删除存在缺失的行,简化数据集,指示删除了多少百分比的行
pima_dropped = pima.dropna()
# 检查删除了多少行
num_rows_lost = round(100*(pima.shape[0] - pima_dropped.shape[0]) / float(pima.shape[0]))
print("删除 {}%".format(num_rows_lost))

# (15)未删除数据的空准确率,在未删除包含缺失值的数据集中0,1占比
pima['onset_diabetes'].value_counts(normalize=True)

# (16)删除数据后的空准确率
pima_dropped['onset_diabetes'].value_counts(normalize=True)

# (17)未删除数据的均值
pima.mean()

# (18)删除数据后的均值
pima_dropped.mean()

# (19)计算未删除缺失值的数据集 pima_dropped 与原始数据集 pima 中数值型列的均值变化百分比
ax = ((pima_dropped.mean() - pima.mean()) / pima.mean()).plot(kind='bar', title='% change in average column values')
ax.set_ylabel('% change')#正值表示均值上升,负值表示均值下降

# (20)使用K最近邻(KNN)分类器对未删除缺失值的数据集进行建模,并通过网格搜索找到最佳的K值
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
import warnings
warnings.filterwarnings('ignore')

# 删除标签数据
X_dropped = pima_dropped.drop('onset_diabetes', axis=1)  # 特征
print("leanrning from {} rows".format(X_dropped.shape[0]))
y_dropped = pima_dropped['onset_diabetes']   # 标签

# 定义了KNN模型的参数范围
knn_params = {'n_neighbors': [1, 2, 3, 4, 5, 6, 7]}

# 实例化了一个KNN分类器,该分类器在后续步骤中将被用于网格搜索
knn = KNeighborsClassifier()

# 使用网格搜索优化
grid = GridSearchCV(knn, knn_params)
grid.fit(X_dropped, y_dropped)

#  输出了网格搜索得到的最佳模型的准确率和对应的最佳参数
print(grid.best_score_, grid.best_params_)

# (21)查看缺失值情况
pima.isnull().sum()

# (22)用fillna方法填充, 再次查看整个数据集中的缺失值数量。
pima['plasma_glucose_concentration'].fillna(pima['plasma_glucose_concentration'].mean(),inplace=True)
pima.isnull().sum()

# (23)使用scikit-learn预处理类的Imputer模块
from sklearn.impute import SimpleImputer
# 实例化Imputer对象并指定了使用中位数填充缺失值的策略。
imputer = SimpleImputer(strategy="median")
# 创建新对象并填充缺失值
pima_imputed = imputer.fit_transform(pima)
# 将得到的ndarray类型转化为DataFrame并设置列名为原始数据集的列名。
pima_imputed = pd.DataFrame(pima_imputed, columns=pima_column_names)
#输出填充后的数据的前几行
pima_imputed.head()

# (24)在填充缺失值后判断是否有缺失值
pima_imputed.isnull().sum()


#(25)
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
import warnings
warnings.filterwarnings('ignore')

# 用0填充,创建特征集和标签集
pima_zero = pima.fillna(0)
X_zero = pima_zero.drop('onset_diabetes', axis=1)
y_zero = pima_zero['onset_diabetes']
print("learning from {} rows".format(X_zero.shape[0]))

# KNN的模型参数用不同的邻居数进行网格搜索
knn_params = {'n_neighbors': [1, 2, 3, 4, 5, 6, 7]}

# 实例化了一个KNN分类器,该分类器在后续步骤中将被用于网格搜索
knn = KNeighborsClassifier()

# 使用网格搜索优化,通过在给定的参数范围内搜索最佳参数组合,以获得最佳的KNN模型。
grid = GridSearchCV(knn, knn_params)
grid.fit(X_zero, y_zero)
# 输出了网格搜索得到的最佳模型的准确率和对应的最佳参数。
print(grid.best_score_, grid.best_params_)

  • 25
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值