[對話式AI-3] Chatbot的記憶與決策–對話管理篇

聊天機器人的對話管理(Dialogue Management)是為了總結目前的對話狀態,並決定系統該做些什麼。通常分為兩個子模組,負責更新對話狀態的「對話狀態追蹤」(Dialogue State Tracking),其輸入自然語言理解模組所得到的使用者動作,以及過往的對話歷史,輸出對話狀態;以及決定系統動作」的「對話策略學習」(Dialogue Policy Learning),其輸入對話狀態,輸出系統動作。上述的「使用者動作、對話狀態、系統動作」皆可用一個意圖與一組槽位值表示。

對話狀態追蹤(Dialogue State Tracking)

目的是透過「使用者動作」及「對話歷史」更新對話狀態,其對話歷史可能隱含著因資訊不足,經過系統反問使用者後,產生的「多輪對話」內容;有些需求還會參考使用者畫像(User Profile),以補足必要的「個性化資訊」。透過推理和總結上述內容,轉換成簡單的對話狀態(一個意圖與一組槽位值),系統可以將當前的對話狀態映射成更完整的表示(Representation)。為了考慮自然語言的模稜兩可、語音辨識或自然語言理解模組產生的失誤,根據可能正確的使用者動作數量,可進一步分成只考慮置信度最高的1-Best,以及考慮多個使用者動作與置信度的N-Best方法;常用CRF、RNN、LSTM模型追蹤序列。

對話策略學習(Dialogue Policy Learning)

目的是透過「對話狀態」決定系統該做些什麼,如果對話狀態的意圖在系統能夠提供的服務項目之內,系統會檢查槽位值是否齊全,然後使用其內容查詢服務API,以得到關鍵答案或內容;若對話狀態的意圖不明,或其符合特定服務但槽位值有缺失,系統應該主動向使用者提問,透過多輪對話及對話狀態追蹤來蒐集足夠的資訊。最後將關鍵答案或內容封裝到系統動作中,以一個意圖及一組槽位值代表,提供給自然語言生成模組(Natural Language Generation)。

對話策略的實作方法

  • 基於規則( Rule-based )的方法,透過編寫明確的規則,來建立各種槽位狀態下,使用者動作所對應的系統動作,此種方法無法處理不確定的狀態,且需要手工編寫大量規則,僅適合特定領域的簡單場景。
  • 基於有限狀態機(Finite-State Machine, FSM),此種方法又可分為「以點代表槽位狀態,以邊代表系統動作」,以及「以點代表系統動作,以邊代表槽位狀態」兩種方案;槽位狀態可分為有或無,系統動作則是詢問槽位或最後回答兩種,為避免置信度過低,也可以增加動作請使用者二次確認。由於前者在槽位增加時,會使狀態數量急遽增多,只適合資料驅動的方式;若要以手工建置會建議採用後者。採用有限狀態機的優點在於實作簡單,且容易理解,缺點是每個狀態和動作都要手工設計,不利於複雜場景。
  • 基於統計(Statistical-based)的方法,通常採用馬可夫鏈(Markov Chain)將對話過程表示成決策過程,而系統在每個對話狀態中決定下一步動作。採用馬可夫鏈的優點在於只需要在決策過程中定義槽位狀態與系統動作,就可以自動學習到狀態的移轉關係,也可在過程中導入強化學習(Reinforcement Learning)與線上學習(Online Learning),缺點是同樣需要手工設計,不利於複雜場景。
  • 基於深度學習(Deep Learning)的方法,輸入使用者動作及相關特徵,輸出對應的系統動作,以訓練深度類神經網路模型。基於深度學習的方法需要大量訓練資料才能夠取得效果,目前實際應用上還難以滿足此須求。

