1. 程式人生 > 其它 >機器學習入門 13 實戰:心臟病預測,補充:ROC曲線、召回率曲線

機器學習入門 13 實戰:心臟病預測,補充:ROC曲線、召回率曲線

尊重原創版權: https://www.gewuweb.com/hot/16250.html

機器學習入門 13 實戰:心臟病預測,補充:ROC曲線、召回率曲線

各位同學好,經過前幾章python機器學習的探索,想必大家對各種預測方法也有了一定的認識。今天我們來進行一次實戰,心臟病病例預測,本文對一些基礎方法就不進行詳細解釋,有疑問的同學可以看我前幾篇機器學習文章。

** 文末有完整程式碼和資料集。 **


1. 資料獲取

首先匯入資料處理所需要的庫檔案,再匯入心臟病病例資料,使用 .info() 函式檢查資料集中是否存在缺失值,本資料集不存在缺失值。

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)
邏輯迴歸演算法:原理、精確率、召回率、例項應用(癌症病例預測)

精準率用來計算查得準不準,結果為 ** 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')

資料集獲取:

完整程式碼:

# 心臟病資料分析
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')

最後有驚喜(別錯過哦)

躋身大廠是每一個程式設計師的夢想,也希望有機會可以大放異彩,成績斐然。不過,不積跬步無以至千里,理想和現實的距離是需要努力來不斷縮短的。

所以這裡我準備了一些禮包,希望能夠幫助到各位小夥伴。

★禮包1

,我會拉你進學習交流群,我們一起交流學習,報團打卡,群內更有眾多福利等你來解鎖喲,趕快加入我們吧!

★禮包2

❶Python全套電子書,200本總共6個G電子書資料,囊括Python各大領域。

❷Python練手專案,包括爬蟲、資料分析、機器學習、人工智慧、小遊戲開發。

小遊戲開發。**

更多內容參考: https://www.gewuweb.com/sitemap.html