程路易,王志軍
(東華大學 計算機科學與技術學院,上海 201620)
隨著信息化建設的持續推進,電子病歷在醫院中得到了廣泛的應用。由于電子病歷包括多個業務領域臨床信息,如病歷概要、門(急)診診療記錄、住院診療記錄等,因此涉及到大量信息錄入場景。目前主要是由醫生通過鍵盤手工輸入信息,但在部分場景下存在不便用鍵盤錄入數據的情況。例如:在病理檢查場景下,醫生手持器械檢查時雙手被占用,無法再使用鍵盤進行錄入;在住院診療場景下,醫生需要與患者近距離交流,沒有時間和空間使用鍵盤進行記錄等。
為此,本文提出使用語音交互的方式來進行電子病歷錄入。已有的工作是將任務分為2步。第一步是語音識別,將語音轉換為文字;第二步是信息抽取,將文本進行結構化,獲得包含樣本、屬性、屬性值的三元組。然而,這類方法存在一些具有挑戰性的問題:
(1)錄入文本過長。不同于普通的語音查詢場景,如詢問天氣,餐廳搜索等,電子病歷文本相對較長。傳統的基于鍵盤的輸入方式影響并不大,但切換到基于語音的輸入方式將成為一個挑戰。
(2)錯誤級聯。當前的語音識別和信息抽取方法的效果都還不夠好,使用pipeline的方法會產生錯誤級聯問題,導致最終錄入效果不佳。
(3)可擴展性差。由于當前的方法需要先對屬性進行充分訓練后才可以用于屬性抽取,難以適用新屬性的抽取。
針對上述挑戰,本文設計了一個基于任務型對話系統的電子病歷結構化錄入系統。提出了基于任務型對話系統的語音交互方式,能夠讓用戶進行分段式語音錄入;在當前語音識別和分段式語音錄入的基礎上,增加了語音糾錯階段,通過基于語音對話的方式,對結構化抽取錯誤的結果進行糾正;提出了一種基于可擴展對話狀態追蹤的模型,僅需要屬性的一段描述信息,即可進行信息抽取。本文在病理檢查記錄錄入、住院診療記錄錄入兩個場景中進行了實驗,實驗結果證明了系統的有效性和可擴展性。
系統由語音識別、語音合成以及對話系統三部分組成,總體架構如圖1所示。首先在系統前端錄制用戶語音,使用語音識別模塊將語音轉換為文本;將文本輸入后端的任務型對話系統,系統將從文本中抽取出屬性值并產生系統語段,一起發送至前端;再使用語音合成模塊將系統語段轉換成語音,并將抽取出的屬性值在前端進行展示,同時等待用戶下一輪的輸入。以上流程確保了系統前后端之間傳輸的數據都是文本,減少了前后端間傳輸的數據量。

圖1 系統總體架構Fig.1 Overall architecture of the system
對話系統模塊包含2個階段:錄入階段、糾錯階段。其中,錄入階段的任務是讓用戶通過多輪對話的方式,完成電子病歷結構化錄入。輸入是當前用戶語段、對話歷史、屬性描述等內容;輸出是屬性(槽)、屬性值對以及系統語段。當用戶告知系統“錄入完畢”時,系統自動進入糾錯階段。糾錯階段的任務是直接使用語音指令,修改錄入有誤的屬性值。當用戶表示沒有需要修改的屬性后,整個流程結束。
錄入階段架構如圖2所示。圖2中,錄入階段主要由3個模塊組成,包括:對話狀態追蹤、對話策略以及自然語言生成。其中,對話狀態追蹤模塊的輸入包括當前用戶語段、對話歷史語段以及屬性的描述,輸出是對話狀態,具體包括一組槽、值對。此模塊包含2個子模塊:可分類槽模塊與不可分類槽模塊,分別用于預測有預設候選值、沒有預設候選值的屬性的值,最終合并成對話狀態。對話策略模塊基于規則,輸入是對話狀態,輸出是系統動作。自然語言生成模塊同樣基于規則實現,輸入對話動作,輸出系統回復。系統不斷重復整個過程,直到用戶表示錄入完畢,進入糾錯階段。