對話管理的具體流程

  1. 自然語言理解模組取得使用者對話「推薦我一家台北的餐廳」,此時會偵測使用者意圖及識別命名實體,並將結果封裝成使用者動作(意圖=推薦餐廳, 地點=台北),得以將自然語言映射成簡單的語意表示。
  2. 對話狀態追蹤模組透過使用者動作(意圖=推薦餐廳, 地點=台北)更新當前的對話狀態,然後在地點填充常用的預設值,並透過使用者畫像補充用餐的個性化資訊,最後輸出對話狀態(意圖=推薦餐廳, 地點=台北公館, 口味=喜歡吃辣)。
  3. 對話策略學習模組得到對話狀態後,發現其意圖在系統能夠提供的服務項目之內,但還缺少了用餐時間,系統應該反問使用者;所以輸出系統動作(意圖=對空白槽位提問, 地點=台北公館, 口味=喜歡吃辣, 時間=Null)。
  4. 自然語言生成模組執行系統動作,產生問句向使用者提問欲用餐的時間「你想在什麼時候用餐呢?」。
  5. 自然語言理解模組取得次輪的使用者對話「明天中午」,再次偵測意圖及識別命名實體,得到使用者動作(意圖=不明, 時間=2020年3月30日12點)。
  6. 對話狀態追蹤模組參考使用者動作及對話歷史,更新當前的對話狀態(意圖=推薦餐廳, 地點=台北公館, 口味=喜歡吃辣, 時間=2020年3月30日12點)。
  7. 對話策略學習模組利用使用者動作及對話歷史,蒐集餐廳推薦服務的必要資訊,透過查詢服務API得到答案後,封裝成系統動作(意圖=推薦餐廳, 地點=台北公館, 口味=喜歡吃辣, 時間=2020年3月30日12點, 餐廳=右手餐廳, 類型=泰式料理)。
  8. 自然語言生成模組執行系統動作,產生具體答案「建議你明天中午可以到台北公館的右手餐廳享用酸辣的泰式料理」。

未來的發展方向

為了解決基於深度學習的對話管理方法,在訓練資料上普遍不足的問題,業界已嘗試使用N-Shot Learning在小樣本下進行訓練,或使用Zero-Shot Learning在沒有任何訓練資料的情況下,進行現有模型的遷移與補全,以及在馬可夫鏈決策過程中,導入強化學習(Reinforcement Learning)與線上學習(Online Learning),建立獎懲與持續學習的機制;也有學者將生成對抗網路(Generative Adversarial Network, GAN)應用在自然語言處理上,透過結合強化學習的SeqGAN讓兩個模型相互博弈,以學習到最強的對話策略。

參考文獻

[對話式AI-2] Chatbot的閱讀能力–自然語言理解篇

一個基本的文字型聊天機器人框架(Chatbot Framework),包含「自然語言理解、對話管理、自然語言生成」三大模組。有些機器人能夠使用語音與使用者交互,還需包含「自動語音辨識、語音合成」模組 ,例如知名的Siri、Google Assistant。本期AI專欄將為大家詳細介紹聊天機器人的核心「自然語言理解 」模組。

自然語言理解是什麼?

自然語言理解(Natural Language Understanding)是為了把自然語言轉換(映射)成機器可讀的語意表示(Semantic Representation),是自然語言處理(Natural Language Processing)中最困難的技術;若要讓機器理解自然語言,必須分析「語音、音韻、詞法、句法、語意和語用」,可以簡單理解如下:

  • 語音(Phonetics):人類如何發出語音
  • 音韻(Phonology): 如何拼出自然語言的讀音
  • 詞法(Morphology):如何構成自然語言的單詞
  • 句法(Syntax):如何構成自然語言的句子
  • 語意(Semantics):如何理解自然語言的句子
  • 語用(Pragmatics):如何使用自然語言的句子

對機器來說,自然語言理解可能碰到以下問題:

  • 語音辨識所產生的錯誤,是否能在自然語言理解中容錯?
  • 中文並沒有像是英文的空格去分隔單詞,如何正確分詞?
  • 如何兼容同一個語意的上百種自然語言表示?例如:「我愛你、我喜歡你、我中意你、你是我的菜」 等 。
  • 同一句話可能會因情境(上下文)不同,而有不同的語意, 如何正確判斷 ?
  • 對話中的代詞或省略所代表的內容?
  • 還沒學到的詞彙該如何處理?例如:「是在哈囉、 新冠肺炎」。

