【机器学习入门】(13) 实战:心脏病预测,补充: ROC曲线、精确率--召回率曲线,附python完整代码和数据集

【机器学习入门】(13) 实战:心脏病预测,补充: ROC曲线、精确率--召回率曲线,附python完整代码和数据集,第1张

【机器学习入门】(13) 实战:心脏病预测,补充: ROC曲线、精确率--召回率曲线,附python完整代码和数据

各位同学好,经过前几章python机器学习的探索,想必大家对各种预测方法也有了一定的认识。今天我们来进行一次实战,心脏病病例预测,本文对一些基础方法就不进行详细解释,有疑问的同学可以看我前几篇机器学习文章。文末有完整代码和数据集。


1. 数据获取

首先导入数据处理所需要的库文件,再导入心脏病病例数据,使用 .info() 函数检查数据集中是否存在缺失值,本数据集不存在缺失值。

数据集获取:链接:百度网盘 请输入提取码 提取码:a9wl

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 设置显示中文字体--宋体
plt.rcParams['font.sans-serif'] = ['SimSun']
# 设置字体大小
plt.rcParams['font.size'] = 10

#(1)文件读取
filepath = 'C:\Users\admin\.spyder-py3\test\文件处理\心脏病\心脏病数据.csv'
heart_df = pd.read_csv(filepath)
# 查看是否存在缺失值,该数据不存在空值
heart_df.info()

我们这个数据集中共有303行样本,14列特征数据,我简单介绍一下这些特征的意义。

age:年龄

sex:性别(1代表男性,0代表女性)

cp:胸部疼痛情况(1:典型心绞痛;2:非典型心绞痛;3:没有心绞痛;4:无症状)

trestbps:静息血压

chol:胆固醇

fbs:空腹血糖>120mg/dl (1:true;2:false)

restecg:静息心电图测量(0:普通;1:ST-T波异常;2:左心室肥大)

thalach:最高心跳率

exang:运动诱发心绞痛(1:yes;2:no)

oldpeak:运动相对于休息引起的ST抑制

slope:运动ST段的峰值斜率(1:上坡;2:平的;3:下坡)

ca:主要血管数目(0、1、2、3、4)

thal:一种血液疾病(1:正常;2:固定缺陷;3:可逆的缺陷)

target:是否患病(1:yes;2:no)


2. 数据分析可视化 2.1 患病分布

针对 target 列,统计有多少人患病,有多少人没患病,绘制条形图和饼图。首先 .value_count() 能统计出target列每一个唯一值出现了多少次。其中1表示患病,出现了165次,0表示没患病,出现了138次。

# 患病分布情况,统计有多少人患病
heart_counts = heart_df['target'].value_counts()

我们对患病情况绘图可视化。pandas中若对象为Series和Dataframe,可以直接在变量名后面跟 .plot() 进行绘制。在绘制饼图'pie'时也可以指定参数 ax=axes[1],表示画在画布的第二个位置。

# 设置画布fig,图像对象axes
fig,axes = plt.subplots(1,2,figsize=(10,5))  #创建1行2列的画布,并设置画布大小
# 绘制条形图
ax = heart_counts.plot(kind='bar',ax=axes[0])  #绘制条形图,画在第0个子图上,并返回axes对象
ax.set_title('患病分布')  #设置标题
ax.set_xlabel('1:患病,0:未患病')  # x轴名称
ax.set_ylabel('人数')  # y轴名称
# 绘制饼图,显示数值保留两位小数,显示%,数值对应的标签名
heart_counts.plot(kind='pie',autopct='%.2f%%',labels=['患病','未患病'])


2.2 性别与患病的分布 

绘制条形图,x轴代表性别,y轴代表人数,其中男性和女性分成患病的和没患病的。

使用seaborn库画图,其中.countplot() 绘图函数,自动计算性别'sex'中的人数,以'sex'的种类分x轴刻度,每个x轴下又以'target'进行划分,返回axes对象,data 代表绘图所需的数据,ax=ax1表示这张图的绘图位置。

