决策树算法与python——心脏病预测
文章目錄
- 前言
- 一、介紹
- 二、過程
- 1.引入庫
- 2.數據處理
- 讀取數據并且述整體信息
- 數據清洗與映射
- 3.建模
- 1.決策樹算法介紹
- 2.擬合過程
- 4.修正與優化
- 三、總結
前言
1.學習記錄,如果能夠幫助到你那就更好!😊2.不是醫學生,可能對解讀某些變量有偏差.
3.數據來源于[Kaggle](https://www.kaggle.com/fedesoriano/heart-failure-prediction)
一、介紹
數據來源于kaggle的Heart Failure Prediction 的數據集。
心血管疾病是全球頭號死因,估計每年有1790萬人喪生,占全球死亡總數的31%。心力衰竭是 CVD 引起的常見事件,此數據集包含 11 個可用于預測可能的心臟病的功能。
心血管疾病患者或心血管風險高的人(由于存在一種或多個危險因素,如高血壓、糖尿病、高脂血癥或已經建立的疾病)需要早期發現和管理,其中機器學習模型可以有很大的幫助。
變量屬性:
13.HeartDisease: 輸出類 [1: 心臟病, 0: 正常]
二、過程
1.引入庫
使用的相關庫介紹:
2.數據處理
讀取數據并且述整體信息
data=pd.read_csv('D:/心臟病預測/heart.csv') data.info()得到下列信息:
數據總共918行,共12列,總體無缺失值。
數據類型:一個浮點,6個整數,5個字符串。
隨機查看10條數據
可以看到數據基本干凈而且清晰。
根據決策樹的數據集要求,需要對以下變量做處理:
- Sex,ChestPainType,RestingECG,ExerciseAngina,ST_Slope,這些名義型變量都需要做數值映射。
- Age,RestingBP,Cholesterol,MaxHR,Oldpeak,這些連續型變量都需要做數值替換。
數據清洗與映射
關于名義數據映射操作:
先看“ChestPainType”取值,總共有哪些類型:
value_counts()方法,統計變量值類型。
例如:ChestPainType中,共有4種變量值類型,其中“ASY”出現頻次為496次。
2.再根據變量值的類型,建立映射字典。
就拿”Sex“這一變量為例,”M“男性就映射成0,”F“女性就映射成1.
3.最后使用map方法進行映射
'ChestPainType’列映射后于映射前的對比:
這五個名義值數據類型處理思路并沒有較大的出入。
直接上代碼,詳細信息看注釋:
關于連續型變量的映射操作:
以’RestingBP’變量為例,
data['RestingBP'].value_counts()看下變量取值情況
發現前面都很正常哈,就有一個非常離譜,屬于異常數據。
按照現實情況,如果休息時心率為0,這人就直接掛了啊😓。
再用pyplot畫個散點圖,很容易就看到了:
因為只有一條,所以刪除這條異常數據,不會對總體造成多大影響
drop方法刪除指定索引行。
這里先提取’RestingBP’列’RestingBP’值為0的索引,找到后再刪除。
再看眼數據,是正常的了。
在網站上了解搜索關于’RestingBP’休息血壓后發現,該取值為90mm Hg到140mm Hg為正常。
于是據此打算劃分為三類,一類是偏高,二類是正常,三類是偏低。
代碼如下:
定義一個帶參數的替換規則函數,然后apply
apply是pandas非常靈活的一個方法,相當于遍歷行或者列,對數據操作(參數設置)
關于apply說明:
pandas 的 apply() 函數可以作用于 Series 或者整個 DataFrame,功能也是自動遍歷整個 Series 或者
DataFrame, 對每一個元素運行指定的函數。
接下來是’Cholesterol’血清膽固醇,百度詞條。
雖然這個變量在百度詞條里,根據年齡階段有不同標準,
但我發現這些數據的年齡,都是分布在成年人范圍
所以就按成年人標準劃分,假如數據年齡分布包括小孩什么的,要嚴謹一點的話,還是要根據年齡再分不同標準。
在詞條里,成年人的血清膽固醇為110-230mg/dl。
看分布:
不知道這數據出了什么問題😓,三百多和不到五百多這里的大部分數據都變成了0。
本人不是醫學生,但感覺0肯定是數據錯了,還有超過400以上也挺離譜
好在異常數據較少,而且不會影響總體的分布,選擇直接刪除。
再看,正常了
如法炮制,做映射
"MaxHR"的處理
看了統計描述與分布圖,數據沒有問題。
網上沒有找到相關正常值的文章。
于是決定根據統計規律劃分,
把這列大小排序后,畫出折線圖,發現有兩個明顯的轉折點,就按這個分類。
當然有更好的辦法那就更好。
"Oldpeak"的處理
依舊是前面分析的思路,不贅述。
"Oldpeak"分為四類。
“Age”的處理
數據年齡范圍為28-77,根據國際標準劃分,成熟期(29—40歲)、中年(41—65歲)、老年(66歲以后)。
重置一下序列
data.reset_index(drop=True, inplace=True)最終得到這份能直接建模的數據:
3.建模
1.決策樹算法介紹
終于到建模過程了。
關于決策樹算法:
決策樹(Decision
Tree)是在已知各種情況發生概率的基礎上,通過構成決策樹來求取凈現值的期望值大于等于零的概率,評價項目風險,判斷其可行性的決策分析方法,是直觀運用概率分析的一種圖解法。由于這種決策分支畫成圖形很像一棵樹的枝干,故稱決策樹。在機器學習中,決策樹是一個預測模型,他代表的是對象屬性與對象值之間的一種映射關系。Entropy
= 系統的凌亂程度,使用算法ID3, C4.5和C5.0生成樹算法使用熵。這一度量是基于信息學理論中熵的概念。
簡單來說決策樹就是根據信息熵來劃分類型,首先遍歷所有按不同變量劃分的結果,找到結果純度最高的劃法,再一步步循環這個過程,直到全部數據劃分完。
純度是個什么意思呢?舉個例子[1,1,1,1,1]和[1,2,3,4,5],第一個的純度就是遠遠高于第二個的純度。
這里純度算法有常見的兩種,信息熵和基尼指數,區別是信息熵越小越純,基尼指數是越接近于0.5越好。
那怎么劃分?以這個數據為例,以性別劃分劃分出來的信息熵,比按休息時血壓劃分的要大,理所當然選擇第二種,于是決策樹的第一個節點就算出來了。
2.擬合過程
擬合
因為分類目標變量包含再數據里面,于是提取出來,再在表里刪除這個變量。
把DataFrame表格轉化成numpy數組,sklearn的數據類型需要。
target=np.array(target) data=np.array(data)訓練集和測試集劃分,
train_test_split(數據,分類目標,測試集大小0-1)
測試集過大過小都不利于建模準確和檢驗,一般建議0.3
建立模型,進行擬合,返回預測準確度
clf = tree.DecisionTreeClassifier()# 載入決策樹分類模型 clf = clf.fit(Xtrain, Ytrain)# 決策樹擬合,得到模型 score = clf.score(Xtest, Ytest) #返回預測的準確度 print(score)可以看到我這個擬合出來的某型準確度達到82%,算是比較好的成績了
看看每個特征的重要程度
可以看到ST_Slope這個特征非常重要,幾乎占一半。
可視化
import graphviz導入graphviz包,還需要安裝這個軟件,windows注意在安裝過程中要選擇添加到系統變量中,然后重啟電腦。
然后就是生成可視化圖形啦。
clf:分類器
feature_names:列名
class_name:分類標簽名
filled:是否填充顏色
rounded:圖形邊緣是否美化
……
得到圖形
看起來是非常不方便的,而且你用訓練集預測一下能有100%正確率,這其實是一種不好的現象,也就是過擬合,導致模型泛化能力較差,需要后續剪枝。
4.修正與優化
在你建立模型,也就是分類器的時候,是有大量參數是可以調的。
例如:
clf = tree.DecisionTreeClassifier(criterion=‘gini’,
max_depth=4,
max_leaf_nodes=10,
min_samples_leaf=9,
)
參數的設置可以提升模型的準確率與模型泛化能力。
所以有很多段子說“調參俠”😂,調的就是這類東西。
一個資深大師可以根據以往的經驗,直接調到合適的參數。
沒達到一定境界就網格搜索,輔助調參。
網格搜索是一項模型超參數優化技術,常用于優化三個或者更少數量的超參數,本質是一種窮舉法。對于每個超參數,使用者選擇一個較小的有限集去探索。然后,這些超參數笛卡爾乘積得到若干組超參數。網格搜索使用每組超參數訓練模型,挑選驗證集誤差最小的超參數作為最好的超參數。
%%time是jupyter notebook用來統計代碼運行時長的
這里導入GridSearchCV
參數備選組成一個字典,比如 ‘criterion’:[‘gini’,‘entropy’],備選有“gini”和“entropy”兩種。
GridSearchCV:
clf:模型
parameters:參數
refit:是否交叉驗證訓練集
cv:交叉驗證參數
verbose:日志冗長度,int:冗長度,0:不輸出訓練過程,1:偶爾輸出,>1:對每個子模型都輸出。
n_jobs:-1代表多核,建議啟用,省時間
運行得到,可以看到總共做了27000多次擬合,用時6.94s,單核的話估計好幾分鐘。
查看最優結果
查看最優參數
三、總結
帶入上面的參數,
Xtrain, Xtest, Ytrain, Ytest=train_test_split(data,target,test_size=0.3) clf = tree.DecisionTreeClassifier(criterion='gini',max_depth=6,max_leaf_nodes=12,min_samples_leaf=2,) clf = clf.fit(Xtrain, Ytrain)# 決策樹擬合,得到模型 score = clf.score(Xtest, Ytest) #返回預測的準確度 import graphviz feature_name = ['Age','Sex','ChestPainType','RestingBP','Cholesterol','FastingBS','RestingECG','MaxHR','ExerciseAngina','Oldpeak','ST_Slope'] dot_data = tree.export_graphviz(clf,feature_names= feature_name,class_names=['yes','no'],filled=True,rounded=True) graph = graphviz.Source(dot_data)#畫樹 graph.render('D:tree.pdf')最后生成決策樹。
看決策樹,最高的是最重要的,節點包含劃分條件,基尼指數,目前樣本數,兩類(分類標簽多個的話就多個)樣本數,最后分類結果。
比如看:
ExcerciseAngina為0,class=yes。
運動時引起的心絞痛為否,可能患心臟病。
很容易理解哈,不運動的時候都會心絞痛,那多半就是心臟病了。
再往下看。
ST_Slope<=0.5,class=yes。
峰運動ST段的坡度為平的,再進一步增加患心臟病的可能性。
再往下看。
Sex<=0.5,class=no。
如果此時你的性別為女,那患心臟病的可能性再增加一步。
再往下看。
就是FastingBS。
最后可以簡單的預測一下,指標全為0的人的心臟病預測結果為1,也就是患有心臟病。
都看到結尾了^-^,點個贊,給個關注吧!
總結
以上是生活随笔為你收集整理的决策树算法与python——心脏病预测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 通信工程专业英语词汇 通信工程 专业英语
- 下一篇: Python 数据分析与挖掘概述