自然語言理解在聊天機器人的功用

自然語言理解在聊天機器人發揮的功能,主要可分為以下七點:

  • 使用者意圖偵測( User Intent Detection ):針對使用者對話的意圖進行分類,得以確定使用者想要或計劃做什麼,可分為顯性(直接知道分類,例如:「今天天氣好嗎?」)和隱性意圖(間接推敲出分類,例如:「今天適合出門嗎?」),以上兩個問句,使用者意圖都是「查天氣」。
  • 命名實體識別(Named Entity Recognition):用來擷取使用者對話中具有特定意義的實體,例如:「查詢日期、地點」等專有名詞,以填充特定意圖的槽位(Slot filling),例如:「2020年2月25日台北的天氣?」,日期的槽位值是「2020年2月25日 」,地點的槽位值是「台北」;而上述的使用者意圖「查天氣」正是需要這兩個槽位值補充說明。
  • 指代消解(Coreference Resolution):判斷在對話中代詞所代表的實體或事件,例如威諾格拉德模式(Winograd Schema)的示例
  • 省略恢復:判斷使用者在對話中所省略的內容。
  • 情感分析(Sentiment analysis):識別使用者對話中的主觀資訊,例如正面或負面,或尋找更複雜的狀態,例如開心、生氣、哀傷等;可以讓機器與人交互時更有溫度。
  • 意圖確認:當意圖識別的置信度(Confidence)不足時,請使用者再次進行確認。
  • 拒絕識別:當識別的意圖超出服務範圍、涉及敏感內容或置信度過低時,系統可拒絕回覆。

不同類型的聊天機器人(請參考聊天機器人的類型與對比),其自然語言理解著重的技術有所不同,如下:

一、問答系統(Question Answering system):

著重於識別問題中的資訊詞,例如問題詞(Who What Where When Why How)、焦點詞、主題詞、中心動詞等,與自然語言理解略有不同,比較偏向自然語言處理的範疇;以模板比對、基於統計、基於深度學習的語意分析,基於深度學習的端對端生成(此方法目前處於研究階段),以上四種方法為主流。主要評估指標為召回率(Recall)、精確率(Precision)、F-Score。

二、任務導向對話系統(Task-Oriented Dialogue system)

著重於將自然語言,轉換成機器可讀的語意表示,例如分為使用者意圖(User Intent)及槽位值(Slot Value)。具體工作有中文分詞、詞性標註、命名實體識別、指代消解、句法分析等。以基於規則、基於統計、基於深度學習的意圖識別與槽位填充,以上三種方法為主流;主要評估指標為意圖分類準確率(Accuracy)、槽位填充的F-Score。

三、閒聊系統(Chit-Chat Dialogue system)

著重於個性化,以及情感分析(使用自然語言處理來識別對話中的主觀資訊,例如正面或負面等)。以對話庫檢索、基於深度學習的端對端生成,以上兩種方法為主流。主要評估指標為詞重疊率和向量距離。

自然語言理解的實作方法

如上所述,自然語言理解可視為分類和序列標註問題,通常分為基於規則、基於統計、基於深度學習三種方法:

  • 採用基於規則的方法,優點在於容易調整修正,而且不需仰賴訓練資料,缺點是當場景變多時,規則數量也大幅增加,將變得難以維護。
  • 採用基於統計的方法,優點在於系統強健性高(Robustness),而且容易維護。缺點是訓練出來的模型較難解釋和修正。常用支持向量機( Support Vector Machine, SVM)或自適應增強(Adaptive Boosting, )進行意圖分類,隱藏式馬可夫模型(Hidden Markov Model, HMM)或條件隨機域(Conditional Random Field, CRF)進行分詞、實體識別。
  • 採用基於深度學習的方法,優點在於其效果最佳,系統強健性高,而且容易維護,缺點是需要大量的訓練資料,模型的空間與時間複雜度高 ,而且幾乎無法解釋與修正, 如同黑盒子一般。常用Attention-based RNN及LSTM等模型,進行意圖偵測與槽位填充等任務。