plt.figure() # 创建画布
ax1 = plt.subplot(121)  # 图1在1行2列的第1个位置
ax = sns.countplot(x='sex',hue='target',data=heart_df,ax=ax1)
ax.set_xlabel('0:女性,1:男性')  #指定x坐标轴名称

根据是否患病绘制饼图,即在患病的人中男性和女性分别占了百分之几,以及在没患病的人中男性和女性分别占比多少。其中 heart_df[heart_df['target']==0] 表示找出所有没有患病(target为0)的所有的行,然后 .sex 为找到指定所有没患病的数据中的'sex'特征列,最后 .value_counts()函数自动计算该列中所有唯一值出现的次数。

# 先找到没有患病的人的性别统计
ax2 = plt.subplot(222)  #该图在画布上的位置,2行2列中的第二个位置
heart_no_counts = heart_df[heart_df['target']==0].sex.value_counts()  #获取没患病的,锁定sex列,统计
heart_no_counts.plot(kind='pie',autopct='%.2f%%',labels=['男性','女性'],ax=ax2)
ax2.set_title('未患病比例')

# 再找到患病的性别统计
ax3 = plt.subplot(224)
heart_yes_counts = heart_df[heart_df['target']==1].sex.value_counts()
heart_yes_counts.plot(kind='pie',autopct='%.2f%%',labels=['男性','女性'],ax=ax3)
ax3.set_title('患病比例')


2.3 年龄与患病分析

首先我们先笼统的看一下年龄与患病的条形图,以数据中出现的所有年龄的唯一值分x轴刻度,每个x轴又以'target'进行划分成患病和没患病。

# 设置画布大小,并设置2行1列
fig,axes = plt.subplots(2,1,figsize=(20,10))
# 每个年龄有多少人患病、有多少人没患病,绘制条形图
sns.countplot(x='age',hue='target',data=heart_df,ax=axes[0])

如果笼统的将每个年龄都分一个x轴刻度,会非常混乱,因此我们再来划分一下年龄段。由于该数据中,年龄最小为29,最大为77,因此我们划分[0,45)为青年,[45,59)为中年,60以上为老年。

# 对age数据按bins划分的区间分组,左闭右开,labels设置分组名
age_cut = pd.cut(heart_df.age,bins=[0,45,60,100],include_lowest=True,right=False,labels=['青年','中年','老年'])
# 统计绘图,条形图,每个年龄段有多少人
age_cut.value_counts().plot(kind='bar')

 

我们完成了年龄的划分,现在需要将划分好的年龄段,与是否患病拼接在一起。绘制条形图:每个年龄段患病和没患病的分别有多少人;绘制饼图:患病的人中三个年龄段的占比,以及在没患病的人中三个年龄段的占比。

pd.concat([变量1,变量2],axis=0或1) 

该函数将两个Series或Dataframe数据拼接到一起,axis=1列方向拼接,axis=0行方向拼接

# 指定水平方向拼接,指定轴axis=1
age_target_df = pd.concat([age_cut,heart_df['target']],axis=1)

# 绘制条形图,每个年龄段有多少人得病,有多少人没得病
plt.figure()
ax4 = plt.subplot(121)
sns.countplot(x='age',hue='target',data=age_target_df,ax=ax4)
ax4.set_title('年龄-患病情况')

# 饼图,绘制患病的人中,每个年龄段所占比例
ax5 = plt.subplot(222)
# 所有患病的人中,对年龄特征计数
age_target_df[age_target_df.target==1].age.value_counts().plot(kind='pie',autopct='%.2f%%',labels=['青年','中年','老年'],ax=ax5)
ax5.set_title('患病-年龄关系')