圖2 錄入階段架構Fig.2 Architecture of the data entry stage
糾錯階段架構如圖3所示。圖3中,糾錯階段主要由自然語言理解、對話策略以及自然語言生成模塊組成。其中,自然語言理解模塊的輸入是當前用戶語段,輸出是從語段中抽取出的一個槽的名稱及其值;糾錯階段剩余2個模塊功能與錄入階段中的相應模塊類似,當用戶表示沒有需要修改的內容后,整個流程結束。

圖3 糾錯階段架構Fig.3 Architecture of the modification stage
系統后端使用Python語言開發。其中,深度學習部 分主要 使用基 于Pytorch的Huggingface Transformers框架,使用bert-base-chinese預訓練語言模型;Web服務器部分使用Flask框架實現。前端使用JavaScript語言開發,界面部分主要使用了基于React的Ant Design組件庫。
2.1.1 數據集的構建
對于錄入階段,需要解決原始數據集中的文本與實際場景不匹配的問題。原始數據集中,每條數據是一段約100~300字的文本,而實際系統需要用戶使用多輪對話的方式進行交互。因此,需對原始數據集的文本進行如下處理:
首先,將一整段文本依據逗號、句號、分號等標點符號進行切分,形成多個短句,再對這些短句進行合并,形成用戶語段,確保每個語段中包含1~3個短句。接下來,需要在每個用戶語段之后生成系統語段。本文使用了構建模板的方式,構建了一些簡單的回復,如“收到,請繼續說”、“好的,請說下一句”等。在整個對話結束時,則插入表示結束錄入的語段,如“錄入完畢”。最后,使用直至當前用戶輪的所有對話歷史作為模型語段部分的輸入。
數學課程標準(2011年版)指出:“學生掌握數學知識,不能依靠死記硬背,而應以理解為基礎,并在知識的運用中不斷鞏固和深化。”這就是說,數學基礎知識的教學應該注重讓學生理解教學中的實例。比如:為了了解某種電動車一次充電后行駛的里程數,對其進行抽檢,結果統計如下表所示,在一次充電后行駛的里程數,則這組數據中眾數和中位數分別是_____?
在糾錯階段,本文構建了一個符合使用自然語言修改屬性值場景的數據集。方法如下:
首先,對2個數據集中的每個屬性,獲取可能值的集合。然后定義一組模板,預設一些用戶需要修改屬性值時可能說的話,如“把KEY的值修改為VALUE”等。最后,將屬性及其所有可能的值填入模板中相應位置生成樣本,并使用BIO形式進行標注,見表1。

表1 糾錯階段的標注形式Tab.1 Annotation method of modification stage
2.1.2 錄入階段對話狀態追蹤
為了使系統具有一定的可擴展性,本模塊將可分類、不可分類槽的預測,分解為可分類槽填充與不可分類槽填充兩個子任務,并建模為機器閱讀理解問題。錄入階段對話狀態追蹤模塊架構如圖4所示。把對話歷史、當前用戶語段作為閱讀理解中的篇章,并在各屬性標注規范的基礎上總結出描述,作為閱讀理解中的問題。對于可分類槽填充模塊,需要完成多選閱讀理解任務,將描述與屬性的候選值進行拼接,使每個候選值都成為一個候選項,模型將從中選出一個選項作為槽的值,具體標注形式,見表2。對于不可分類槽填充模塊,需要完成抽取式閱讀理解任務,直接將描述作為問題,模型將預測出屬性值在語段中的起始位置與結束位置,具體標注形式見表3。

圖4 錄入階段對話狀態追蹤模塊架構Fig.4 Architecture of the dialogue state tracking module

表2 可分類槽的標注形式Tab.2 Annotation method of categorical slots