自然語言理解相關技術的其他用途

自然語言理解涉及的自然語言處理技術,除了用於聊天機器人,也可用於其他用途:

  • 垃圾郵件偵測 (Spam Detection):分析大量的資料歸納出特徵,協助使用者過濾垃圾郵件,例如Gmail中的垃圾郵件匣。
  • 搜尋引擎建議(Search Engine Suggestions):透過預測使用者輸入的字詞,主動推薦搜尋的內容,例如在Google搜尋輸入些許字詞,所出現的推薦搜尋清單。
  • 機器翻譯(Machine Translation):將某種自然語言翻譯成另一種自然語言,例如Google翻譯的英翻中功能。
  • 自動摘要(Automatic Summarization):分析一篇或多篇文章,自動產生一段大意,常應用在新聞短訊中。

參考文獻

[對話式AI-4] Chatbot的挑戰與發展趨勢

雖然電腦視覺(Computer Vision)透過深度學習(Deep Learning)技術取得了重大進展,但在自然語言處理(Natural Language Processing)領域,深度學習的導入仍然處於發展初期。

以聊天機器人(Chatbot)來說,自從圖靈測試在2014年被聊天機器人Eugene通過後,加拿大學者改進測試的缺失提出了威諾格拉德架構挑戰賽(Winograd Schema Challenge),也是目前最具權威的AI競賽。

該競賽的第一輪是代詞消歧問題(Pronoun disambiguation problems)。舉例來說,當人類分析句子時,會用經驗來理解指代的對象:

  • 市議會拒絕示威者,因為他們害怕暴力。
  • 市議會拒絕示威者,因為他們提倡暴力。

而這個選擇題只有兩個答案,代詞”他們”是指”市議會”還是”示威者”,AI應該要指出在第一句說的是市議會,第二句說的是示威者,從問題上可以發現,系統無法透過這段話的上下文進行理解得到答案,這在傳統實作上必須透過知識圖譜(Knowledge Graph)進行推理,或使用深度類神經網路模型,要通過比賽拿到獎金25,000美金,準確率(Accuracy)必須達到90%以上,但目前最好的成績只有58%,遠比人類低得多。

除了上述根本影響Chatbot問答品質的問題,還有幾個難題仍未被突破:

  1. 通用的模型架構(Universal Model Architecture):為了整合語音辨識、詞法分析、句法分析、語意分析、深度學習,答案搜尋,對話管理、自然語言生成和語音合成等模組,確保其相容性,當前Chatbot架構與模型相當複雜,管理較為困難,如何研發通用的架構與模型,是未來所有同業的發展目標。
  2. 情感計算( Affective Computing ):從分析文本的情感 (Sentiment Analysis)到辨識人類情緒的情感計算,例如開心、生氣、哀傷等;可以讓Chatbot與人交互時更有溫度,是目前產學界熱門研究方向。
  3. 開放領域(Open Domain):現在的Chatbot只能做好特定領域的工作,如何建構開放領域的知識,甚至不需要人工建構知識,讓機器自學習,也是產學界正在努力的方向。
  4. 端對端 ( End to end ) :不經過傳統的模組串聯,利用深度學習 ( Deep Learning ) 建立端對端的簡潔模型;達到輸入原始資料後,可直接得到想要的輸出結果,但與此同時還要支援多輪對話管理、上下文情境及知識圖譜推理,避免安全回答,甚至是保持Chatbot個性的一致性,正確的進行指代消解,這些挑戰都是產學界近期的目標。
  5. 基於生成的模型(Generative Model):目前自然語言生成技術 ,可分為基於檢索、基於範本及基於生成兩種方法,三者都可以導入深度學習技術,目前以基於檢索及基於範本為業界主流;雖然深度學習Seq2seq模型非常適合產生文字,但此基於生成方法尚處早期的發展階段,空間和時間複雜度高,實際應用效果不佳。

[對話式AI-7] 預訓練語言模型比較(ELMO、BERT、GPT-2)