# 饼图,绘制没有患病的人中,每个年龄段的比例
ax6 = plt.subplot(224)
age_target_df[age_target_df.target==0].age.value_counts().plot(kind='pie',autopct='%.2f%%',labels=['青年','中年','老年'],ax=ax6)
ax6.set_title('没患病-年龄关系')


2.4 统一查看所有的特征分布

由于特征值较多,本文也就不一一列出来分析了,我们可以用一个循环打印所有特征的分布情况,从第一张图中可以看出年龄的分布情况。

# 有多少个特征就画多少个直方图,一共有14个特征
fig,axes = plt.subplots(2,7,figsize=(40,10))
# 用一个循环绘图
for x in range(14):
    plt.subplot(2,7,x+1)  #设置当前画板为当前画图对象,x+1表示第几个画布
    sns.distplot(heart_df.iloc[:,x],kde=True)  # 绘制直方图,所有特征下面的值的直方图,并显示曲线。取第x列的所有行
# 自动调整布局,轻量化调整
plt.tight_layout()


2.5 特征之间的关联性

在pandas库中我们可以使用函数 .corr() 来查看每个特征之间的相互关系。

相关性分析:相关性系数 |r| 在[0,0.3)是低相关,在[0,0.8)是中相关,在[0.8,1]高度相关

 低度相关可以认为是特征值独立的

#(4)每个特征之间的关联性
# pandas库中 .corr() 函数反应每个特征之间两两关联程度
heart_corr = heart_df.corr()

获得相关关系后我们可以通过热力图的方式来将这种关系可视化

#(5)绘制关联性的热力图
plt.figure(figsize=(8,5))
# 改变颜色cmap,显示相关性数据annot
sns.heatmap(heart_df.corr(),cmap='Blues',annot=True)


3. 模型建立 3.1 数据预处理

首先,划分特征值数据和目标值数据,即target这一列代表的目标,其他都是特征值。

# 划分特征值和目标值
features = heart_df.drop(columns=['target'])  # 删除target这一列,剩下的就是特征值
targets = heart_df['target']  # target这一列是目标值

由于特征值中存在两种类型的数据,离散型数据和连续型数据。

对离散型数据转换成字符串类型,后期进行标准化的时候,不会对离散型数据处理。将离散型数据,从普通的0,1,2这些数字,转换成字符串表示。

原特征值数据中的 sex,cp,fbs,exang,slope,thal,restecg,ca 特征列都是离散型数据,因此将这些列转变成字符串类型。

features[['sex','cp','fbs','exang','slope','thal','restecg','ca']] = features[['sex','cp','fbs','exang','slope','thal','restecg','ca']].astype('object')

将连续型数据和离散型数据分开处理

对离散型数据进行特征抽取,one-hot编码,提取文本信息。使用pandas方法:pd.get_dummies()

对连续型数据进行标准化处理。然后将处理完成的两种数据重新合并。

# 接收离散型数据
features_dis = features[['sex','cp','fbs','restecg','exang','slope','ca','thal']]
# 接收连续型数据
features_con = features.drop(columns=features_dis.columns)

# 离散数据one-hot编码--即字典特征提取
features_dis = pd.get_dummies(features_dis)

# 连续型数据标准化 
from sklearn.preprocessing import StandardScaler  #导入标准化方法
features_con = pd.Dataframe(StandardScaler().fit_transform(features_con))  #将标准化之后的数据变成Dataframe类型

# 按列方向拼接在一起 .join() ,用新变量features_temp接收
features_temp = features_con.join(features_dis)


3.2 划分训练集和测试集

将已经处理好的特征值features_temp,和目标值targets传入划分函数,以25%测试数据,75%训练数据划分训练集和测试集。

#(8)切分测试集和训练集
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(features_temp,targets,test_size=0.25)

3.3 预测方法

之前我们介绍了许多分类预测的方法,比如:k近邻、朴素贝叶斯、决策树、逻辑回归等,我这里用K近邻方法演示一下。如果有同学想用其他方法只需要将下面这段代码换成别的预测方法就可以了,如果有不清楚的可以看我的前几篇文章。y_predict 种存放预测结果

