糖尿病预测--KNN算法
该文本介绍了利用机器学习算法对糖尿病数据集进行二分类的任务,并详细描述了相关过程:
任务背景:使用机器学习算法对糖尿病数据集进行二分类。
数据分析:
- 数据集包含768个样本,8个特征和1个目标标签(是否患糖尿病)。
- 目标标签“Outcome”为0表示无糖尿病,1表示有糖尿病。
- 数据来源为Kaggle平台。
代码实现:- 加载并预览了数据。
- 描述性统计分析:查看样本信息、分布情况及标签分布。
- 数据可视化:绘制热力图显示各特征间的相关性;使用pairplot展示各特征两两之间的关系;绘制混淆矩阵以评估模型性能。
KNN算法:- 使用K-最近邻(KNN)算法进行分类。
- 通过调整K值优化模型性能,并通过混淆矩阵和准确率评估模型效果。
- 最终选择K=9时的模型表现最佳。
摘要总结了上述内容的核心信息。
一、问题背景
基于机器学习算法对糖尿病相关数据集进行了二类分类问题的研究与实现
二、数据集分析
- 糖尿病数据集中一共有768个样本,每个样本有8个特征和1个对应的标签
| 属性 | 含义 |
|---|---|
| Pregnancies | 怀孕次数 |
| Glucose | 葡萄糖测试值 |
| BloodPressure | 血压 |
| SkinThickness | 皮肤厚度 |
| Insulin | 胰岛素 |
| BMI | 身体质量指数 |
| DiabetesPedigreeFunction | 糖尿病遗传函数 |
| Age | 年龄 |
| Outcome | 糖尿病标签,1表示有糖尿病,0表示没有糖尿病 |
数据集下载地址为:https://www.kaggle.com/saurabh00007/diabetescsv
打开diabetes.csv,数据格式如下:

三、代码实现
import numpy as py
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
diabetes_data = pd.read_csv('diabetes.csv')
print(diabetes_data.head())
# 查看数据信息
print(diabetes_data.info(verbose=True))
# 设置参数verbose为True,允许冗长信息
# 数据描述
print(diabetes_data.describe())
# 通过describe可以观察到数据的数量,平均值,标准差,最小值,最大值等数据
#数据形状
print("dimension of diabetes data: {}".format(diabetes_data.shape))
#查看标签分布
print(diabetes_data.Outcome.value_counts())
#使用柱状图的方式画出标签个数统计
plt.figure()
diabetes_data.Outcome.value_counts().plot(kind="bar")
plt.figure()
sns.countplot(diabetes_data['Outcome'], label="Count")
plt.savefig("0_1_graph")
# 可视化数据分布
# 对角线上是各个属性的直方图(分布图)
# 而非对角线上是两个不同属性之间的相关图
plt.figure()
sns.pairplot(diabetes_data)
plt.savefig("0_2_graph")
'''
sns.pairplot(diabetes_data, hue="Outcome");
plt.savefig("0_3_grap")
'''
# 画热力图,数值为两个变量之间的相关系数
# annot: 默认为False,为True,在格子上显示数字
plt.figure()
sns.heatmap(diabetes_data.corr(), annot=True)
plt.savefig("0_4_grap")
# KNN算法
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split(\
diabetes_data.loc[:,diabetes_data.columns !='Outcome'],\
diabetes_data['Outcome'],stratify=diabetes_data['Outcome'],random_state=66)
# 把数据切分为特征X和标签y
# 切分数据集,test_size=0.3表示30%为测试集。
# stratify=y表示切分后训练集和测试集中的数据类型的比例跟切分前y中的比例一致
# 如切分前y中0和1的比例为1:2,切分后y_train和y_test中0和1的比例也都是1:2
#X = diabetes_data.drop("Outcome",axis = 1)
#y = diabetes_data.Outcome
#X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.3, stratify=y)
from sklearn.neighbors import KNeighborsClassifier
# 保存不同k值测试集准确率
training_accuracy = []
# 保存不同k值训练集准确率
test_accuracy = []
# try n_neighbors from 1 to 10
neighbors_settings = range(1,11)
for n_neighbors in neighbors_settings:
# build the model
knn = KNeighborsClassifier(n_neighbors = n_neighbors)
knn.fit(X_train,y_train)
#record training set accuracy 保存训练集准确率
training_accuracy.append(knn.score(X_train,y_train))
#record test set accuracy 保存测试集准确率
test_accuracy.append(knn.score(X_test,y_test))
plt.figure()
plt.plot(neighbors_settings,training_accuracy,label="training accuracy")
plt.plot(neighbors_settings,test_accuracy,label="test accuracy")
plt.ylabel("Accuracy")
plt.xlabel("n_neighbors")
plt.legend() # 给图像加上图例
plt.savefig('knn_compare_model')
knn = KNeighborsClassifier(n_neighbors=9)
knn.fit(X_train,y_train)
print('Accuracy of K-NN classifier on training set:{:.2f}'.format(\
knn.score(X_train,y_train)))
print('Accuracy of K-NN classifier on training set:{:.2f}'.format(\
knn.score(X_test,y_test)))
from sklearn.metrics import confusion_matrix
from sklearn.metrics import classification_report
y_pred = knn.predict(X_test)
print(classification_report(y_pred, y_test))
confusion = confusion_matrix(y_pred, y_test)
df_cm = pd.DataFrame(confusion)
plt.figure()
sns.heatmap(df_cm, annot=True)
plt.savefig('confusion_matrix')
plt.show()
补充说明:
pandas模块中的sns.heatmap函数主要用于生成热力图来展示数据间的相关性关系。该热力图通过数值反映两个数据变量之间的相关程度,在-1至1的范围内进行量化表示。具体而言,在数值大于零的情况下体现着正相关关系,在小于零的情况下则代表负相关情况;当数值等于零时,则表明两个数据变量之间不存在线性相关关系。