預訓練(Pre-train)語言模型可用於自然語言理解(Natural Language Understanding)的命名實體識別(Named Entity Recognition)、問答(Extraction-based Question Answering)、情感分析(Sentiment analysis)、文件分類(Document Classification)、自然語言推理(Natural Language Inference)等任務。

以及自然語言生成(Natural Language Generation)的機器翻譯(Machine translation)、自動摘要(Automatic summarization)、閱讀理解(Reading Comprehension)、資料到文本生成(Data-to-Text Generation)等任務。

本文透過列舉時下主流預訓練語言模型的特點,介紹最具代表性的ELMO、BERT及GPT-2模型;用最簡短的文字敘述,讓大家能夠輕易比較出差異。

ELMO(Embeddings from Language Model)

  • RNN-based Language Models
  • 透過一堆句子訓練,不需要標註
  • 預測下一個Token
  • 從RNN的hidden layer取得Contextulize word embedding
  • 從正反向embedding接起來就是上下文的embedding
  • 最後把每一層的embedding都加起來,再由後續任務學習到加權參數
  • 94M個參數

Source: https://arxiv.org/abs/1802.05365

BERT(Bidirectional Encoder Representations from Transformers)

  • 屬於Transformer的Encoder
  • 只需要訓練Transformer的Encoder(輸入輸出一對一)
  • 透過一堆句子訓練,不需要標註
  • 給一個詞序列,每一個詞都會吐embedding
  • 中文更適合用字為單位,因為用one-hot encoding詞太多了;常用中文字約4800個,中文詞則比這個高數倍
  • Masked LM: 輸入詞序列中隨機15%的詞被換成特殊的Token [Mask],並做預測
  • 預測下一個句子: 引入[SEP]代表兩個句子的交界,及[CLS]代表輸出分類結果的位置
  • 上述兩種方法都是把抽出來[Mask]或[CLS]的Vector丟到Linear Multi-class Classifier去預測詞
  • 以上兩種方法要同時使用
  • 340M個參數

Source: https://arxiv.org/abs/1810.04805

GPT-2(Generative Pre-Training)

  • 屬於Transformer的Decoder
  • 預測下一個Token
  • 40GB的文本訓練出來的
  • 可以做到Zero-shot Learning,不需訓練資料,做到Reading Comprehension(F-score=55接近Dr.QA)、Summarization(跟隨機差不多)、Translation(跟隨機差不多)
  • 1542M個參數

Source: https://d4mucfpksywv.cloudfront.net/better-language-models/language_models_are_unsupervised_multitask_learners.pdf

[對話式AI-6] 模組化的任務導向對話系統實作方法

# 自然語言理解 (Natural Language Understanding)
問句 = input("請輸入你的問題: ") 
使用者動作.意圖 = 意圖識別(問句)
使用者動作.一組槽位 = 槽位填充(問句, 使用者動作.意圖)

# 對話狀態追蹤 (Dialogue State Tracking)
if (使用者動作.意圖 == Null)
  對話狀態.意圖 = 得到意圖(對話歷史)
  對話狀態.一組槽位 = 更新對話狀態(使用者動作.一組槽位, 對話歷史)
else
  對話狀態 = 使用者動作
  填充個性化槽位(對話狀態.一組槽位, 使用者畫像)
  意圖所缺的槽位填入預設值(對話狀態)

# 對話策略學習 (Dialogue Policy Learning)
if (對話狀態.意圖 == Null)
  系統動作.意圖 = "不明"
else if (對話狀態.意圖 == 特定服務)
  if (槽位是否缺失(對話狀態))
    系統動作.意圖 = "對空白槽位提問"
    系統動作.一組槽位 = 對話狀態.一組槽位
   else
    系統動作.意圖 = 特定服務
    系統動作.一組槽位 = 查詢服務API(系統動作.意圖, 對話狀態.一組槽位)

# 自然語言生成 (Natural Language Generation)
if 系統動作.意圖 == "不明"
  問句 = input("我不懂你的意思,請換個方式告訴我: ")