# 导入k近邻方法
from sklearn.neighbors import KNeighborsClassifier
# 接收k近邻方法,设置根据多少个点来决定属于哪个分类
knn = KNeighborsClassifier(n_neighbors=5)
# 训练函数 .fit()
knn.fit(x_train,y_train)
# 预测
y_predict = knn.predict(x_test)

3.4 模型验证

对于分类预测我们之前一直使用的是.score()评分法计算准确率。在这里我将介绍其他4种模型验证方法。

(1)交叉验证法

交叉验证法计算模型准确率的方法可以这样理解,例如,将模型分成3等分。首先,将1、2份数据用于训练,第3份数据用于测试;再将1、3份数据用于训练,第2份数据用于测试;再将2、3份数据用于训练,第1份数据用于测试。这样,每一份数据都有机会用于训练和测试。提高了计算准确率。

导入方法: from sklearn.model_selection import cross_val_score 计算方法: cross_val_score(算法对象, 未划分的特征值, 目标值)
# 导入交叉验证法--检测模型准确率
from sklearn.model_selection import cross_val_score
# 传入算法对象、x特征值、y目标值、cv=几等分
cross = cross_val_score(knn,features_temp,targets)  #x_train和x_test已经被分割过了;这里会自动分割
result_cross = cross.mean()  #计算交叉验证的平均值

 

(2)精准率

精准率、召回率、F1-score综合评分,这三种理论我在之前的文章写过,这里不再做过多讲解,见下文第2小节:【机器学习入门】(9) 逻辑回归算法:原理、精确率、召回率、实例应用(癌症病例预测)附python完整代码和数据集

精准率用来计算查得准不准,结果为 0.829

导入方法: from sklearn.metrics import precision_score 计算方法: precision_score(真实值, 预测值)
from sklearn.metrics import precision_score
# 传入真实值和预测值
result_precision = precision_score(y_test,y_predict)
(3)召回率

召回率用来计算查得全不全,结果为 0.928

导入方法: from sklearn.metrics import recall_score 计算方法: recall_score(真实值, 预测值)
# ==3== 计算召回率,查得全不全
from sklearn.metrics import recall_score
result_recall = recall_score(y_test,y_predict)
(4)F1-score综合指标

综合了精准率和召回率来计算,结果为 0.876

导入方法: from sklearn.metrics import f1_score 计算方法: f1_score(真实值, 预测值)
# ==4== F1-score综合评分
from sklearn.metrics import f1_score
result_f1 = f1_score(y_test,y_predict)

4. 召回率--精准率曲线、ROC曲线

4.1 召回率--精准率曲线

x轴为召回率,y轴为精准率。曲线越靠近右上角,召回率越接近1,精准率越接近1。则左下部分的面积越大,模型越好。

(1)计算精准率、召回率、阈值 导入方法: from sklearn.metrics import precision_recall_curve 使用方法: precision_recall_curve()

该函数的返回值为:精准率、召回率、阈值(计算结果大于它就判定是预测到了)

该函数的参数为:真实值,预测到目标的概率

预测概率的计算方法: .predict_proba(测试值)

(2)计算平均精确率 导入方法: from sklearn.metrics import average_precision_score 使用方法: average_precision_score(真实值, 预测到目标的概率)
# 精准率和召回率曲线绘制
from sklearn.metrics import precision_recall_curve
# 参数:y真实值,预测到的概率,
# 预测概率,第一列存放,得了心脏病的概率
y_predict_proba = knn.predict_proba(x_test)
# 第1列存放预测到得了心脏病的概率
# 返回值是一个元组,分别是,精准率,召回率,阈值(大于多少判定为是心脏病)
precisions,recalls,thretholds = precision_recall_curve(y_test,y_predict_proba[:,1])

