KNN心脏病数据集分类

1.实验目的

掌握KNN的算法原理和具体分类实验方法

2.KNN原理

KNN是通过测量不同特征值之间的距离进行分类。
如果一个样本在特征空间中的k个最邻近的样本中的大多数属于某一个类别,则该样本也划分为这个类别。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。
算法的描述:

Created with Raphaël 2.2.0 开始 计算测试数据与各个训练数据之间的距离 按照距离的递增关系进行排序 选取距离最小的K个点 确定前K个点所在类别的出现频率 返回前K个点中出现频率最高的类别作为测试数据的预测分类 结束

3.实验数据

实验数据来自Kaggle平台
Heart Disease UCI数据集包含14个属性,分类的target为是否患有心脏病,分别由0,1表示。
属性包括:

  1. age 年龄
  2. sex 性别
  3. chest pain type 胸痛的类型
  4. resting blood pressure 静息血压
  5. serum cholestoral in mg/dl 血清胆固醇含量
  6. fasting blood sugar > 120 mg/dl 空腹血糖
  7. resting electrocardiographic results (values 0,1,2) 静息心电图结果
  8. maximum heart rate achieved 最高心跳率
  9. exercise induced angina 运动诱发的心绞痛
  10. oldpeak = ST depression induced by exercise relative to rest 运动引起的ST抑制(相对于休息)
  11. the slope of the peak exercise ST segment 运动ST段的峰值斜率
  12. number of major vessels (0-3) colored by flourosopy 主要血管数目(0-3)
  13. thal: 3 = normal; 6 = fixed defect; 7 = reversable defect 地中海贫血

3.1数据分析

1.导入必要的库

# 基本操作
import numpy as np
import pandas as pd
import pandas_profiling

# 数据可视化
import matplotlib.pyplot as plt
import seaborn as sns

# 高级可视化
import plotly.offline as py
from plotly.offline import init_notebook_mode, iplot
import plotly.graph_objs as go
init_notebook_mode(connected = True)
from bubbly.bubbly import bubbleplot

2.观察数据

data = pd.read_csv('heart.csv')
data.head()
agesexcptrestbpscholfbsrestecgthalachexangoldpeakslopecathaltarget
063131452331015002.3001
137121302500118703.5002
241011302040017201.4202
356111202360117800.8202
457001203540116310.6202

共303行14列

data.shape
#(303,14)

3.绘制heat map
任意两个变量的相关系数使用函数data.corr()得到,上面的heat map显示了给定数据集的不同属性之间的相关性

# making a heat map
plt.rcParams['figure.figsize'] = (20, 15) #设置图像细节,显示图像的最大范围
plt.style.use('ggplot')

sns.heatmap(data.corr(), annot = True, cmap = 'Wistia')
plt.title('Heatmap for the Dataset', fontsize = 20)
plt.show()

图1 相关系数热力图
从该热力图可以看出,数据集中给出的几乎所有特征/属性之间的相关性都很低。
4.观察患者的年龄分布

# 患者年龄分布
import warnings
warnings.filterwarnings('ignore')

plt.style.use('fivethirtyeight')
plt.rcParams['figure.figsize'] = (15, 5)
sns.distplot(data['age'], color = 'cyan')
plt.title('Distribution of Age', fontsize = 20)
plt.show()

患者年龄分布
5.绘制出患者的性别分布

size = data['sex'].value_counts()
colors = ['lightblue', 'lightgreen']
labels = "Male", "Female"
explode = [0, 0.01]

my_circle = plt.Circle((0, 0), 0.7, color = 'white') #(0,0)为圆心,0.7为半径

plt.rcParams['figure.figsize'] = (9, 9)
plt.pie(size, colors = colors, labels = labels, shadow = True, explode = explode, autopct = '%.2f%%') #绘制一个饼状图,参数explode为离开圆心的距离,autopct数据标签保留小数点后两位
plt.title('Distribution of Gender', fontsize = 20)
p = plt.gcf() #获取当前图标
p.gca().add_artist(my_circle) #p.gca()获取子图,add_artisi()将画好的饼状图添加进去
plt.legend()
plt.show()

性别分布
6.绘制出目标类别的分布
样本类别分布比较均匀

# plotting the target attribute

plt.rcParams['figure.figsize'] = (15, 7)
plt.style.use('seaborn-talk')
sns.countplot(data['target'], palette = 'pastel') #使用条形图显示每个分类中的值,参数palette为选择色调
plt.title('Distribution of Target', fontsize = 20)
plt.show()

样本类别分布
7.绘制属性静息血压与类别的关系图
图为,患者静息血压与患者是否有心脏病之间的二元图,由图可知不易患病的人的血压略高于易患病的人。