else if 系統動作.意圖 == "對空白槽位提問"
  系統提問 =  提問生成(系統動作)
  問句 = input(系統提問)
else if 系統動作.意圖 == 特定服務
  print(回答生成(系統動作, 回答模板))

[對話式AI-5] 基於知識庫的問答系統實作方法

# 問句分析 (Question Analysis)
問句 = input("請輸入你的問題: ") 
代表問句的一組資訊詞 = 問句分析(問句)
使用者意圖 = 意圖識別(代表問句的一組資訊詞, 知識圖譜)

# 片語映射 (Phrase Mapping)
if (使用者意圖 == Null)
  問句 = input("我不懂你的意思,請換個方式告訴我: ")  
else if (使用者意圖 == 特定服務)
  服務所需的一組資訊詞 = 所缺的資訊詞填入預設值(代表問句的一組資訊詞)
  問句資訊詞的本體 = 自然語言映射到本體(服務所需的一組資訊詞, 知識圖譜)

# 查詢建構 (Query Construction)
  答案的關鍵內容 = 查詢(問句資訊詞的本體, 各種API服務)
  答案的本體 = 服務映射到本體(答案的關鍵內容, 知識圖譜)
  一組候選答案 = 產生答案(答案的本體, 知識圖譜)

# 消歧 (Disambiguation)
    一組候選答案 = 消歧(一組候選答案, 服務所需的一組資訊詞)

# 答案生成 (Answer Generation)
  一個答案 = 排序(一組候選答案)
  回答 = 轉換成自然語言(一個答案, 回答模板)
print(回答)

[對話式AI-1] Chatbot的類型與對比(問答、對話與閒聊系統)

由於常常跟客戶和外部工程師雞同鴨講,最後發現大家對聊天機器人的定義都不一樣;你知道Chatbot可以分成三類嗎?對話式AI專欄的第一篇,就來介紹一下「各類Chatbot的用途」,並針對「開發方法」、「特點」、「關鍵評價指標」及「應用場景」等進行深入對比,讓你一次搞懂Chatbot,不再一知半解。

類別問答系統任務導向對話系統閒聊系統
英文Question Answering systemTask-Oriented Dialogue systemChit-Chat Dialogue system
功能回答使用者問題代替使用者完成任務陪伴使用者閒聊
領域特定領域特定領域 開放領域
方法基於Web檢索、基於知識庫、基於社群模組化(基於規則、資料驅動)、端對端(資料驅動)基於檢索、基於生成
特點單輪對話,著重問句分析(識別資訊詞)多輪對話,著重對話管理多輪對話,著重個性化及情感分析
關鍵指標召回率(Recall)、精確率(Precision)、F-Measure任務完成率、對話耗時、對話輪數、機器模擬使用者評分詞重疊率、詞向量距離、機器模擬使用者評分
應用場景FAQ、教育助理、訂票閒聊、陪伴
知名案例IBM WatsonSiri、Google Assistant微軟小冰、SimSimi
實作方法基於知識庫的問答系統模組化的任務導向對話系統應用搜尋引擎檢索,或訓練Seq2seq模型生成

[對話式AI-8] 研發部門與開發流程介紹

本文以筆者所任職的公司為例;在不涉及公司機密的前提下,介紹人工智慧產品研發的「相關部門、開發流程及工作內容」,為大家揭開AI產業的神秘面紗。

公司主要業務是為電信、金融、政府及電商等領域,導入AI技術、自然語言處理(Natural Language Processing, NLP)技術、系統整合及平台建置,最常幫一些大型機構建置Chatbot及呼叫中心等系統,協助提升客戶服務,並降低人力需求。

AI公司的組織架構

一般AI公司研發中心可以分為下列部門(舉例),橫向為各部門名稱,縱向為組織架構:

  • 研究院 / 知識研究部(算法研究)
  • 自然語言理解NLU研發部 / 語音引擎研發部(算法研究及應用)
  • 基礎產品研發部 / 雲端平台研發部(引擎應用)
  • 產品測試部
  • 解決方案部(產品包裝)
  • 專案實施部(產品應用及二次開發)