通过查看该热力图的数据分布情况,我们可以观察到一些明显的特征。例如,在热力图中可以看到糖尿病相关的指标[Outcome]与葡萄糖测试值Glucose呈现显著的相关性。具体而言,在数据中发现当血糖水平较高时(即Glucose数值较大),个体可能患有糖尿病。同样地,在分析中也显示出年龄Age与怀孕次数Pregnancies之间具有较强的相关性。
sns.pairplot()用于展示属性两两之间的关系,线性、非线性、相关等等。*
confusion matrix()是一种用于评估模型性能的关键工具,在机器学习领域中被广泛应用于分析和优化分类模型的效果。它通过构建一个基于真实类别与预测类别双重标准的矩阵来系统地汇总和展示数据集中的分类结果。该表格工具能够直观地反映模型对实际数据进行分类预测的结果情况,并根据不同的真实类别与预测类别的组合提供详细的统计信息。以下是如何呈现二分类问题中的典型混淆矩阵结构:

TP(True Positive):真阳性的数量,在真实情况和预测结果均为正的情况下计数
FN(False Negative):假阴性的数量,在真实情况为正但预测结果为负的情况下计数
FP(False Positive):假阳性的数量,在真实情况为负但预测结果为正的情况下计数
TN(True Negative):真阴性的数量,在真实情况和预测结果均为负的情况下计数
在二分类问题中,在讨论性能指标时我们通常使用精确度Precision和召回度Recall等概念来评估模型的表现效果。具体而言,在这里我们可以看到:精确度Precision=(真 positives)/(真 positives + 假正类);而召回度=(真 positives)/(真 positives + 真负类)。此外,在计算准确性时需要注意的是:准确性不仅涉及正确预测的实例(即对角线元素),还包括所有可能的实例。从该公式可以看出,在计算准确性时分子项仅由对角线元素构成。
Python中的sklearn库包含confusion_matrix()方法用于生成矩阵数据。具体而言,该函数的功能定义为:
sklearn.metrics.confusion_matrix(y_true, y_pred, labels=None, sample_weight=None):其中,
y_true表示样本的真实分类结果,
y_pred为模型预测的结果,
labels可选参数用于指定需要评估的具体分类类别,
而sample_weight则允许对不同样本赋予不同的权重以进行加权评估。
该函数能够生成一个混淆矩阵,
帮助评估分类模型的性能表现。

