天天看點

實戰美年健康AI大賽之一_自然語言處理

1. 說明

 一直想找個自然語言處理(NLP)相關的比賽.起始看到"美年健康AI大賽"的時候,覺得和之前糖尿病比賽很相似,還是GBDT調參大賽.解包一看幾百兆資料,覺得自己機器可能跑不動(後來确實加了一條記憶體),都沒打開看資料就放棄了.

 後來兩個朋友都推薦做這個比賽,說是NLP的,打開資料一看,欸~還挺有意思的.資料量大的好處是穩定,我線上線下基本是同增同減(隻送出過三次,目前為止是同增同減),就是看那病情診斷看得心驚肉跳的,腿都軟了.

2. 比賽介紹

 言歸正傳,介紹一下比賽内容,比賽提供了涉及5萬多人的800多萬條各項體驗資料,有資料型的,也有字元型的.體驗項目名稱經過了脫敏處理,檢查結果的文字内容未脫敏,目标是預測:收縮壓、舒張壓、甘油三酯、高密度脂蛋白膽固醇和低密度脂蛋白膽固醇這五項名額,預測具體的值,是一個回歸問題.簡單說就是分析哪些名額與高血壓/高血脂相關.

 我使用的是lightgbm模型,簡單調參,對字元串隻做了一些簡單的處理,過濾出一些我認為重要的文字特征,目前最好成績是0.03002(今天中午).NLP建構正在進行中.

 估計最後大多數人還是使用GBDT類算法,對于模型調參和基本的特征工程就不再重複,詳見之前的"糖尿病比賽".

 本文主要說說自然語言處理,此處的目的是把文字轉換成數值,枚舉,或者布爾類型,以友善代入模型.資料裡面包含了很多文本,粗算也有上百萬條,其中涉及至少幾百種類型的檢查,眼科,牙科,心髒,B超等等,不可能為每種檢查寫一套正規表達式,下面來看看如何使用NLP的方法簡化工作.

3. 專業領域的自然語言處理

 一開始做的時候首先想到用一些現成的工具,比如snowNLP或者jieba把文字分成短句,詞組,取其中的關鍵詞等等.然後發現,醫療報告相對于普通文章有很大不同.普通文章可能有各種句式,各種結構,篇幅可能很長,其中可能有些和主題無關的資訊等等.體驗結果中的文字,結構相對比較簡單.

 先來看看提供的txt資料,它包括:使用者id,體項項目名稱,體驗結果.體驗結果可以分成四種情況:

 第一種:純數值型,無需處理.

 第二種:枚舉型及其變種,如:"陰性","未見異常"等等,簡單處理即可轉成數值.

 第三種:簡單混合型,如:">100次/分,窦性心動過速",此類型以數值為主.

 第四種:複雜混合型,如:"甲狀腺内見多個低回聲結節,最大位于右葉約14mm×8mm,結節周邊有血管環繞".這種情況可能是純文字,可能是文字和數值混合,相對比較複雜,也很有趣,它包含了第二和第三兩種情況.

4. 預處理

 在處理文本之前,先要做些預測處理,比如:歸一大小寫,各種符号的全角半角,處理輸入錯誤,多餘的空格等等.

5. 枚舉型及其變種

 常見的一些枚舉有"正常","未見明顯異常","陰性","陽性",以及加減号等等,相對來說比較容易判斷.需要注意的是同一内容可能有幾種不同的表達,此時需要判斷它的關鍵詞,尤其是注意其中的包含否定詞.隻要unique()少,就适合将其視為枚舉處理.

6. 簡單混合型

 文本中會有長句包含短句,括号内外等等情況,這裡隻考慮:以數值為核心的短句.這經常出現在一個字段中其它都是純數字,而某幾個值被寫成"<30次".如果一個短句含有數字,可以把它分解成三部分:字首+數字+字尾.其中數字又包括:數值,符号,機關.我處理的方法是将其拆分後儲存在結構中,借助Python靈活的結構,這一操作并不複雜.

 同時還要需要考慮包含多個數值的情況,比如:< 30(正常範圍30-50).分優先級處理,比如括号内的優先級更低,帶大于小于和範圍比具體數值優先級更低等等.如果不借助結構,直接用正則判斷會非常複雜.

 數字部分除了0-9和小數點正負号外,還可能包含大于,範圍,描述面積體積的乘号等等,也是有限的幾種情況,可以分别用正則實作.

 字尾以機關為主:長度,體積,頻率等等,可能性有限,可一一列舉.

 字首和其它字尾可能是一些描述性資訊,其中也可提取出一些資訊,比如:"左眼/右眼",可能涉及一個體驗結果用多個字段描述,放在複雜混合型中讨論.

7. 複雜混合型

8. 其它

9. 總結

繼續閱讀