# 计算平均精准率
from sklearn.metrics import average_precision_score
# 参数:y_true真实值,y_score预测到的概率
precisions_average = average_precision_score(y_test,y_predict_proba[:,1])

# 绘图,召回率x轴,精准率y轴
fig,axes = plt.subplots(1,2,figsize=(10,5)) #设置画布,1行2列
# 在第一张画布上绘图
axes[0].plot(precisions,recalls) #横坐标精确率,纵坐标召回率
axes[0].set_title(f'平均精准率:{round(precisions_average,2)}')
axes[0].set_xlabel('召回率')
axes[0].set_ylabel('精准率')

4.2 ROC曲线

以FP为x轴,TP为y轴。FP为预测结果为正例,实际上是假例。TP为预测结果是正例,实际上也是正例。曲线越靠近左上角越好 ,FP=0,TP=1。右下部面积越大越好。AUC得分为ROC曲线右下部分面积

(1)计算FP、TP、阈值 导入方法: from sklearn.metrics import roc_curve 使用方法: roc_curve(y_test, y_predict_proba)

该函数的返回值为:FP、TP、阈值

该函数的参数为:真实值,预测到目标的概率

(2)计算AUC得分 导入方法: from sklearn.metrics import auc 计算方法: auc(返回值FP, 返回值TP)
# ROC曲线绘制
from sklearn.metrics import roc_curve
# 传入参数:y_true真实值,y_predict_proba预测到的概率
# 产生返回值,FP、TP、阈值
fpr,tpr,thretholds = roc_curve(y_test,y_predict_proba[:,1])
# 计算AUC得分
from sklearn.metrics import auc
# 传入参数:fpr、tpr
AUC = auc(fpr,tpr) 

# 绘图
axes[1].plot(fpr,tpr) #传入FP和TP的值
axes[1].set_title(f'AUC值为{round(AUC,2)}')
axes[1].set_xlabel('FPR')
axes[1].set_ylabel('TPR')


数据集获取:

 链接:百度网盘 请输入提取码 提取码:a9wl

完整代码:

# 心脏病数据分析
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimSun']
plt.rcParams['font.size'] = 10

#(1)文件读取
filepath = 'C:\Users\admin\.spyder-py3\test\文件处理\心脏病\心脏病数据.csv'
heart_df = pd.read_csv(filepath)

# 查看是否存在缺失值,该数据不存在空值
heart_df.info()

#(2)数据分析

# ==1== 患病分布
# 患病分布情况,统计有多少人患病
heart_counts = heart_df['target'].value_counts()
# 165人患病,138人没患病,绘制条形图
# pandas中若为Series对象或Dataframe对象可直接进行绘制

# 设置画布fig,axes未图像对象
fig,axes = plt.subplots(1,2,figsize=(10,5))
# 绘制条形图
ax = heart_counts.plot(kind='bar',ax=axes[0])  #绘制条形图,画在第0个子图上,并返回axis对象
ax.set_title('患病分布')  #设置标题
ax.set_xlabel('1:患病,0:未患病')
ax.set_ylabel('人数')
# 绘制饼图,显示数值保留两位小数,显示%,数值对应的标签名
heart_counts.plot(kind='pie',autopct='%.2f%%',labels=['患病','未患病'])


# ==2== 绘制性别与患病的分布
# 绘制条形图,x轴为性别,每个性别分为患病和没患病
# counplot自动计算性别'sex'中的人数,以'sex'的种类分x轴刻度,每个x轴下又以'target'进行划分,返回axes对象
plt.figure()
ax1 = plt.subplot(121)
ax = sns.countplot(x='sex',hue='target',data=heart_df,ax=ax1)
ax.set_xlabel('0:女性,1:男性')  #指定x坐标轴名称

# 根据是否患病绘制饼图,患病的人中男女占比是多少,没患病的男女占比是多少
ax2 = plt.subplot(222)
# 先找到没有患病的人的性别统计
heart_no_counts = heart_df[heart_df['target']==0].sex.value_counts()  #获取没患病的,锁定sex列,统计
heart_no_counts.plot(kind='pie',autopct='%.2f%%',labels=['男性','女性'],ax=ax2)
ax2.set_title('未患病比例')