表3 不可分類槽的標注形式Tab.3 Annotation method of non-categorical slots
模塊輸入包括3部分:屬性描述、對話歷史、當前用戶語段。其中,當前用戶語段由用戶從前端以json格式發送至后端,屬性描述可使用配置文件的形式,存儲在后端。對話歷史信息存儲在后端,在自然語言生成模塊輸出系統語段之后,系統將當前用戶語段與當前系統語段存入對話歷史中。
預測結果將直接寫入對話狀態中,覆蓋原有的值。系統中的對話狀態同樣使用json格式存儲,具體結構為:{“槽1的名稱”:“值”,“槽2的名稱”:“值”……,“結束錄入”:“值”},以便于發送至前端進行展示。對所有槽都完成預測后,將對話狀態傳入對話策略模塊的同時,將其發送至前端,使得用戶能夠在說完每個語段后,看到系統的反饋。此外,當用戶需要錄入一條全新的病歷時,對話狀態追蹤模塊會清空對話狀態以及對話歷史。
2.1.3 糾錯階段自然語言理解
模塊所使用的模型結構與文獻[7]中提出的單句標注任務模型基本相同。模型將按照2.1.1節所標注的標簽,為每個字符進行分類。將Outside()標簽之外所有標簽的Begin()與Inside()部分所對應的單詞進行合并,產生實體。經合并后,共有、、三種標簽形式。以表1為例,標簽為的實體為“腺癌形狀”,標簽為的實體為“隆起型”。本模塊將找到標簽為的實體與所有槽的名稱進行匹配。由于實際用戶輸入是通過語音識別產生的,很可能無法完全匹配。因此,使用計算編輯距離的方式,計算標簽為的實體與槽的名稱相似度,并選取分數最高的作為需要修改的屬性。如:語音識別結果為“癌形狀”,該結果與“腺癌形狀”的相似度為1-1/(3+4)=0.86,而與“標本大小”的相似度為1-(3+4)/(3+4)=0。因此,需要修改的屬性為“腺癌形狀”。同時,設置一個閾值,若相似度最高的屬性分數小于閾值,則不修改任何內容。此外,模塊同樣使用計算編輯距離的方式將輸入語段與表示結束糾錯的一組語段進行匹配,若相似度大于閾值,則認為用戶糾錯完畢。模塊的輸出依然使用json格式,若存在需要修改的值,輸出的用戶動作為{需要修改的屬性名:值}。如果用戶表示結束糾錯,則輸出為{結束修改:是}。
2.1.4 對話策略與自然語言生成
系統對話策略模塊的主要作用,是根據錄入階段對話追蹤輸出的對話狀態,或是糾錯階段自然語言理解模塊輸出的槽、值對,產生對應的系統動作,控制自然語言生成模塊的輸出。自然語言生成模塊的作用是將系統動作轉化為自然語言。
需要產生的系統動作主要用于系統處理完當前的用戶輸入后,給用戶一個反饋,引導用戶進行下一輪對話。因此,采用基于規則的對話策略模塊,具體規則如下:
(1)錄入階段。如果輸入的對話狀態中,“結束錄入”槽的值為“否”,則輸出系統動作{動作:CONFIRM};否 則,輸 出 系 統 動 作{動 作:REQUEST}。同 時,向 前 端 發 送json,內 容 為{inputend:True},使得前端進入糾錯階段。
(2)糾錯階段。若輸入的用戶動作中包含{需要修改的屬性名:值},則以json的形式向前端發送此內容,同時輸出系統動作{動作:REQUEST}。直到輸入中包含{結束修改:是}時,模塊會向前端發送json,內容為{modend:True}。通知前端整個錄入流程已完全結束,模塊不再輸出任何系統動作,結束后端的流程。
系統采用基于模板的自然語言生成模塊,當輸入的系統動作為CONFIRM時,系統準備了多種表示確認的短句,如:“收到,請繼續說”、“好的,請說下一句”等。當輸入動作為REQUEST時,系統同樣預置了多種詢問用戶是否需要繼續進行修改的語句。本模塊在收到系統動作后,會從對應的模板中隨機選擇一個語句進行回復,使得系統產生的回復從用戶的角度看,具有一定的多樣性。同時,有效地避免了模塊可能產生不確定、不安全回復的可能。
為了節省前后端之間數據傳輸所需帶寬,系統完全在前端實現與用戶的語音交互。由于系統整體采用B/S架構,需要在瀏覽器中完成錄音與播放、調用第三方語音識別、語音合成API。系統采用發送事件的方式,完成這些任務之間的同步。各任務具體實現細節如下:
(1)錄音任務需要完成的內容主要包括:獲取錄音權限、開始錄音、停止錄音。系統直接調用瀏覽器內置的WebAudio接口,完成麥克風權限的獲取以及音頻錄制。經過調研發現,不同類型的麥克風所需的冷啟動時長有所不同。冷啟動時長是指從系統初次獲取到錄音權限起,直至錄音設備能夠錄制用戶的語音為止。如果在取得錄音權限后立即開始錄制音頻,會造成錄音開頭部分的音頻丟失。因此,在用戶授權使用麥克風后,系統播放一段音頻,引導用戶開始語音錄入。在開始播放引導音頻的同時讓麥克風開始錄音,在音頻播放結束的前一刻停止錄音,使麥克風獲得足夠的冷啟動時間,能夠完整錄制用戶的聲音。在用戶說完當前語段后,系統將自動停止錄音。盡管一些第三方的語音識別API本身提供此功能,但效果并不理想,無法及時停止錄音,導致上傳的音頻存在大段空白,不利于語音識別。本系統利用WebAudio API,以一定的時間間隔檢測當前錄音的音量,當出現連續三個時間點的音量低于一定閾值時停止錄音。為了緩解錄音中包含大段空白或是錄音提前終止的情況,在錄入階段與糾錯階段,設置了不同的時間間隔,一定程度上改善了用戶體驗。
(2)錄制的音頻流將被發送至第三方語音識別API進行語音識別。本系統使用訊飛語音識別API,由于該API使用Websocket協議通信,被瀏覽器允許直接進行“跨域”請求,系統將直接音頻發送至訊飛服務器,減少了前后端間數據的傳輸。在收到了后端對話系統返回的文本后,發送至訊飛文字轉語音API進行語音合成。其中,主要調節的參數是播報的語速,讓用戶感到系統能夠及時對每個輸入做出響應。系統最后將合成的音頻流使用WebAudio API進行播放。
本文實驗環境設置見表4。