AI產品的開發流程

  1. 研究院負責與大學院校合作,閱讀論文並研究前瞻技術後,將研究成果提供給NLU / 語音研發部。同時通報專利申請單位,將有價值的技術註冊成專利。
  2. NLU / 語音研發部將研究成果,實作成底層引擎,並將其轉交給基礎產品研發部。同時通報專利申請單位,將有價值的技術註冊成專利。
  3. 基礎產品研發部負責市場調查、設計產品,並撰寫前後端邏輯,將引擎包裝成Chatbot / 推薦系統(Recommender system)等產品。同時通報專利申請單位,將有價值的技術註冊成專利。
  4. Chatbot / Recommender等產品的基本內容及行業知識,由知識研究部負責建置,如標註資料、建置知識、知識圖譜、預置行業包等。
  5. 解決方案部負責將Chatbot / Recommender產品的各項能力,打包成各個行業的解決方案,提供給業務單位兜售。
  6. 如果客戶有興趣,專案實施部會使用該Chatbot / Recommender等產品 / 解決方案,為客戶無償做POC(Proof of Concept);如果客戶滿意其成果,就會為後續開發簽約付錢。
  7. 專案實施部再根據合約內容完成Chatbot / Recommender等系統建置及介接API等二次開發工作,並提供售後維護服務。公司每年再收取License、維護及再開發費用。

AI產業的工作內容

若你有志投入AI相關產業,可以往以下幾種部門走,但著重的技術都不同:

研究院

一般使用Python語言及TensorFlow、PyTorch及SKlearn等框架研究算法(Algorithm),如語音辨識(Automatic Speech Recognition)、分詞(Word Segmentation),詞性標註(Part of Speech)、句法分析(Syntactic Analysis)、語意分析(Semantic Analysis)、對話管理(Dialogue Management)、自然語言生成(Natural Language Generation)及語音合成(Text to Speech)等。

NLU / 語音研發部

由於Python不適合用於大規模平行計算(Parallel Processing),這裡常使用Java語言,Mahout、Deeplearning4j等框架在Hadoop及Spark上實現算法、引擎、訓練及部署模型。

基礎產品研發部

這裡就比較沒有局限了,什麼語言和框架都可以用,譬如使用Go語言及Gin框架,撰寫後端邏輯,將底層引擎包裝成產品;以及使用Javascript語言、React或Vue等框架開發前端。

專案實施部

根據客戶需求選擇語言及框架,透過Chatbot / Recommender等產品 / 解決方案為客戶二次開發,並提供售後維護服務。

基於深度學習的推薦算法調研

年底因為工作任務,調研了幾篇推薦系統 ( Recommender System ,以下簡稱RS) 的論文;我寫碩論時還不流行深度學習(Deep Learning,以下簡稱DL),轉眼間DL已經成為顯學,近年發表的推薦算法也都是基於DL的研究,我也已經應用在業界的專案中,並獲得了一些進展,但對DL應用在RS的普遍成效,我也是相當好奇。

趁著還記得調研的內容,在此以ACM RecSys 2019最佳論文「Are We Really Making Much Progress? A Worrying Analysis of Recent Neural Recommendation Approaches」為基礎,跟大家分享一些心得:

論文總結:

  • DL應用在電腦視覺CV和自然語言處理NLP領域相當成功,但在其他方面不如預期。
  • 2015到2018年RecSys, WWW, KDD, SIGIR頂級會議共有18篇DL論文與top-n推薦有關,可重現的實驗有7篇,比例約39%;也就是61%的實驗無法重現。
  • 通常做為baseline的方法有非個性化TopPopular、協同過濾CF的ItemKNN、UserKNN、P3alpha、RP3beta,混合的ItemKNN CF + CB,以及機器學習ML的SLIM。
  • 論文作者重現這7個實驗,驗證其進展是否真實,發現DL方法,效果並沒有上述經典的啟發式方法好,在7篇論文中只有1篇優於上述baseline方法,但只是在部分情況下超越。
  • 論文作者認為導致此結果的原因,是這7篇論文挑選了較差的baseline方法和參數、所選擇的測試資料epoch次數不同,甚至有實驗程序不同導致評估錯誤。