# 再找到患病的性别统计
ax3 = plt.subplot(224)
heart_yes_counts = heart_df[heart_df['target']==1].sex.value_counts()
heart_yes_counts.plot(kind='pie',autopct='%.2f%%',labels=['男性','女性'],ax=ax3)
ax3.set_title('患病比例')


# ==3== 年龄与患病分析
# 查看年龄的最小值和最大值
age_min,age_max = heart_df.age.min(),heart_df.age.max() 
# 设置画布大小,并设置2行1列
fig,axes = plt.subplots(2,1,figsize=(20,10))
# 每个年龄有多少人患病、有多少人没患病,绘制条形图
sns.countplot(x='age',hue='target',data=heart_df,ax=axes[0])

# 将年龄段划分。0-45青年,45-59中年,60以上老年
# 对age数据按bins划分的区间分组,左闭右开,labels设置分组名
age_cut = pd.cut(heart_df.age,bins=[0,45,60,100],include_lowest=True,right=False,labels=['青年','中年','老年'])
# 统计绘图,条形图,每个年龄段有多少人
age_cut.value_counts().plot(kind='bar')


# concat将两个对象拼接成一个,将年龄段与是否患病拼接在一起
# 指定水平方向拼接,指定轴axis=1
age_target_df = pd.concat([age_cut,heart_df['target']],axis=1)

# 绘制每个年龄段有多少人得病,有多少人没得病
plt.figure()
ax4 = plt.subplot(121)
sns.countplot(x='age',hue='target',data=age_target_df,ax=ax4)
ax4.set_title('年龄-患病情况')

# 绘制患病的人中,每个年龄段所占比例
ax5 = plt.subplot(222)
# 所有患病的人中,对年龄特征计数
age_target_df[age_target_df.target==1].age.value_counts().plot(kind='pie',autopct='%.2f%%',labels=['青年','中年','老年'],ax=ax5)
ax5.set_title('患病-年龄关系')

# 绘制没有患病的人中,每个年龄段的比例
ax6 = plt.subplot(224)
age_target_df[age_target_df.target==0].age.value_counts().plot(kind='pie',autopct='%.2f%%',labels=['青年','中年','老年'],ax=ax6)
ax6.set_title('没患病-年龄关系')


#(3)统一查看所有特征的分布情况
# 有多少个特征就画多少个直方图,一共有14个特征
fig,axes = plt.subplots(2,7,figsize=(40,10))
# 用一个循环绘图
for x in range(14):
    plt.subplot(2,7,x+1)  #设置当前画板为当前画图对象
    sns.distplot(heart_df.iloc[:,x],kde=True)  # 绘制直方图,所有特征下面的值的直方图,并显示曲线。取第x列的所有行
# 自动调整布局,轻量化调整
plt.tight_layout()


#(4)每个特征之间的关联性
# pandas库中 .corr() 函数反应每个特征之间两两关联程度
heart_corr = heart_df.corr()
# 相关性分析:相关性系数|r|在[0,0.3)是低相关,在[0,0.8)是中相关,在[0.8,1]高度相关
# 低度相关可以认为是特征值独立的

#(5)绘制关联性的热力图
plt.figure(figsize=(8,5))
sns.heatmap(heart_df.corr(),cmap='Blues',annot=True) #改变颜色cmap,显示数据annot


# 建模 *** 作
#(6)数据预处理
# 划分特征值和目标值
features = heart_df.drop(columns=['target'])  # 删除target这一列,剩下的就是特征值
targets = heart_df['target']  # target这一列是目标值

# 存在两种特征值,离散型和连续型
# 对离散型数据转换成字符串类型,后期进行标准化的时候,不会对离散型数据处理
# 将离散型数据,从普通的0,1,2这些数字,转换成字符串表示

