劉 宇, 喬 木
1(南京烽火天地通信科技有限公司, 南京 210019)
2(武漢郵電科學研究院, 武漢430074)
早在上個世紀初, 心臟病就已經成為人們對于健康隱患關注的焦點. 全世界每年約有1750萬人死于心臟病及其并發(fā)癥, 占全部死亡人數的1/3; 而我國社會開始進入老年化階段, 老齡化趨勢明顯, 患有慢性病的人群(如患有心臟病和血壓不穩(wěn)定人群)也逐漸增長.對于慢性病患者而言, 他們的生命體征數據應該進行實時監(jiān)測, 否則會嚴重影響醫(yī)生的準確診斷.
目前, 大部分醫(yī)療機構對于心臟病的檢測診斷還是以醫(yī)生個人經驗和體檢結果為標準. 不僅在人工上花費很高, 也會延誤患者最佳就診時間, 但是, 如果可以以機器學習的方法作為輔助診斷, 為臨床診斷提供有效精準的指導幫助, 將會很大程度的提高診斷的科學性. 而且現(xiàn)在大數據時代下的技術融合屢見不鮮, 利用機器學習來輔助心臟病診斷和預測會是一個值得研究的問題.
近年來, 陳天奇對GBDT (Gradient Boosting Decision Tree)算法進行改進[1], 提出了一種設計高效、靈活并且可移植性強的最優(yōu)分布式決策梯度提升庫 XGBoost (Extreme Gradient Boosting, XGBoost), 其原理是通過弱分類器的迭代計算實現(xiàn)準確的分類效果,本文將XGBoost 引入到心臟病預測中, 分析用戶在醫(yī)療平臺的檢查數據信息建立分類預測模型, 從而個作為醫(yī)生的輔助判斷. 實驗結果表明, 所提出的基于聚類和XGboost算法的預測方法的可行性和有效性, 為就醫(yī)推薦等應用提供了精準有效的幫助.
因為數據是從真實場景下獲取的, 所以大體上并不完整, 不能夠直接應用于實驗訓練, 因此正需要數據預處理來解決這一問題。所謂預處理就是對不標準的數據進行類型變換, 除去空值等操作[2], 本次實驗的數據包括14個特征, UCI開源數據集某醫(yī)院的300個心臟病患者體側數據和一萬個經過數據清洗的某健康App的用戶調查數據. 而本次算法模型的應用場景是根據這些特征對樣本進行預測, 并判斷是否患病. 樣本是否患病是一個分類問題, 正好符合本文模型的應用標準,因為本次算法模型選用的是線性模型邏輯回歸, 全部特征的值對應的都是double型, 且不能為空.
(1) 二值類的數據
這類數據通常只有兩個值, 如性別字段有兩種表現(xiàn)形式female和male, 我們可以將female表示成0,把male表示成1.
(2) 多值類的數據
比如表示胸部的疼痛感的cp字段, 我們可以通過疼痛的由輕到重映射成1~4的數值以及缺陷種類可以劃分0~10個不同的等級, 并以此處理為訓練可用的數據.
(3) 去空的數據
在實際情況下的患者的檢查數據中, 會有部分檢查項未填或者未進行, 該特征會為空, 在數據中會以?表示, 我們就需要去掉有空值的那行數據, 去噪, 保持訓練模型的精準性.
第一步和第二步的處理通過sql腳本來實現(xiàn), 最后一步去空則是在Python里遍歷每一行進行操作. 處理過后的數據特征包括年齡, 性別, 胸部疼痛, 血壓,膽固醇,心電圖,最大心跳等14個變量. 變量列表如表1所示.
表1 變量名列表
本文引用的聚類算法是K-means 算法, K-means算法中的K代表類簇個數, means代表類簇內數據對象的均值(這種均值表示的是類簇中心)[3]. K-means算法是一種經典的聚類算法, 此算法以數據對象之間的距離作為聚類標準, 即數據對象之間距離越小則表示這類數據擁有較高的相似度, 就會朝著一個中心點聚集, 距離越大則作用相反. 而數據對象的間距通常用歐氏距離來計算. 算法流程就是一直重復這一計算過程到標準測度函數收斂為止. 給出聚類K和數據子集
K-means算法的基本思想[4]如下:
步驟1. 隨機選擇K作為初始質心點;
步驟2. 對于所剩下的對象, 則根據它們與這些聚類中心距離, 分別將它們分配給與其最相似的聚類;
步驟3. 計算每個所獲新聚類的聚類中心;
步驟4. 如果滿足了標準, 就停止步驟, 否則轉回步驟 2, 直到條件滿足.
停止條件如下: 沒有需要分配的任務到不同的簇,質心不再發(fā)生變化, 或者均方誤差值下降幅度很小, 其計算式:
其中,ck是第k個簇,mk是簇ck的質心,是x和質心mk之間的距離[5], 在本文提出的方法中, 歐氏距離是每個目標點到簇中心的距離:
本文使用K-means算法是為了分割數據集, 因為海量數據會對模型精準度產生影響, 根據某個特征做聚類分成若干的小數據集, 可以使模型更加準確.
XGBoost 是一種改進的 GBDT 算法, GBDT 是2001 年Friedman 等人提出的一種Boosting算法. 它是一種迭代的決策樹算法, 該算法由多棵決策樹組成, 所有樹的結論加起來作為最終答案[6]. 而XGBoost算法與GBDT 有很大的區(qū)別. GBDT 在優(yōu)化時只用到一階導數, XGBoost 則同時用到了一階導數和二階導數, 同時算法在目標函數里將樹模型復雜度作為正則項,用以避免過擬合[7].
XGBoost 算法目標函數:
根據泰勒公式[8]展開:
同時令:
決策樹復雜度[9]計算公式:
將式 (4)、(5)、(6)代入式 (3), 求得目標函數:
不過通過解得的目標函數來尋找出一個最優(yōu)結構的樹, 加入到模型中, 通常情況下枚舉出所有可能的樹結構是不可能的, 因此最后會使用貪心算法來尋找最優(yōu)的分割方案, 也就是一種分割尋找算法, 這個算法稱為精確貪心算法[11].
本文提出的基于聚類和XGboost算法的心臟病預測模型, 數據集是取自UCI開源數據集某醫(yī)院的300個心臟病患者體側數據和一萬個經過數據清洗的某健康App的用戶調查數據. 模型流程是將輸入值通過K-means算法進行聚類, 找到對應某特征不同分段的類, 并將數據離散化分開成單獨的簇, 每個簇經過XGboost算法訓練和測試得到預測的輸出值. 算法包括數據預處理、任務構造、數據離散、模型訓練和結果分析5個部分, 如圖1所示.
圖1 基于聚類和XGboost算法的心臟病預測模型
步驟一. 拿到初始數據后, 對初始數據做預處理,即對數據進行去噪、填充缺失值、類型變換等操作. 獲得一個相對完整可用于訓練模型的數據集.
步驟二. 選定一個與心臟病判斷相關的特征, 如本文選取了膽固醇(chol)來作為K-means 算法的聚類特征, 因為膽固醇特征與本文的心臟病預測模型并無直接聯(lián)系, 且數據跨越度大, 聚類區(qū)分效果明顯, 很適合作為實驗特征對象. 根據目標估計值構造k個學習任務t+1,t+2,···,t+n,n≤h,針對每個任務對應的輸出值,分別從數據集通過K-means 算法聚類. 本文選取k值為3, 并找到3個聚類的中心點. 根據數據離散化, 即統(tǒng)計學習中最大熵的原理, 將數據分成指標程度為高中低的3個數據集. 因為訓練模型時, 在所有可能的概率模型中, 熵最大的模型是最好的模型, 通常用約束條件來確定概率模型的集合, 所以最大熵原理也可以表述為在滿足約束條件的模型集合中選取熵最大的模型[12].如本文所確定膽固醇指標的聚類中心在212和291兩處, 所以我們的數據集應該是小于 212, 212 至 291, 大于291, 分別對應低中高三類數據集.
步驟三. 將N個任務的訓練集同時訓練XGboost模型, 得到最終的預測模型.
步驟四. 將離散化過后的數據集以測試集和訓練集比例1:4分割, 將n個任務相應的測試樣本輸入訓練好的XGboost模型, 可同時得到n個估計值, 最后從中選擇需要的估計值. 選取需要的估計值之后, 即可以與實測數據進行對比, 從而得出本文算法預測的精確情況.
評價分類器性能的優(yōu)劣通常是用分類準確率(Accuracy), 精確率 (Precision)與召回率 (Recall), 準確率(Accuracy)表示的是對于給定的測試數據集,分類器正確分類的樣本數與總樣本數之比[13], 精確率(Precision)通常表示的是預測是正例的結果中, 實際為正例的比例. 召回率(Recall)表示的是實際為正例樣本中, 預測也為正例的比例. 通常以關注的類為正類, 其他類為負類,分類器在測試數據集上的預測是否準確, 如表2所示.
表2 分類結果混淆矩陣
樣本預測的Accuracy、Recall和F1 值作為評價指標其公式[14,15]如下:
其中,P為陽性樣本總數,TP為正確預測的陽性樣本數量,NP為錯誤預測的陽性樣本數量. 同時, 對于大量樣本的數據處理, 算法模型的運算速度也是重要的評價指標. 本實驗在個人計算機(CPU: Intel i7 7700HQ 2.8 GHz; RAM: 16 GB)上運行, 用 Python 包的time.time()函數[16]記錄時間模型運行前后時間差, 即為運行時間,方便運行效率比較.
通過調參后得到的三種算法的最佳模型, 并且拿到測試樣本對測試集進行預測, 以分類器評價標準對三種算法的各個方面作比對, 比對結果如表2所列. 實驗結果表明, 在三種分類算法中, 以XGBoost算法訓練的模型只是在準確率上稍遜隨機森林算法, 而在運行速度方面顯著優(yōu)于隨機森林算法. 而以SVM算法為基礎的模型在原理上相對簡單, 盡管運行速度與XGBoost算法訓練的模型相近, 但是準確率卻大大不如前者優(yōu)秀. 因此經過最后的交叉比較以XGBoost算法訓練的模型具有準確性較高, 運行速度快等優(yōu)勢. 經過這樣的交叉比較, 突出了XGBoost算法在分類預測上的高效性.
表3 運行結果比較
但是單純的使用XGboost算法, 在實際應用場景中可能不能達到最好的預測效果, 因為龐大的數據集也需要模型的準確性, 因此對數據集做了分割, 以高中低三種指標分別訓練模型提高精確性, 根據表4的直觀分析, 分別訓練的三種模型在準確率上確實基本比初始模型要高, 在召回率上L模型和H模型表現(xiàn)的較為優(yōu)秀. 而F1值也都差別不大. 因為都是使用的同一算法, 所以運行時間上不會有太大的差別. 綜合三個數據集所訓練的模型數據, 普遍優(yōu)于初始數據集的模型,并且有所提升1%~2%. 尤其表現(xiàn)在中等指標的數據集訓練模型, 其預測效果是最佳的.
表4 模型準確率對比
通過XGBoost的建??梢耘袛嗝總€特征變量對模型的貢獻程度, 從而判斷哪些特征變量對于患心臟病的影響更為顯著. 并可以以此對醫(yī)生的判斷其參考輔助作用, 分析結果如圖1 所示.
如圖2所示為XGBoost 模型的變量重要性結果,其中, f0、f4、f7 和f9 這4個變量在模型中的重要性排序中在前四位, 這四個變量分別代表著年齡、膽固醇、最大心跳和運動后比較心壓. 而重要性最低的變量是心電圖傾斜度. 從常識上講, 年齡越大患心臟病概率越大, 不僅是心臟病, 各種心腦血管疾病患病概率都很大, 畢竟在數據集中高齡患者也是占很多的, 因此不作為主要判斷參數. 而膽固醇, 最大心跳, 心壓這三個參數是需要經過檢測的, 在醫(yī)生判斷的時候根據檢測結果, 這三個參數也可以作為主要參考. 就算患者本人體檢自測三個參數, 也可以根據異常值推薦就醫(yī). 因此不僅僅是預測心臟病, 重要特征的顯示也能給醫(yī)生和患者帶來重要的參考意見.
圖2 特征變量重要性
本文針對醫(yī)療行業(yè)的心臟病預測問題, 提出了一種聚類和機器學習相結合的心臟病預測方法, 首先從患者數據中提取特征, 將醫(yī)療特征作為心臟病預測的輸入變量, 然后使用XGBoost 算法來對心臟病進行預測, 最后將該方法與其他機器學習算法進行比較.
實驗結果證明, XGBoost 算法在各個評價標準中普遍優(yōu)于傳統(tǒng)算法, 說明了此模型精準性較高, 論證了使用XGBoost 算法來對心臟病進行預測的可行性和可靠性. 且通過對變量重要性進行分析, 我們識別了對模型貢獻較高的變量. 可以此為依據針對就醫(yī), 給醫(yī)生和患者帶來重要的參考意見. 對當前的醫(yī)療系統(tǒng)中疾病預防的完善有著重要的現(xiàn)實意義. 雖然模型準確率得到了提高, 但是在實驗過程中發(fā)現(xiàn), 改進的算法運行時間要更長, 如何在大數據量的情況下, 降低算法運行時間是接下來的工作.