表4 實驗環境Tab.4 Experimental setting
本次實驗獲取到2個不同錄入場景下的數據集。對此擬做闡釋分述如下。
場景的數據來源于上海市某大型三甲醫院的腸癌病理檢查數據,包含原始診斷文本以及12個屬性。其中,淋巴結轉移情況、基底切端、上切端、下切端、神經侵犯、脈管侵犯為有預設候選值:是、否、無的屬性;標本名稱、腫瘤大小、浸潤深度、病理等級、分化程度、腺癌形狀為無預設候選值。訓練集、測試集中包含的數據量分別為1 672、634。
場景的數據選取2019全國知識圖譜與語義計算大會(CCKS2019)面向中文電子病歷的醫療實體識別任務,以及屬性抽取任務中的部分數據。其中包含原始文本以及疾病和診斷、影像檢查、實驗室檢驗、手術、藥物、解剖部位等6個無預設候選值的屬性。訓練集、測試集中數據量分別為998、378條數據。
為了能夠模擬語音錄入、語音糾錯的實際情況,將按2.1.1節方法中生成的對話文本,輸入到訊飛語音合成中產生語音,再將語音傳入訊飛語音識別模塊,最終生成語音識別后的文本。針對用于語音修改的文本,本文窮舉了所有屬性的所有值,配合一些預定的模板,生成了用于語音修改的語段,再經過語音合成與語音識別,得到最終的糾錯指令。
由于數據集中的每條文本記錄包含多個屬性,本文分屬性統計屬性值預測正確記錄的條數,并將其與總記錄條數的比值作為該屬性的準確率。
實驗結果見表5、表6。

表5 場景ATab.5 Results of scenario A

表6 場景BTab.6 Results of scenario B
從錄入階段的結果可以觀察到,場景、中部分屬性準確率較低,如病理等級、解剖部位等,導致錄入效果不佳。其中,有預設候選值的屬性準確率都在90%以上,而無預設候選值的準確率都相對較低,原因是預設候選值為“是”、“否”、“無”,語音識別的正確率更高。其次,從糾錯階段的結果能夠看到,糾錯階段大幅提升了屬性的準確率,場景中所有屬性的準確率均超過90%。實驗證明,本系統使用同一模型,能夠在2個場景中完成錄入任務,說明系統具有一定的可擴展性。
本文設計了基于任務型對話系統的電子病歷結構化錄入系統,能夠讓用戶以人機對話的形式完成結構化錄入。并且增加了糾錯階段,讓用戶能夠通過語音,修改錄入有誤的屬性值,還通過實驗驗證了糾錯階段的有效性。同時,該系統能夠使用一個模型完成2個不同場景的錄入任務,表明系統具有一定的可擴展性。