個人心得:

  • 為了驗證這幾年的進展,論文作者使用公開資料集作為可重現條件之一,從18篇論文中挑選了7篇重現實驗,但目前的公開資料集有資料量不夠大,矩陣比較不稀疏,以及特徵少等特色;此種資料集並非DL的強項。
  • 公開資料集大多出於學術界,其大小與特徵豐富程度遠低於業界的系統;所以論文作者的結論,以及DL在商用資料集的表現,還有待進一步的驗證。

參考資料:
https://dl.acm.org/authorize?N684126
https://arxiv.org/pdf/1907.06902.pdf

現有命名方法彙整及比較

命名規則是為了增加識別和可讀性,沒有強制的規定,但一旦選擇其中一種,會建議編寫時統一格式;而化學、天文、生物也有其慣用的命名方法;大部分的程式語言也有對此進行建議,以統一風格。

在程式設計的命名上,當變數、函式及類別等名稱由兩個以上的單字組合,就可以使用現有的命名方法,增加識別和可讀性。目前已經出現的命名方法,可以分為Underscore(底線式)、Camel-case(駝峰式)及Hungarian notation(匈牙利命名法)三大類。此文進行彙整,並以個人經驗,探討其優缺點。


Underscore(底線式):

單字之間使用底線分隔,GNU/Linux環境中最常見,例如:string_name。

優點:使用底線取代空格,閱讀上比較直覺易懂。

缺點:比起Camel-case使用字首大寫取代空格,底線比較少在日常輸入,因此需要適應。


Camel-case(駝峰式):

單字之間使用大寫分隔,又可以分為Lower Camel-case(小駝峰式),或Upper
Camel-case(大駝峰式),而後者又稱為Pascal-case(帕斯卡式)。

Lower Camel-case(小駝峰式):
第一個字母用小寫,此變化常用在變數名稱上,例如stringName。

Upper Camel-case(大駝峰式):
第一個字母用大寫,此變化常用在函數、類別、屬性及命名空間上,例如StringName。

優點:

  • 可以利用名稱前綴的大小寫,區分變數,以及函數、類別等其他型別。
  • 單字之間使用大寫取代底線,能夠減少名稱的長度,減少程式碼超出視窗被遮擋的情況。

缺點:

  • 比起Underscore使用底線取代空格,閱讀上較不直覺易懂。

Hungarian notation(匈牙利命名法)

在Camel-case(駝峰式)的基礎上,在名稱前綴添加預先約定好的縮寫,例如約定如下:

b boolean
c character
str C++ String
si short integer
i integer
li long integer
f floating point
d double-precision floating point
ld long double-precision floating point
sz Old-Style Null Terminated String
if Input File Stream
is Input Stream
of Output File Stream
os Output Stream
S declaring a struct
C declaring a class

Source: http://web.mst.edu/~cpp/common/hungarian.html

根據縮寫用途的不同,又可分為Systems Hungarian,以及Apps Hungarian。

Systems Hungarian:
名稱前前綴代表的是實際的資料型別,例如:strName。

Apps Hungarian:
名稱前綴代表的是目的或其他提示,例如:usName,其中us代表unsafe,為了避免Code injection或XSS,之後必須進行過濾處理。

優點:

  • 不需要IDE支援,就能夠從名稱能看出型別。
  • 制定好的編碼規則,能夠在搜尋時更加統一易找。
  • 制定好的編碼規則,能夠在命名及輸入上更快。

缺點:

  • 需要另外學習編碼規則。
  • 現代IDE已經可以輕易的區分型別,在資料型別上,此方法稍嫌多餘。
  • 變數型別修改時,名稱也必須修正維護。
  • 採用縮寫來命名,對新手較不友善,例如szName,不如stringZeroName。
  • 也更容易造成歧義,例如szName,更容易被誤讀成其他意思,也難以透過關鍵字搜尋。