通过混淆矩阵可以看出,在测试集中有100例原本属于‘正常血糖’却被正确归类到‘正常血糖’类别中(即真阴性),其中44例的正常血糖病例成功地正确识别出来(即真阴性)。此外,在这测试集中共有23份原本属于‘正常血糖’却被错误分类到‘异常血糖’类别里的样本(即假阳性),以及还有20份正常的案例却未能正确识别出来(即假阴性)。
以案例为例,在寻找最佳K值的过程中采用了循环机制。该案例中采用循环方法得出了不同K值对应的准确率数据。图形直观地呈现了模型预测准确性与最近邻数量之间的关系。从图形分析可以看出,在选择一个最近邻居时模型在训练集中完全正确;当增加最近邻居的数量时发现,在训练集中准确性随之降低而在测试集中准确性提升;经过分析比较后确定最佳参数设置为K=9。

四、KNN算法

定义:KNN全称为K-Nearest Neighbors(K最近邻算法),是机器学习算法中最基础的一种分类方法之一。其基本思想是,在特征空间中找到与给定样本距离最近的前k个邻居。这些邻居中大多数属于某个类别,则该样本也属于这个类别并具有该类别的特征。其中参数k的选择至关重要,直接影响最终分类结果。


基于图中的示意图,在图中标注了需要进行分类的数据点(以绿色圆圈表示)。当取值K=3时,在这些待分类的数据点与其最近邻(共三个)中发现蓝三角数量较多,则可将这些数据划分为蓝三角类别;同样地,在K=5的情形下,则根据其最近邻(共五个)中红圆的数量多少进行划分。由此可见,在选择不同的参数设置时会直接影响最终的结果质量。值得注意的是
在数据处理中,点间距离的计算同样具有重要意义。常见的度量方式包括曼哈顿距离(即一范数)和欧式距离(即二范数)等。值得注意的是,在K近邻算法中,默认选择的是欧氏距离。举例而言,在二维空间中,两个点的间距计算较为直观且高效。具体而言,在二维平面中,两个坐标点(x1,y1)与(x2,y2)之间的欧氏距离可通过以下公式进行计算:d = \sqrt{(x2-x1)^2 + (y2-y1)^2}

将其拓展到多维空间,公示则变为如下:

K邻近算法通过计算预测样本与训练集所有样本的距离来进行分类,在完成距离计算后对各距离值进行排序,并选取排序后的前K个样本进行统计分析。最终根据各类别数量的多少确定最终分类结果为具有最高数量的类别即为预测结果。
2、如何确定Kmeans算法中的最佳聚类数目(k)?
(1)采用遍历法,在通常情况下,默认设置相对较小。具体操作为:通过遍历从2开始到某个上限,在每个给定的k值下执行以下步骤:计算每个样本群集的平均轮廓系数;最终选择具有轮廓系数最接近理想值的那个k值作为最佳聚类数量。(2)基于经验或借助数据分析与可视化手段获得。
3、算法优缺点比较
算法的优点 :
(1)思想简单,理论成熟,既可以用来做分类也可以用来做回归;
(2)可用于非线性分类;
(3)训练时间复杂度为O(n);
(4)准确度高,对数据没有假设,对outlier不敏感。
算法的缺点 :计算量大;样本不平衡问题(即有些类别的样本数量很多,而其它样本的数量很少);需要大量的内存;
需要考虑问题 :
(1)KNN的计算成本很高;
(2)所有特征应该标准化数量级,否则数量级大的特征在计算距离上会有偏移;
(3)在进行KNN前预处理数据,例如去除异常值,噪音等。
