石艷敏 張守賓 朱習軍
(青島科技大學信息科學技術學院 山東 青島 266061)
通過“四診”信息中醫學可以發現人體生理和病理的變化,故采用中醫辨證原理來診斷病癥,然后對癥下藥,治愈疾病[1]。作為患者的外在表現,癥狀是識別疾病的重要航標,也是診斷證型的重要依據。因此,對癥狀正確分類(辯證過程)是治愈疾病的重要環節,也是確保療效的前提。為獲取更高的分類精確度,以及提高算法的效率,本文采用分類算法實現對某種證型的判定,即基于KNN算法在Hadoop平臺下分布式計算實現對多組癥狀群的分類。挖掘出癥狀-證型間的內在聯系,即癥狀群所屬的證型類別,從而分析出癥狀與證型之間的密切關系[2]。
Hadoop[3]是Apache基金會所開發的一個開源的分布式系統軟件框架。該框架具備的高可靠性、高擴展性、高容錯性和低成本等特點使其成為當前運用最廣泛的云平臺框架。其核心組件包括:分布式文件系統[4](HDFS)、分布式計算框架[5](MapReduce)和資源管理系統YARN等,該框架通過組建集群的方式實現對大規模數據集的高速計算和存儲。目前已在谷歌、亞馬遜、Facebook、Yahoob百度等多個大型網站上得到應用。能夠穩定解決海量數據的存儲、計算分析以及資源的管理調度等問題,是當前該領域炙手可熱的開發和運行處理大規模數據的軟件平臺,這對日益龐大的中醫病案數據來說,是一個新的發展契機。
MapReduce 編程模型[6]是一個基于分布式計算模式的軟件結構。分布式計算過程可簡化抽象為兩個函數:Map函數和Reduce函數。首先由JobTracker負責將大規模任務分解;然后,Map函數執行分解后的小任務并得到中間結果;最后,由Reduce函數執行匯總得到最終結果。其MapReduce編程模型的處理流程主要分為以下幾個階段,如圖1所示。

圖1 Mapreduce模型計算過程
(1) 分塊分配階段:MapReduce模型將待處理數據集切分為固定大小的片Splits,其大小默認為64 MB,每個Split創建一個map任務,這里可以根據具體數據情況,設置切片大小,創建更多的map任務個數。
(2) Map階段:Map函數繼承Mapper類,讀取屬于自己的數據片Split,并將其映射成鍵值對
(3) 將Map任務產生的中間結果周期性地寫入磁盤之前,將對這些鍵值對進行二次排序,首先根據數據所屬的partition(partition是分割map每個節點的結果)分組,相同key的value放到一個集合中,然后每個partition中再按key排序。如果設定了Combiner,則將key相同的數據收集到一個List中,得到
(4) Reduce階段:用戶定義Reduce函數繼承于Reducer類,通過與對應的數據節點通信,獲取數據并整合排序。再經過Reduce函數自定義操作,將輸入的中間鍵值轉化為新的鍵值對
KNN(K-Nearest Neighbor)分類算法[7]是比較經典的機器學習算法之一,它由Cover和Hart在1968年提出。主要應用對一些未知事物的分類,基于距離準則來判斷未知事物所屬的類別。由于KNN方法主要靠周圍有限的鄰近的樣本,而不是靠判別類域的方法來確定所屬類別的,故KNN方法較其他方法對于類別域重疊較多或交叉的待分樣本集更為適合[8]。

