(青島科技大學(xué) 信息科學(xué)技術(shù)學(xué)院,山東 青島 266000)
根據(jù)國(guó)際腎病協(xié)會(huì)、歐洲腎病學(xué)會(huì)-歐洲透析和移植學(xué)會(huì)、美國(guó)腎病學(xué)會(huì)估計(jì),全球至少有8.5億人患有腎病,占世界總?cè)丝诘?1%[1]。在2017年全球發(fā)布的腎臟地圖中,僅慢性腎病每10個(gè)人就有一個(gè)人是患者,由此可見慢性腎病占比之高。而慢性腎病的發(fā)展不可逆轉(zhuǎn),因而患者只能通過(guò)長(zhǎng)期藥物治療來(lái)控制病情發(fā)展。若患者不盡早接受治療,極易出現(xiàn)病情惡化導(dǎo)致終末期腎臟病[2]。因此盡早進(jìn)行診斷慢性腎病對(duì)于后期治療具有重大意義和價(jià)值。
隨著醫(yī)療信息化建設(shè)的推進(jìn),醫(yī)療數(shù)據(jù)量正在急劇膨脹,導(dǎo)致數(shù)據(jù)挖掘技術(shù)在醫(yī)療領(lǐng)域的應(yīng)用也更加廣泛。目前數(shù)據(jù)挖掘應(yīng)用于醫(yī)療領(lǐng)域主要是用來(lái)預(yù)防、診斷、治療和預(yù)后。應(yīng)用于預(yù)防是通過(guò)尋找疾病的誘病因子以及通過(guò)疾病早期篩查來(lái)預(yù)防疾病。應(yīng)用于診斷是利用電子病歷文本信息或圖像信息輔助[3]醫(yī)生對(duì)疾病進(jìn)行診斷。應(yīng)用于治療是通過(guò)關(guān)聯(lián)規(guī)則等算法挖掘出藥物對(duì)疾病的治療作用并且能制定臨床路徑,方便醫(yī)生開處方。應(yīng)用于預(yù)后通過(guò)對(duì)原始數(shù)據(jù)的分析,能輔助預(yù)測(cè)患者手術(shù)后的身體指標(biāo)狀況,從而起到預(yù)警作用[4]。本文研究的慢性腎病輔助診斷是數(shù)據(jù)挖掘應(yīng)用于醫(yī)療診斷的體現(xiàn),并通過(guò)利用慢性腎病數(shù)據(jù)建立隨機(jī)森林分類模型對(duì)慢性腎病進(jìn)行分類來(lái)建立慢性腎病輔助診斷系統(tǒng)。
本系統(tǒng)的主要工作是慢性腎病的輔助診斷,對(duì)于該系統(tǒng)的主要流程就是將患者的化驗(yàn)信息以及患者的身份信息輸入到該系統(tǒng)中,通過(guò)已經(jīng)訓(xùn)練好的慢性腎病診斷模型,讓該模型對(duì)該患者進(jìn)行診斷,判斷是否患有慢性腎病。本系統(tǒng)采用B/S架構(gòu)[5]進(jìn)行設(shè)計(jì),分為顯示層、業(yè)務(wù)層、服務(wù)層和數(shù)據(jù)層,系統(tǒng)架構(gòu)如圖1所示。
圖1 系統(tǒng)總體架構(gòu)圖
按圖1所示,表示層是系統(tǒng)用于界面交互的一層,其重要利用HtmL和js進(jìn)行編寫,用jsp輔助傳值,實(shí)現(xiàn)數(shù)據(jù)交互;業(yè)務(wù)層采用SSM框架[6]進(jìn)行設(shè)計(jì),用于實(shí)現(xiàn)系統(tǒng)的功能邏輯;服務(wù)層利用tomcat服務(wù)器進(jìn)行項(xiàng)目部署工作;數(shù)據(jù)層采用oracle數(shù)據(jù)庫(kù)對(duì)數(shù)據(jù)進(jìn)行存儲(chǔ)和處理。
本系統(tǒng)的腎病輔助診斷功能如圖2所示。
圖2 腎病輔助診斷系統(tǒng)框架圖
由圖2可以看出,本系統(tǒng)在功能上應(yīng)具備以下幾個(gè)功能模塊。
2.1.1 化驗(yàn)數(shù)據(jù)錄入模塊
該模塊的功能是將病人的基本信息和病人的本次化驗(yàn)數(shù)據(jù)錄入系統(tǒng),提交診斷后進(jìn)入后臺(tái)由腎病輔助診斷模型進(jìn)行數(shù)據(jù)處理和慢性腎病診斷,最后將輸出結(jié)果0,1轉(zhuǎn)換成是否患有慢性腎病并輸出(0代表病人未患慢性腎病,1代表病人診斷結(jié)果為慢性腎病),并即時(shí)將結(jié)果顯示在頁(yè)面醒目的位置。
2.1.2 腎病輔助診斷模塊
該模塊有應(yīng)具備兩部分功能:1)是腎病診斷模型構(gòu)建功能,該模塊利用原始數(shù)據(jù)對(duì)慢性腎病輔助診斷模型進(jìn)行構(gòu)建。首先將原始數(shù)據(jù)集分為訓(xùn)練數(shù)據(jù)集和測(cè)試數(shù)據(jù)集,然后利用訓(xùn)練集訓(xùn)練慢性腎病輔助診斷分類模型,利用測(cè)試集測(cè)試訓(xùn)練后的模型性能,根據(jù)測(cè)試結(jié)果調(diào)節(jié)模型參數(shù),以使模型達(dá)到最佳性能;2)是利用醫(yī)生輸入進(jìn)來(lái)的基本信息和化驗(yàn)項(xiàng)目參數(shù)封裝成實(shí)例對(duì)象通過(guò)慢性腎病輔助診斷模型進(jìn)行診斷,并將診斷結(jié)果返回。
2.1.3 數(shù)據(jù)處理模塊
該模塊應(yīng)具備的主要功能有:存儲(chǔ)診斷結(jié)果及化驗(yàn)項(xiàng)目信息的功能、能夠即時(shí)查看患者歷史診斷記錄的功能、提供患者診斷記錄增、刪、改的功能。
2.1.4 用戶管理模塊
該模塊的主要功能是提供添加、刪除、更改用戶信息的功能及密碼修改重置功能。
2.2.1 化驗(yàn)指標(biāo)錄入模塊
該錄入模塊有病人基本信息(如化驗(yàn)單號(hào)、姓名、年齡、性別等)5項(xiàng),病人化驗(yàn)指標(biāo)(如血壓、比重、白蛋白、血尿素、血清肌酐等)23項(xiàng),用v1~v23表示。其中只有v1~v23作為模型訓(xùn)練的特征屬性被使用,病人基本信息只是為了方便醫(yī)生查找和數(shù)據(jù)庫(kù)記錄而被添加的。23項(xiàng)特征屬性如表1所示。
表1 慢性腎病輔助診斷模型特征屬性
由于純手工錄入這28個(gè)指標(biāo)會(huì)耗時(shí)較長(zhǎng),為了解決時(shí)耗問題,本實(shí)驗(yàn)設(shè)計(jì)了自動(dòng)填充功能,利用AJAX[7]傳值如下:
/*
自動(dòng)填充病人信息
*/
function fillInfo(keyword,keydate){
.ajax({
url:'{sysPath}patient/patientInfoSearch.do',
type:'POST', //GET
async:true, //或false,是否異步
data:{
keyword:keyword,
keydate:keydate
},
//timeout:5000, //超時(shí)時(shí)間
dataType:'json', //返回的數(shù)據(jù)格式:json/xml/html/script/jsonp/text
success:function(data,textStatus,jqXHR){
(" sampleNo").val(data[0].sampleNo); //sampleNo,化驗(yàn)單號(hào)
(" patientId").val(data[0].patientId);
(" patientName").val(data[0].patientName);
(" sex").val(data[0].sex);
(" age").val(data[0].age);
(" v1").val(data[0].v1);
(" v2").val(data[0].v2);
(" v3").val(data[0].v3);
(" v4").val(data[0].v4);
(" v5").val(data[0].v5);
(" v6").val(data[0].v6);
.......... //省略部分為v7~v23的填充項(xiàng)
},
error:function(xhr,textStatus){
alert("系統(tǒng)錯(cuò)誤");
},
complete:function(){
console.log('結(jié)束')
}
});
}
2.2.2 慢性腎病輔助診斷模塊
此模塊主要功能是利用輸入的化驗(yàn)指標(biāo)判斷該患者是否患有慢性腎病。因此該診斷模塊需要數(shù)據(jù)建模。本次慢性腎病輔助診斷建模利用隨機(jī)森林分類算法的建模方案如下:
1)隨機(jī)森林中決策樹的數(shù)目n是一個(gè)重要參數(shù),需要根據(jù)設(shè)置數(shù)目的模型準(zhǔn)確度反復(fù)調(diào)節(jié),一般設(shè)置為100~1 000,多次調(diào)節(jié)選取最優(yōu)參數(shù);
2)將慢性腎病數(shù)據(jù)按是否慢性腎病分別1:1的比例劃分出訓(xùn)練集和測(cè)試集,將腎病訓(xùn)練數(shù)據(jù)進(jìn)行有放回的隨機(jī)抽樣,抽取n次,得到n個(gè)樣本,每個(gè)腎病訓(xùn)練數(shù)據(jù)樣本容量約為總樣本數(shù)的2/3;
3)屬性子集的選?。郝阅I病數(shù)據(jù)集的特征屬性有血壓、比重、白蛋白、血尿素、血清肌酐等共23個(gè),設(shè)每次隨機(jī)選取的屬性子集中屬性的個(gè)數(shù)為x,log223約為4.5,取4,以4為屬性子集的屬性個(gè)數(shù)最小值,分別取4,5,6,7,8,9,10作為每次隨機(jī)選取的屬性子集中屬性的個(gè)數(shù)。以x=4為例,隨機(jī)抽取n個(gè)特征數(shù)目為4的特征子集進(jìn)行建模實(shí)驗(yàn),用慢性腎病測(cè)試數(shù)據(jù)測(cè)試建模準(zhǔn)確率;x=5時(shí)也進(jìn)行相同實(shí)驗(yàn),將所有x不同取值的模型準(zhǔn)確率進(jìn)行對(duì)比,選擇最優(yōu)x的取值;
4)將n個(gè)樣本和n個(gè)屬性子集一對(duì)一組成n個(gè)決策樹;
5)將腎病測(cè)試樣本實(shí)例輸入到n個(gè)決策樹中,以投票法確認(rèn)該測(cè)試實(shí)例的腎病類別即為隨機(jī)森林模型測(cè)得的腎病類別。
利用隨機(jī)森林算法建立慢性腎病輔助診斷模型的建模流程如圖3所示。
圖3 慢性腎病輔助診斷的隨機(jī)森林建模流程圖
本實(shí)驗(yàn)按照上述隨機(jī)森林的腎病輔助診斷建模流程,利用weka[8]包里的隨機(jī)森林(randomForest)類建立分類模型,模型的訓(xùn)練數(shù)據(jù)和測(cè)試數(shù)據(jù)來(lái)源于機(jī)器學(xué)習(xí)庫(kù)UCI的慢性腎病[9]數(shù)據(jù)集。該數(shù)據(jù)集共400條數(shù)據(jù)、24個(gè)特征屬性,2個(gè)診斷類別。本文將其分為200條訓(xùn)練數(shù)據(jù),200條測(cè)試數(shù)據(jù)對(duì)隨機(jī)森林模型進(jìn)行訓(xùn)練[10]。模型訓(xùn)練測(cè)試設(shè)計(jì)如下:
public static void main(String[] args) throws Exception {
Classifier m_classifier = new WriteRandomForest();
File inputFile = new File("C:UsersAdministratorDesktopuciChronic_Kidney_Disease rain.csv.arff");
ArffLoader atf = new ArffLoader();
atf.setFile(inputFile);
Instances instancesTrain = atf.getDataSet(); // 讀入訓(xùn)練文件
inputFile = new File("C:UsersAdministratorDesktopuciChronic_Kidney_Disease est.csv.arff");//A類下的測(cè)試語(yǔ)料文件
atf.setFile(inputFile);
Instances instancesTest = atf.getDataSet(); // 讀入測(cè)試文件
instancesTest.setClassIndex(instancesTest.numAttributes()-1); //設(shè)置最后一行為分類類別行。instancesTest.numAttributes()可以取得屬性總數(shù)
double sum = instancesTest.numInstances(),//取實(shí)例數(shù)
right = 0.0f;
instancesTrain.setClassIndex(instancesTest.numAttributes()-1);
m_classifier.buildClassifier(instancesTrain); //訓(xùn)練
System.out.println(m_classifier);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:UsersAdministratorDesktop1RandomForest.model"));
oos.writeObject(m_classifier);
oos.flush();
oos.close();
// 保存模型
SerializationHelper.write("RandomForest.model", m_classifier);//參數(shù)一為模型保存文件,classifier4為要保存的模型
for(int i = 0;i { System.out.println(m_classifier.classifyInstance(instancesTest.instance(i))+","+instancesTest.instance(i).classValue()); if(m_classifier.classifyInstance(instancesTest.instance(i))==instancesTest.instance(i).classValue()) { right++;//正確值加1 } } // 獲取上面保存的模型 Classifier classifier8 = (Classifier) weka.core.SerializationHelper.read("RandomForest.model"); double right2 = 0.0f; for(int i = 0;i { if(classifier8.classifyInstance(instancesTest.instance(i))==instancesTest.instance(i).classValue()) { right2++;//正確值加1 } } Evaluation eval = new Evaluation(instancesTrain); //構(gòu)造評(píng)價(jià)器 eval.evaluateModel(m_classifier, instancesTest);//用測(cè)試數(shù)據(jù)集來(lái)評(píng)價(jià)m_classifier System.out.println(eval.toClassDetailsString("===ClassDetailsString===")); System.out.println(eval.toSummaryString("=== Summary ===",false)); //輸出信息 System.out.println(eval.toMatrixString("=== Confusion Matrix ==="));//Confusion Matrix } 該隨機(jī)森林模型的主要參數(shù)是m_numTrees和m_KValue。其中m_numTrees代表的是隨機(jī)森林模型中樹的數(shù)目,KValue代表的是每個(gè)結(jié)點(diǎn)建造時(shí)選擇隨機(jī)特征的數(shù)量。本實(shí)驗(yàn)?zāi)J(rèn)樹數(shù)目100,默認(rèn)隨機(jī)特征數(shù)量為log2(data.numAttributes()-1)+1。為了確定最優(yōu)參數(shù),本文進(jìn)行了多次實(shí)驗(yàn),將樹的數(shù)量分別設(shè)置為100,200,300,400,500,600,700,800,所得結(jié)果以折線圖的形式呈現(xiàn),見圖4。在樹的數(shù)量取到最優(yōu)的情況下,隨機(jī)特征的數(shù)量設(shè)置為4,5,6,7,8,9,10,所得結(jié)果見圖5。 圖4 隨機(jī)森林建模參數(shù)對(duì)照?qǐng)D1 圖5 隨機(jī)森林建模參數(shù)對(duì)照?qǐng)D2 由以上兩折線圖可以看出,當(dāng)樹的數(shù)量取400時(shí),分類準(zhǔn)確率達(dá)到最優(yōu),此時(shí)準(zhǔn)確率為92.5%。在樹數(shù)量取400的前提下,隨機(jī)特征數(shù)量為5時(shí)模型達(dá)到最大值,準(zhǔn)確率為93.7%。因此當(dāng)m_numTrees=400且m_KValue=5時(shí),本次慢腎病輔助診斷實(shí)驗(yàn)的隨機(jī)森林模型達(dá)到最優(yōu)準(zhǔn)確率,為93.7%。本次慢性腎病輔助診斷系統(tǒng)設(shè)計(jì)將應(yīng)用最優(yōu)參數(shù)進(jìn)行系統(tǒng)設(shè)計(jì)實(shí)現(xiàn)。 2.2.3 數(shù)據(jù)處理模塊 該模塊主要有兩個(gè)功能:(1)是讓醫(yī)生可以查看病人診斷歷史記錄,可以通過(guò)病人ID、病人姓名查看某患者在該系統(tǒng)的所有歷史診斷記錄,通過(guò)化驗(yàn)單編號(hào)可查患者唯一記錄。在數(shù)據(jù)列表展示區(qū)點(diǎn)擊化驗(yàn)單編號(hào)可以看到患者此次診斷的詳細(xì)化驗(yàn)信息和診斷結(jié)果信息,并且具備修改和刪除以及導(dǎo)出功能;(2)是數(shù)據(jù)庫(kù)設(shè)計(jì)[11],本文數(shù)據(jù)庫(kù)表結(jié)構(gòu)如圖6所示。 圖6 腎病輔助診斷系統(tǒng)數(shù)據(jù)庫(kù)結(jié)構(gòu) 用戶管理及密碼修改模塊:用戶管理模塊為僅系統(tǒng)管理員可見模塊,該模塊主要有用戶添加、編輯功能、用戶科室配置功能、用戶修改密碼功能。修改密碼功能通過(guò)輸入原密碼、新密碼和確認(rèn)新密碼后,點(diǎn)擊確定修改即可。該部分有原密碼校驗(yàn)功能、新密碼和確認(rèn)新密碼是否一致功能。密碼校驗(yàn)功能代碼如下: /** * 校驗(yàn)新舊密碼 */ function checkContent() { var oldPWD =.trim((" oldPWD").val());//舊密碼 var newPWD1 =.trim((" newPWD1").val());//新密碼 var newPWD2 =.trim((" newPWD2").val());//確認(rèn)新密碼 if (oldPWD == null || oldPWD == undefined || oldPWD == "") { alert("舊密碼不能為空!"); return false; } if (newPWD1 == null || newPWD1 == undefined || newPWD1 == "") { alert("新密碼不能為空!"); return false; } if (newPWD2 == null || newPWD2 == undefined || newPWD2 == "") { alert("確認(rèn)新密碼不能為空!"); return false; } if (oldPWD == newPWD1) { alert("新密碼與原密碼一致!"); return false; } if (newPWD1 != newPWD2) { alert("新密碼與確認(rèn)密碼不一致!"); return false; } } 該模塊在用戶通過(guò)正確輸入用戶名和密碼,登錄成功后進(jìn)入系統(tǒng)界面如圖7所示。 圖7 腎病輔助診斷系統(tǒng)主頁(yè) 從主界面上看該系統(tǒng)一共分為3部分,分別是指標(biāo)錄入平臺(tái)、選擇查詢平臺(tái)以及系統(tǒng)幫助平臺(tái)。指標(biāo)錄入平臺(tái)和選擇查詢平臺(tái)分別是對(duì)患者化驗(yàn)項(xiàng)目指標(biāo)的錄入和對(duì)已經(jīng)診斷的患者記錄進(jìn)行查詢。系統(tǒng)幫助平臺(tái)的本地用戶管理僅系統(tǒng)管理員可見,修改密碼功能普通用戶可使用。 指標(biāo)錄入模塊是醫(yī)生用來(lái)將患者的基本信息和化驗(yàn)指標(biāo)輸入到系統(tǒng)中,該部分利用了AJAX傳值通過(guò)輸入患者化驗(yàn)單號(hào)后使用自動(dòng)填充功能,無(wú)需醫(yī)生再輸入患者的其他信息就可以將該患者的所有信息自動(dòng)填充到頁(yè)面中。 慢性腎病輔助診斷指標(biāo)錄入頁(yè)面如圖8所示。 圖8 指標(biāo)錄入模塊頁(yè)面 該模塊通過(guò)錄入病人基本信息及化驗(yàn)結(jié)果后點(diǎn)擊“診斷”按鈕,數(shù)據(jù)就會(huì)被后臺(tái)診斷功能接收并處理,并將診斷結(jié)果以JS彈框輸出,方便醫(yī)生查看輔助診斷結(jié)果。同時(shí),診斷數(shù)據(jù)和診斷醫(yī)生也被保存到數(shù)據(jù)庫(kù)中,方便醫(yī)生查看歷史診斷記錄。 該模塊主要為用作醫(yī)生查看病人診斷歷史記錄,可以通過(guò)病人ID、病人姓名查看某患者在該系統(tǒng)的所有歷史診斷記錄,通過(guò)化驗(yàn)單編號(hào)可查患者唯一記錄。在數(shù)據(jù)列表展示區(qū)點(diǎn)擊化驗(yàn)單編號(hào)可以看到患者此次診斷的詳細(xì)化驗(yàn)信息和診斷結(jié)果信息,并且具備修改和刪除以及導(dǎo)出功能。該模塊如圖9所示。 圖9 診斷結(jié)果查詢頁(yè)面 用戶管理模塊為僅系統(tǒng)管理員可見模塊,該模塊主要有用戶添加、編輯功能、用戶科室配置功能、用戶重置密碼功能。 用戶科室配置功能頁(yè)面如圖10所示,該功能在用戶點(diǎn)擊進(jìn)入該頁(yè)面時(shí)先從session中調(diào)取用戶的科室,然后查詢除用戶所在科室以外的所有科室,將結(jié)果放入“未在科室”的控件中。通過(guò)“>>”可將用戶“所在科室”刪掉,并且“未在科室”會(huì)增加所刪內(nèi)容;通過(guò)“<<”可將“未在科室”中選中的內(nèi)容放入到用戶“已在科室”,即添加用戶“已在科室”,同時(shí)“未在科室”作相應(yīng)刪減。配置科室功能是為以后研究其他疾病的輔助診斷功能預(yù)留了空間[12]。 本文利用數(shù)據(jù)挖掘的隨機(jī)森林分類技術(shù)和web開發(fā)技術(shù)[13]構(gòu)建了慢性腎病輔助診斷系統(tǒng)[14]。該系統(tǒng)通過(guò)對(duì)病患的基本信息數(shù)據(jù)和化驗(yàn)指標(biāo)數(shù)據(jù)的錄入,利用數(shù)據(jù)挖掘隨機(jī)森林分類模型對(duì)患者是否患有慢性腎病進(jìn)行分類,并將 圖10 用戶科室配置頁(yè)面 分類結(jié)果通過(guò)JS彈框形式及時(shí)返回到頁(yè)面,直觀地便于醫(yī)生查看慢性腎病輔助診斷結(jié)果,同時(shí)將診斷信息存入數(shù)據(jù)庫(kù)以備醫(yī)生查詢?cè)摶颊叩臍v史診斷記錄。該系統(tǒng)在功能上可以給經(jīng)驗(yàn)不足的腎病醫(yī)生提供借鑒,從而幫助他們提高診斷技能,降低誤診率,從而使患者盡早進(jìn)行正確的治療,避免慢性腎病治療延誤帶來(lái)的嚴(yán)重后果。3 系統(tǒng)效果
3.1 系統(tǒng)登錄模塊
3.2 腎病輔助診斷指標(biāo)錄入及診斷模塊
3.3 腎病診斷記錄查詢模塊
3.4 用戶管理及密碼修改模塊
4 結(jié)束語(yǔ)