plt.rcParams['figure.figsize'] = (12, 9)
sns.boxplot(data['target'], data['trestbps'], palette = 'viridis') #绘制箱形图以显示类别的分布
plt.title('Relation of tresbps with target', fontsize = 20)
plt.show()

箱型图包括最大值、最小值、中位数、及上下四分位数,上面的点为异常值。四分位数(Quartile)也称四分位点,是指在统计学中把所有数值由小到大排列并分成四等份,处于三个分割点位置的数值。
在这里插入图片描述
8.绘制胆固醇与类别的关系图
由图可知,与不患病的患者想比,患病的患者的胆固醇水平更高,我们可以推断胆固醇水平在是否得心脏病中起较大的影响作用。

plt.rcParams['figure.figsize'] = (12, 9)
sns.violinplot(data['target'], data['chol'], palette = 'colorblind') #绘制小提琴图
plt.title('Relation of Cholestrol with Target', fontsize = 20, fontweight = 30)
plt.show()

小提琴图 (Violin Plot) 用于显示数据分布及其概率密度。
这种图表结合了箱形图和密度图的特征,主要用来显示数据的分布形状。中间的黑色粗条表示四分位数范围,从其延伸的幼细黑线代表 95% 置信区间,而白点则为中位数。
胆固醇与类别
9.绘制静息心电图与类别的关系图
由图中柱状图可以发现,在不患病的患者中restecg值为0的人数显著较高,在患病的患者中restecg值为1的人数明显较多

plt.rcParams['figure.figsize'] = (12, 9)
dat = pd.crosstab(data['target'], data['restecg']) #crosstab交叉表,可以统计出每类'target'对应着多少'restecg'类
dat.div(dat.sum(1).astype(float), axis = 0).plot(kind = 'bar', 
                                                 stacked = False, 
                                                 color = plt.cm.rainbow(np.linspace(0, 1, 4)))
plt.title('Relation of ECG measurement with Target', fontsize = 20, fontweight = 30)
plt.show()

静息心电图与类别
10.绘制血管数与类别关系图
由图我们可以看出,不患病患者血管数整体较低,而患病患者血管数整体较高;即血管数越多,患心脏病的机会就越高

sns.boxenplot(data['target'], data['ca'], palette = 'Reds')
plt.title('Relation between no. of major vessels and target', fontsize = 20, fontweight = 30)
plt.show()

血管数
11.绘制年龄与类别关系图
患病与不患病患者的年龄分布没有明显差距,可知,无论年龄大小都要注意心脏的问题。

plt.rcParams['figure.figsize'] = (15, 9)
sns.swarmplot(data['target'], data['age'], palette = 'winter', size = 10)#绘制具有不重叠点的分类散点图。
plt.title('Relation of Age and target', fontsize = 20, fontweight = 30)
plt.show()

在这里插入图片描述
12.绘制性别与类别关系图
male = 1, female = 0
由图中可知,在不患病的病人中,男性比女性明显较多;在患病人群中,男性和女性数量几乎相同

sns.boxenplot(data['target'], data['sex'], palette = 'Set3')
plt.title('Relation of Sex and target', fontsize = 20, fontweight = 30)
plt.show()

在这里插入图片描述
13.地中海贫血与类别关系图
与不易患心脏病的患者相比,患有心脏病的患者得地中海贫血症的可能性较小

sns.boxenplot(data['target'], data['thal'], palette = 'magma')
plt.title('Relation between Target and Blood disorder-Thalessemia', fontsize = 20, fontweight = 30)
plt.show()

在这里插入图片描述

4.实验结果及分析

使用KNN进行分类
随着K值得增加,一开始训练准确率会增高,然后趋于平稳,从K=155开始,准确率一直下降

from sklearn.neighbors import KNeighborsClassifier
k_score = []
k_range = range(1,228)
for k in range(1,228):
    knn = KNeighborsClassifier(n_neighbors=k)
    knn.fit(X_train_std,y_train)
    k_score.append([k,knn.score(X_test_std,y_test)])
k_score = np.array(k_score)
k_score = pd.DataFrame(k_score,columns=['Value of K for KNN','Score'])
fmri = sns.load_dataset("fmri")
ax = sns.lineplot(data=k_score,x="Value of K for KNN", y="Score",)

在这里插入图片描述
当k = 7时,准确率最高
Training Accuracy : 0.8546255506607929
Testing Accuracy : 0.868421052631579

precisionrecallf1-scoresupport
00.900.790.8433
10.850.930.8943
accuracy0.8776
macro avg0.870.860.8676
weighted avg0.870.870.8776
  • 9
    点赞
  • 160
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值