當p分別等于1、2、∞時,度量函數分別為曼哈頓距離、歐式距離和切比雪夫距離。
KNN算法串行實現的時間復雜度為O(nm),n、m分別表示樣本總數和屬性數目。因此該算法的計算量隨n、m的增大以n×m形式增長。但每個待分類樣本都可以獨立進行KNN分類,因此可以基于Hadoop平臺中MapReduce模型并行化計算求解高復雜度問題[9]。在Hadoop分布式計算平臺上實現KNN算法,首先是worker節點將訓練集和測試集從HDFS文件系統下載到本地節點,啟動Map計算過程,并根據所選擇的度量距離公式計算測試樣本與訓練樣本的距離。最后將中間計算結果送到Reduce節點規約生成最終結果。
任務中將訓練集和預測集讀取到內存中進行切分處理,計算測試樣本與訓練樣本的距離;在Combine和Reduce進行排序和統計的工作。
Mapper主要包括三個函數:setup()、map()、cleanup()。首先調用內置Split函數讀取樣本片并轉換成特定格式文件,之后遍歷計算測試樣本與每個訓練樣本的度量距離,存放在context集合形成鍵值對映射。主要流程為:
(1) 初始化數組List1
(2) 根據所選度量函數計算每個測試樣本與本節點中訓練樣本的距離值。
(3) 輸出數據
Combiner相當于一次本地的Reduce操作,它在Map函數輸出的集合中取出鍵值,進行篩選和排序:對每一個測試樣本所對應的向量集合,按照度量距離選取K個最近鄰樣本作為Reduce節點的輸入,從而節約Reduce節點的計算和通信開銷。具體流程為:首先將Map節點的鍵值對存入ArryList集合,然后按value增序排序,最后每個測試樣本根據設定的K選取K條記錄傳給Reduce節點。Combiner需要輸入/輸出的格式都是即
Reducer主要任務是進行規約獲取K個近鄰,計算多數近鄰樣本的類別,并賦予測試樣本。模型中執行shuffle操作,即:將不同Map節點上同一測試樣本的數據送到一個節點上執行排序、分類以及輸出操作。輸入數據
并行的KNN分類算法流程如圖2所示。

圖2 KNN算法Mapreduce并行化原理
本文選擇中醫哮喘病病案[10]作為研究對象,所使用的證型及對應的癥狀群是根據歷史病案數據經關聯分析算法及名醫總結提取而來,主要證型有寒哮證、熱哮證、腎虛熱哮證、腎虛寒哮證、肺脾氣虛證五類證型。證型及其對應的癥狀群如表1所示。

表1 不同證型及對應癥狀群
由于中醫病案的特性,癥狀描述客觀度不強,因此在處理樣本數據時首先將癥狀進行數據量化[11]。本文選取“咳嗽”、“呼吸”、“咯痰”、“胸悶”、“喘息”、“氣急”、“哮鳴音”、“舌質”、“苔色”、“厚薄”、“舌滑膩”、“脈位”、“流暢度”、“紫紺”、“小便”、“口干”,以及“寒熱”17個癥狀屬性進行表述,并對應“風哮證”、“熱哮證”、“寒哮證”、“腎虛寒哮證”以及“腎虛熱哮證”5個證型。量化準則為:1) 若病案中不涉及對應的癥狀,則該癥狀默認為“正常”或“無”;2) 涉及該癥狀而無描述輕重時默認為“中”。癥狀所對應的中醫描述及其量化取值,如表2所示。

表2 癥狀量化表

續表2
本文將KNN算法基于Hadoop平臺應用于中醫哮喘病癥狀群的分類預測中。所采用的訓練數據集是根據10 662例哮喘病中醫病案整理而來。詳細證型數據如表3所示。

表3 樣本數據統計
部分量化的病案數據如圖3所示。

圖3 部分病案數據
KNN算法是一種基于懶操作的算法,因此只有在輸入測試數據進行預測計算時,才會處理訓練數據。例輸入量化測試樣本:[1,2,2,0,2,1,3,0,1,0,1,1,0,0,0,0,0],輸出預測種類為W。即對應中醫癥狀群:微咳痰多、呼吸急促、喘憋氣逆、喉中哮鳴如水擊聲、易咯、面色青晦、舌苔白滑、脈弦浮緊。輸出預測證型為:寒哮證。結合證型中的總結的癥狀表現,可以確定其判斷正確。為驗證MapReduce編程模型的性能,選取病案中的一半作為測試用例,即5 331條作為預測病案。則KNN算法在Hadoop平臺運行5 331次,所得準確率為98.12%,其建模耗時相比于單一傳統分類算法以及集成學習算法均有較大提升。
本文將KNN分類算法布局到Hadoop平臺,依據MapReduce編程模型實現分布計算,從而在保證分類準確的前提下較大提高了分類建模時間。該平臺不僅可以滿足大數據量的分類計算,而且改善建模時間與數據量成正比的困境。通過中醫癥狀群分類應用,驗證了KNN分類算法在Hadoop平臺的可行性,為后續應用于更大數據量法分類預測奠定了基礎。