features[['sex','cp','fbs','exang','slope','thal','restecg','ca']] = features[['sex','cp','fbs','exang','slope','thal','restecg','ca']].astype('object')

#(7)将连续型数据和离散型特征数据分开处理
# 对离散性数据进行one-hot编码 pd.get_dummies()
# 对连续型数据进行标准化处理
# 将处理后的数据再合并
features_dis = features[['sex','cp','fbs','restecg','exang','slope','ca','thal']]
features_con = features.drop(columns=features_dis.columns)

# 离散数据one-hot编码--即字典特征提取
features_dis = pd.get_dummies(features_dis)

# 连续性数据标准化 
from sklearn.preprocessing import StandardScaler
features_con = pd.Dataframe(StandardScaler().fit_transform(features_con))

# 组合在一起
features_temp = features_con.join(features_dis)


#(8)切分测试集和训练集
from sklearn.model_selection import train_test_split
x_train,x_test,y_train,y_test = train_test_split(features_temp,targets,test_size=0.25)

#(9)K近邻分类预测
# 导入k近邻方法
from sklearn.neighbors import KNeighborsClassifier
# 接收k近邻方法,设置根据多少个点来决定属于哪个分类
knn = KNeighborsClassifier(n_neighbors=5)
# 训练
knn.fit(x_train,y_train)
# 预测
y_predict = knn.predict(x_test)

# 模型验证:
# ==1== 交叉验证法计算模型准确率。
from sklearn.model_selection import cross_val_score
# 传入算法对象、x特征值、y目标值、cv=几等分
cross = cross_val_score(knn,features_temp,targets)  #x_train和x_test已经被分割过了;这里会自动分割
result_cross = cross.mean()

# ==2== 计算精准率,查得准不准
from sklearn.metrics import precision_score
# 传入真实值和预测值
result_precision = precision_score(y_test,y_predict)

# ==3== 计算召回率,查得全不全
from sklearn.metrics import recall_score
result_recall = recall_score(y_test,y_predict)

# ==4== F1-score综合评分
from sklearn.metrics import f1_score
result_f1 = f1_score(y_test,y_predict)


# 精准率和召回率曲线绘制
from sklearn.metrics import precision_recall_curve
# 参数:y真实值,预测到的概率,
# 预测概率,第一列存放,得了心脏病的概率
y_predict_proba = knn.predict_proba(x_test)
# 第1列存放预测到得了心脏病的概率
# 返回值是一个元组,分别是,精准率,召回率,阈值(大于多少判定为是心脏病)
precisions,recalls,thretholds = precision_recall_curve(y_test,y_predict_proba[:,1])

# 计算平均精准率
from sklearn.metrics import average_precision_score
# 参数:y_true真实值,y_score预测到的概率
precisions_average = average_precision_score(y_test,y_predict_proba[:,1])

# 绘图,召回率x轴,精准率y轴
fig,axes = plt.subplots(1,2,figsize=(10,5)) #设置画布,1行2列
# 在第一张画布上绘图
axes[0].plot(precisions,recalls)
axes[0].set_title(f'平均精准率:{round(precisions_average,2)}')
axes[0].set_xlabel('召回率')
axes[0].set_ylabel('精准率')


# ROC曲线绘制
from sklearn.metrics import roc_curve
# 传入参数:y_true真实值,y_predict_proba预测到的概率
# 产生返回值,FP、TP、阈值
fpr,tpr,thretholds = roc_curve(y_test,y_predict_proba[:,1])
# 计算AUC得分
from sklearn.metrics import auc
# 传入参数:fpr、tpr
AUC = auc(fpr,tpr) 

# 绘图
axes[1].plot(fpr,tpr) #传入FP和TP的值
axes[1].set_title(f'AUC值为{round(AUC,2)}')
axes[1].set_xlabel('FPR')
axes[1].set_ylabel('TPR')

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5572346.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存