本文要點
- 現在,很多客戶支持平臺都配備了人工智能,大大節省了人力,提高了用戶體驗。
- 歷史會話數據會隨着時間的推移而增加。將這些數據放到Apache Hadoop集羣中是一個可擴展的數據管理和共享解決方案。
- Analytics Zoo是一個面向Apache Spark上分佈式TensorFlow、Keras和BigDL的統一分析+ AI平臺,由英特爾開源。
- Analytics Zoo爲從集羣中讀取和預處理文本數據提供了豐富的支持。用戶可以輕鬆地使用內置模型以分佈式方式執行自然語言處理任務。
- 本文將逐步演示如何使用Analytics Zoo構建端到端的QA排名應用程序。該解決方案已被Microsoft Azure成功地用於服務其客戶。
本系列文章討論了微軟Azure中國團隊在Azure上使用Intel Analytics Zoo構建人工智能客戶支持平臺的實踐。
在上一篇文章中,我們詳細介紹了構建文本分類模塊以更有效地處理客戶請求的成功經驗。在接下來的文章中,我們將繼續介紹我們的客戶服務平臺中的另一個重要AI模塊——QA排名,它用於對QA模塊中的大量候選項進行排序,並選出最佳答案。
下圖展示了客戶支持平臺的總體架構,並以橙色突出顯示了問答(QA)組件。上一篇文章介紹了更多關於客戶支持平臺背景和架構的信息。
我們有很多Azure中國客戶不斷尋求幫助來解決他們遇到的技術問題(用中文描述),他們經常希望得到及時的支持。因此,我們打算設計一個QA模塊,目的是爲客戶的問題提供儘可能多的準確答案(也是用中文),同時儘可能地減少人的干預。在我們最初的實現中,我們根據預先定義的對話流以及基於信息檢索的文檔搜索、索引和權重爲用戶提供答案。
遺憾的是,當我們開始處理這個問題時,QA模塊返回的結果不是很令人滿意。如果客戶的問題屬於預定義的對話流,那麼提供的答案可能很有用。然而,在大多數情況下,預定義的對話流不能捕獲客戶提出的問題,所提供的答案也不是用戶所期望的。
爲了改善結果以獲得更好的用戶體驗,我們決定嘗試使用AI技術來幫助完成這項任務。利用NLP技術和深度學習相結合的方法是一個自然的選擇。隨着數據的累積,它們可以增量訓練和演進。我們決定添加一個深度學習QA排名模塊,從搜索引擎提供的候選答案中選擇最佳答案。
針對我們的場景,我們採用了Analytics Zoo提供的內置文本匹配模型,並將其集成到我們的服務平臺中。通過新添加的QA排名模塊,根據基準測試結果和客戶反饋,我們已經看到了顯著的性能改進。在本文剩下的部分中,我們將與你分享在Intel Analytics Zoo中添加QA排名模塊的一般步驟和實踐經驗。
爲什麼選擇Analytics Zoo?
Analytics Zoo是一個開源的統一分析+人工智能平臺,由英特爾開發,用於Apache Spark上的分佈式TensorFlow、Keras和BigDL。該平臺提供了非常豐富的功能支持,包括高級管道API、預定義模型、公共數據集上的預訓練模型、參考用例等。我們之前使用Analytics Zoo成功集成了文本分類器模塊,因此我們認爲,Analytics Zoo是我們以及其他Azure大數據用戶在Azure上構建端到端深度學習應用的一個很好的選擇。有關Analytics Zoo的更詳細介紹,可以參考本文。
什麼是問答(QA)排名?
問答(QA)是一種常見的自然語言處理任務,它試圖用自然語言自動回答人類提出的問題。在我們的場景中,我們的客戶支持平臺有一個FAQ文本和文檔文章的集合,可以作爲回答語料庫使用,它試圖從這些語料庫中爲用戶的每個問題找到最佳的相關答案。這樣的問題可以看作是一個文本匹配問題,我們可以創建一個模型來預測一個問題和候選列表中每個候選答案的相關度,然後對候選答案進行排序,並將得分最高的答案返回給客戶。
與文本分類類似,文本匹配模型的訓練也包括數據收集、訓練和驗證數據集的準備、數據清理和預處理,然後是模型訓練、驗證和調優。Analytics Zoo爲我們提供了一個內置的文本匹配模型和Python及Scala語言的參考示例。有關文本匹配API和功能的更詳細文檔,參見此處。
數據收集和預處理
我們維護了一個整潔有序的候選答案和文章(均爲中文)集合,每一項都有一個不同的ID。我們有一個從不同來源收集的用戶問題的集合(也是中文),每個問題也分配了不同的ID。然後,我們讓人標記出每個問題的最佳匹配答案。我們使用這些數據來訓練用於QA排名的文本匹配模型。
問答語料庫示例如下:
備註:實際內容爲中文。原文作者把它們翻譯成了英語。
對於數據加載,首先我們使用Analytics Zoo中的TextSet API把CSV格式的問答語料庫加載到一個基於TextSet的、文本的彈性分佈式數據集(RDD)中,用於如下分佈式預處理:
1. from zoo.common.nncontext import init_nncontext
2. from zoo.feature.text import TextSet
3.
4. sc = init_nncontext()
5. q_set = TextSet.read_csv("question_corpus.csv", sc, partition_num)
6. a_set = TextSet.read_csv("answer_corpus.csv", sc, partition_num)
接下來,我們需要準備關係文件,表明問題答案對之間的相關性。一對標記爲1(正)或0(負)的問答表示答案是否與問題匹配。由於原始的標籤數據只有正標籤,我們通過對每個問題的所有非匹配答案隨機抽樣,生成一個負樣本集合。
我們爲訓練、驗證和測試分別構建了手動和半自動的關係文件。每個關係記錄包含一個問題ID、一個答案ID和一個標籤(0/1)。關係示例如下所示:
CSV格式的關係也可以使用以下API輕鬆讀取爲RDD:
1. from zoo.feature.common import Relations
2.
3. train_relations = Relations.read("relation_train.csv", sc, partition_num)
4. validate_relations = Relations.read("relation_validate.csv", sc, partition_num)
下面的預處理步驟與我們在文本分類器模塊中所做的非常相似。每個輸入都需要經過符號化、從單詞到索引的轉換和序列對齊。有關詳細信息,你可以參考前一篇文章中相應的部分。
Analytics Zoo中的TextSet提供了內置的操作,幫助我們非常方便地構建預處理管道。Analytics Zoo提供的原始實現只能處理英語。由於我們的數據是中文的,所以我們進行了修改,並利用jieba及自定義的標記將中文句子分成單詞。代碼的預處理部分是這樣的 :
1. transformed_q_set = a_set.tokenize().word2idx().shape_sequence(q_len)
2. transformed_a_set = q_set.tokenize().word2idx(existing_map=q_set.get_word_index()) \
3. .shape_sequence(a_len)
4. word_index = transformed_a_set.get_word_index()
在內部,上述過程首先對問題語料庫進行預處理。然後對答案語料庫進行類似的預處理,不過是將新單詞添加到從問題語料庫獲得的單詞索引圖中,使兩個語料庫共享相同的單詞索引。上面的操作基於RDD,因此可以很容易地擴展並以分佈式方式在大型問答數據集上執行。
模型定義和構造
對於文本匹配模型,我們使用Analytics Zoo中內置的K-NRM模型,該模型利用內核池技術來有效地獲取排名。下面是K-NRM模型的架構:
輸入查詢和文檔將首先經過一個共享嵌入層,該層通常使用預先訓練的詞嵌入向量作爲其初始權重。隨後的點層生成翻譯矩陣,其中每個條目表示查詢和文檔中每個單詞之間的相似性。RBF內核用於提取多級軟匹配特徵,然後是一個“學習排名(learning-to-rank)”層,它將這些軟TF特徵組合成最終的排名得分。有關詳細信息,可以參考“帶有內核池的端到端神經即時排名”一文。
K-NRM模型可以使用以下開箱即用的API進行構建:
1. knrm = KNRM(text1_length, text2_length, embedding_file, word_index=None,
2. train_embed=True, kernel_num=21, sigma=0.1, exact_sigma=0.001,
3. target_mode="ranking")
該模型的輸入是問題索引序列以及答案索引,輸出是它們之間的相關性分值。用戶需要分別指定問題和答案的長度q_len和a_len。注意,對於詞嵌入,該模型支持用於英語單詞預訓練的GloVe。同樣,由於我們處理的是中文,所以我們選擇並修改FastText作爲中文詞嵌入。參數word_index只是上面介紹的答案語料庫TextSet生成的單詞及其ID的映射。
是否對嵌入層進行訓練是可配置的,實驗結果表明,根據內核池的結果對詞嵌入向量進行微調,可以獲得更好的性能。你還可以指定使用多少內核和內核寬度。實際上,默認參數對於我們的數據集來說已經足夠好了。
這實際上是一個多用途模型,它的target_mode可以是“ranking”或“classification”。你可以查看這個文檔瞭解更多細節。
模型訓練、評估和優化
現在,我們有了開始訓練所需的所有要素。訓練和驗證關係、經過預處理的問答語料庫TextSet,這些是我們訓練文本匹配模型所必須的。
該模型可以按照上面介紹的兩種target_mode值以兩種方式進行訓練。一種是將每個關係記錄單獨訓練,作爲一個二元分類問題,輸出將是問題與答案相關的概率。另一種方法是聯合訓練一對記錄,每對記錄由同一問題的正關係(標籤爲1的關係)和負關係(標籤爲0的關係)組成,並優化兩者之間的間隔。我們已經嘗試了兩種方法,並發現後者的表現更好。
Pairwise訓練是以相同問題的一對關係作爲輸入。每對關係包含一個標籤爲1的關係和一個標籤爲0的關係。因此,在這種情況下,我們在K-NRM模型外封裝了一個TimeDistributed封裝器:
1. from zoo.pipeline.api.keras.models import Sequential
2. from zoo.pipeline.api.keras.layers import TimeDistributed
3.
4. model = Sequential().add(TimeDistributed(knrm, input_shape=(2, q_len + a_len)))
Analytics Zoo還提供了一個API,可以直接生成給定關係和預處理語料庫的所有關係對,這些關係對的結果可以直接輸入到模型中。
1. train_set = TextSet.from_relation_pairs(train_relations, q_set, a_set)
然後,我們使用便捷的Keras-Style API來編譯和訓練K-NRM模型。有一個損失函數RankHinge是專門爲Pairwise訓練提供的。損失函數hinge用於最大間隔分類,RankHinge是其方差,其目的是使正樣本與負樣本之間的間隔最大化。
1. model.compile(optimizer=SGD(learning_rate), loss="rank_hinge")
2. model.fit(train_set, batch_size, nb_epoch)
可調參數包括週期數、批大小、學習率等。用戶還可以在訓練期間獲取快照,然後從快照中恢復訓練。
排名模型的評價與訓練有一點不同。基本上,對於每一個驗證問題,我們都會準備一個正確的答案和一些錯誤的答案。我們想根據輸出分數按降序排列所有候選答案。標籤爲1的得分越高越好。NDCG或MAP是評估排序任務的常用指標。Listwise評估的示例代碼如下:
1. validate_set = TextSet.from_relation_lists(validate_relations, q_set, a_set)
2.
3. knrm.evaluate_ndcg(validate_set, k=3)
4. knrm.evaluate_map(validate_set)
你可以從日誌控制檯找到計算結果。NDCG和MAP都會給出0到1之間的值。如果指標接近1,那麼最相關的答案應該排在第一位。你還可以在訓練期間保存即時結果,並使用Tensorboard可視化損失曲線。如果度量指標相對較低,或者模型沒有如預期的那樣收斂,這表明模型性能不夠好,我們必須對模型進行調優。這通常是一個反覆檢查數據質量、選擇合適的訓練超參數或調整模型參數的過程,直到得到滿意的結果,然後訓練好的模型就可以投入生產。
模型服務及發佈
這部分與我們在前一篇文章中詳細說明的文本分類器模塊中所做的工作非常相似。我們在我們的服務中使用了類似POJO的Java推理API(更多細節參見這裏)。由於QA排名中每個問答的預處理與文本分類器基本相同,所以這兩個模塊共享這部分的代碼,這樣便於維護。Analytics Zoo還提供了Web服務示例(包括文本分類和推薦)供我們參考。
隨着我們不斷收集用戶反饋,我們會有越來越多的關係,我們會定期重新訓練和發佈更新後的排名模型。
小結
本文到這裏就結束了。總結一下,本文演示了我們使用Intel Analytics Zoo在Azure大數據平臺上成功構建QA排名模塊的過程。你可以遵循我們上面的步驟,並參考Analytics Zoo提供的指南和示例,將其添加到你自己的應用程序或服務中!在本系列的後續文章中,我們將繼續介紹在構建客戶支持平臺方面的更多實踐經驗。
要了解更多信息,請訪問Github上Analytics Zoo的項目主頁,你也可以下載並嘗試在Azure市場上預安裝Analytics Zoo和BigDL鏡像。
作者簡介
Chen Xu,微軟高級軟件工程師。他負責Mooncake Support Chatbot AI組件的設計和開發。
Yuqing Wei ,微軟軟件工程師,專注於大數據平臺及相關技術。她致力於Mooncake Support Chatbot AI的開發。
Shengsheng (Shane) Huang ,英特爾高級軟件架構師,Apache Spark提交者和PMC成員。她有10多年的大數據經驗,目前在Apache Spark上的分佈式深度學習基礎設施和應用程序開發方面擔任領導角色。
Kai Huang是英特爾公司的一名軟件工程師。他的工作主要是在Apache Spark上開發深度學習框架,幫助客戶在大數據平臺上制定端到端的深度學習解決方案。
查看英文原文:Using Intel Analytics Zoo to Inject AI Into Customer Service Platform (Part II)