用 Intel Analytics Zoo/BigDL 為客服平臺新增 AI 的實踐(一)

机器之心發表於2018-09-28

本系列部落格主要分享了微軟 Azure 的團隊使用 Intel Analytics Zoo(https://github.com/intel-analytics/analytics-zoo)在 Azure 的平臺上為客戶支援服務平臺新增 AI 模組的一些實踐。

本篇部落格是此係列中的第一篇。在本篇中,我們將介紹為客服平臺新增“文字分類”模組的大致流程及實踐經驗。

背景

在如今商業高度發達的社會,客戶支援服務平臺已被廣泛使用在售前和售後為客戶提供技術或業務支援,例如銀行的電話客服,淘寶京東等電商的線上客服等等。傳統的客戶支援服務平臺僅僅是一個簡單的溝通工具,實際的服務和問題解答都是靠大量的人工客服和客戶直接互動。後來隨著機器智慧和自動化技術的提升,越來越多的商家開始為客服系統新增智慧模組,節省人力,提升顧客的互動體驗。

我們有一個試驗中的智慧客服平臺。它主要基於線上的文字對話,客戶在對話介面中提出問題,平臺從支援文件和預先儲存的常用答案中搜尋答案回覆客戶。如果客戶覺得答案給的不合適,可以主動尋求轉人工幫助,後臺的支援人員會線上和客戶對話,提供幫助。基礎的客服系統問答給使用者自動提供的答案主要來自於預先編輯好的對話流和基於 Information-retrieval 的文件搜尋、索引和權重計算。在陸陸續續有了一些真實的問答互動之後,我們希望改進初版的系統,利用機器學習人工智慧實現基於不斷累積的真實資料的自動學習和進化。一方面,利用自然語言意圖識別和 QA 問答相關技術來提高答案的準確性;另一方面,利用對話內容和其他客戶特徵進一步提升效率和使用者體驗——例如對對話進行情感分析,對包含負面情緒的客戶進行特殊處理;根據對話內容進行分類,為轉接人工對應團隊提高服務效率;根據使用者畫像選擇更相關的問題答案。

作為初步嘗試,我們在原有的系統中新增了兩個新的智慧模組(使用 Intel Analytics Zoo 實現):文字分類模組,和 QA 排序模組。文字分類模組的作用是對對話的服務型別進行分類,以使得轉接對應人工團隊的時候更加高效,這個模組以後經過一些簡單的修改還可用於情感分析。QA 排序模組則用來對現在搜尋引擎得到的答案進行再排序。

目前我們已經做了一些實驗,效果還不錯,後續的實驗和部署還在進行中。在這個系列部落格裡,我們會逐步把我們在搭建這個客服平臺的流程和經驗分享出來,供大家參考借鑑。

在本篇部落格中,我們主要介紹基於 Analytics Zoo 0.2.0 版本(https://analytics-zoo.github.io/0.2.0/)為客服平臺新增“文字分類”模組的大致流程及實踐經驗。

為什麼採用 Analytics Zoo

Analytics Zoo(https://github.com/intel-analytics/analytics-zoo)是 Intel 開發的一個開源大資料分析 +AI 平臺。專案包含 Scala 和 Python 兩套 API,提供了一系列方便實用的封裝和工具(包括 Pipeline API 以及更 high-level 的 API,預定義的模型,在公共資料集上預訓練的模型,以及參考的實用案例等等),使使用者能更容易地使用 Spark 和 Intel BigDL(Intel 開源的一個基於 Spark 的分散式深度學習框架)進行深度學習應用的開發。

客服平臺的對話資料量會隨著系統投入使用逐漸變得龐大,將資料存放在 Hadoop 叢集上可以滿足集中管理、分享和可擴充套件性的需要。而使用 Analytics Zoo 讀取和處理存放在 Hadoop/Spark 叢集上的資料是非常方便的事情。Analytics Zoo 在標準的 Spark 叢集上面使用 Scala API 訓練和預測並不需要對雲有特殊的改動或配置,還有很多預定義的模型可以開箱即用。在預測的時候,可以使用 Analytics Zoo 提供的 POJO 風格的 service API(本地執行無需 Spark 叢集)來做低延遲的預測。如果是對吞吐量要求較高的話,則建議使用 Analytics Zoo 提供的標準 prediction API(可以執行在 Spark 叢集上)。這兩套 API 都可以很方便地被新增到基於 java 的 service 中。

文字分類概述

文字分類是一種常見自然語言處理任務,主要的目的是將輸入的文字片段分配到一個或者多個類別中。例如,垃圾郵件分類就是把郵件的內容片段分配到是否垃圾郵件的類別中。而我們這裡的應用場景則是將一段對話歸類到一種服務類別中。

訓練一個文字分類模型的過程一般包括幾個步驟:採集和準備訓練資料集和驗證資料的文字集,資料清洗和預處理預處理,在訓練資料集上訓練模型,在驗證資料集上評估的指標,如果驗證集上的指標不夠好,則繼續優化模型(包括新增新資料,調整引數,演算法等)。

Analytics Zoo 提供了一系列預定義好的文字分類模型(如 CNN, LSTM 和 GRU)。我們直接選擇了其中基於 CNN 的分類模型作為基礎進行開發(以下訓練過程中使用的 API 均以 python API 為例)。

在上面的介面定義中,class_num 是指該文字分類問題包含類的數量,token_length 是指每個詞對應詞向量的大小,sequence_length 是指每個文字所包含的詞的數目,encoder 是指對輸入的詞向量序列的編碼器(可以是 cnn, lstm 或者 gru),encoder_output_dim 是指編碼器的輸出維度。這個模型接收的輸入的是一段文字的詞向量的序列,輸出是一個類別標籤數字。

如果對這個模型內部包含的具體神經網路結構感興趣,可以檢視這段原始碼(https://github.com/intel-analytics/analytics-zoo/blob/branch-0.2/pyzoo/zoo/models/textclassification/text_classifier.py#L58-L72 )。

資料採集和預處理

訓練資料中的每一條記錄包含兩個欄位:對話歷史和對應的服務類別標籤。我們採集了幾千條這樣的記錄,並用半自動和人工的方法進行了類標籤的標註。拿到原始訓練資料以後,首先對對話文字進行了清洗,去掉文字中無意義的 tag 和亂碼,並轉化成每一條記錄都是(text, label)的 text RDD。然後我們對 text RDD 做了預處理,生成文字分類模型可以接收的輸入。要注意,資料清洗和預處理的部分,對於訓練資料和對將來應用預測中的新資料都要一致。

(如何開發票 …, 1)
(發票如何寄送…,1)
(遠端服務連不上…,2)
(如何購買…, 3)

清洗之後的 text RDD 記錄示例 (每條記錄都是一對對話文字和類標)

清洗過程這裡不再贅述,下面主要介紹預處理主要包含的常用步驟:

1. 中文分詞 (Tokenization)

和英文不同,中文文字由連續的字序列組成,每句話的詞與詞之間沒有特定的分隔符,需要通過語義和詞典進行分詞。我們採用的是jieba對原始文字內容進行分詞。經過分詞之後,原文字被轉化成了一個由詞構成的陣列。

2. 去掉停用詞 (Stopwords Removal)

停用詞是在文字檢索過程中出現頻率很高但又不涉及具體內容的單詞,這些詞的存在通常對於文字分類的幫助不大。可以選擇使用中文常用的停用詞表(比如“只要”、“無論”等)或者使用者自己指定停用詞,將這些詞從分詞的結果中去除。

3. 統一長度(Sequence Aligning)

不同的文字通常會有不同的長度,但對於一個深度學習模型而言,則需要統一規格的輸入,因此我們要把文字對應的詞陣列轉換成相同的長度。對於給定的長度 sequence_length(比如 500),如果文字包含的詞數目大於該長度,可以選擇從文字開頭或者從結尾擷取該文字中該長度數量的詞。如果文字的詞數目不足該長度,則可以在原本的詞之前或之後加上虛擬的詞來補足(比如“##”)。

4. 轉換為詞向量 (Word2Vec)

處理到目前為止每個文字轉換成的仍然是詞的陣列,但要放入模型進行訓練,需要的是數值的輸入,因此我們需要把每個詞轉化為相同維度的詞向量。我們採用的是 Facebook 開源的詞向量工具 FastText (https://github.com/facebookresearch/fastText),FastText 提供預先訓練好的中文詞向量,每個詞對應一個 300 維的空間向量。在詞向量的空間中,任意兩個向量的之間的距離能體現對應的兩個詞之間的語義聯絡,兩個語義上很相似或者有很強關聯的詞對應的詞向量會有很近的距離。對於不在預先訓練好的 FastText 中的詞,我們用一個 300 維的零向量來代替。

5. 轉換為 Sample

經過以上的處理之後,每個文字轉換為形狀是(sequence_length, 300)的多維向量。對於文字所屬的類別,我們則轉換為整數來表示。把多維向量作為 feature,類別作為 label,每條文字資料生成一個 BigDL Sample (https://bigdl-project.github.io/0.6.0/#APIGuide/Data/#sample )。最終整個資料集轉化成 Sample RDD 用於模型基於 Spark 的分散式訓練。

模型訓練,測試,評估和優化

在準備好 RDD 格式的訓練集(train_rdd)和驗證集(val_rdd),並按照例子例項化好一個模型(text_classifier)之後,我們建立一個 BigDL Optimizer 對模型進行分散式訓練。這是一個類別用整數表示的多分類問題損失函式我們選擇的是稀疏分類交叉熵損失 (Sparse Categorical Cross Entropy)。

在建立 Optimizer 的時候可以指定讓模型在訓練集上進行多少次迭代訓練(epochs),每次訓練使用的批大小(batch_size),採用的優化方法以及它的學習率(learning rate) 等引數

可以在訓練的過程中,在驗證集上輸出指定的效能指標 (比如 Top1 accuracy) ,這樣能瞭解到模型在訓練的過程中是否已經過擬合。同時 BigDL 也支援在訓練過程中階段性儲存快照可用於之後恢復訓練。更詳細的 Optimizer引數和使用方法請參考文件(Analytics-zoo 同時支援 BigDL 0.5 和 0.6 版本,Python pip install 預設同時安裝的是 BigDL 0.6 版本):https://bigdl-project.github.io/0.6.0/#ProgrammingGuide/optimization/

如果不選擇在訓練的過程中驗證,也可以在訓練完成後,用訓練好的模型對驗證資料進行預測並檢查準確率。要保證驗證集也經過了和訓練集同樣的預處理過程。模型會返回對應的概率分佈或者所預測的分類編號。

如果驗證集上結果不好,就要對模型進行優化,這個過程基本是重複調參/調資料/訓練/測試驗證的過程,直到準確率可以滿足實用要求。我們這個模型一開始幾次的準確率是不夠好的,我們之後對學習率進行了調整,並新增了新的訓練資料,增加了停用詞詞典,後來準確率有了大幅提升 。

以上的訓練過程在單機上和叢集上都可以執行。如何操作可以參考文件:https://analytics-zoo.github.io/0.2.0/#PythonUserGuide/run/

另外,Analytics Zoo 提供了完整的文字分類的指南和例項供使用者參考:

https://analytics-zoo.github.io/0.2.0/#ProgrammingGuide/text-classification/ 

https://github.com/intel-analytics/analytics-zoo/tree/branch-0.2/pyzoo/zoo/examples/textclassification

將模型預測部分與 service 整合

拿到訓練好的模型之後,接下來要做的就是把新輸入的文字經過同樣的預處理之後餵給模型,然後模型會輸出一個分類的標籤。由於我們的微服務是用 Java 實現的,考慮到效率,我們沒有直接用 python 程式碼進行預測,而是用 Analytics Zoo 提供的 POJO 風格的 Java Inference API (用法和介面參考文件https://analytics-zoo.github.io/0.2.0/#ProgrammingGuide/inference/ )實現了預測部分的程式碼(Java API 可以直接 load python code 訓練好的模型來做預測),示意如下。另外 Analytics Zoo 也提供了文字分類的完整的 web service 示例可參考:https://github.com/intel-analytics/analytics-zoo/tree/master/apps/web-service-sample

模型的持續更新和釋出

資料是隨著時間不斷累積的,因此在實際使用中經常會定期使用全量或增量資料重新訓練模型,並把模型更新到預測服務中。要實現這一點,只需定期執行訓練程式得到新的模型,然後利用上面示例過的 model.load API 重新載入更新過的新模型就可以了。另外,我們的 service 用基於 Kubernetes 的方案進行持續更新和整合。Analytics Zoo 也提供了 docker 的 image (https://github.com/intel-analytics/analytics-zoo/tree/branch-0.2/docker) 供下載安裝。

結語

相信大家看了以上的介紹,已經對如何使用文字分類,以及如何將類似模組新增到自己的應用中有了大致的瞭解。我們將在這個系列後續的部落格中介紹其他方面的內容和實踐進展。

如果需要更多資訊,請訪問 Analytics Zoo 在 Github 上的專案地址(https://github.com/intel-analytics/analytics-zoo) ,並且可以從 Market place 上面下載使用已經準備好的預裝 Analytics Zoo 和 BigDL 的映象(https://market.azure.cn/zh-cn/marketplace/apps/intel.bigdlstandard )。

相關文章