1. 程式人生 > >手把手教你解決90%的自然語言處理問題

手把手教你解決90%的自然語言處理問題

640?wx_fmt=jpeg

640?wx_fmt=gif

640?wx_fmt=png

無論你是成熟的公司,還是想要推出一個新服務,都可以利用文字資料來驗證、改進和擴充套件產品的功能。科學的從文字資料中提取語義並學習是自然語言處理(NLP)研究的一個課題。

NLP每天都會產生新的令人興奮的結果,並且它是一個非常大的領域。然而,在與數百家公司合作之後,Insight團隊發現一些關鍵的實際應用程式比其他應用程式出現得更頻繁,例如:

  • 識別不同的使用者/客戶群體(如預測客戶流失、終身價值、產品偏好);

  • 準確地檢測和提取不同類別的反饋(積極和消極的評論/意見和特定屬性,如衣服尺寸/是否合身);

  • 根據意圖對文字進行分類(例如,基本請求,緊急問題)。

雖然有許多線上NLP檔案和教程,但我們發現很難找到有效地從底層解決這些問題的指導方針和技巧。

這篇文章解釋瞭如何構建機器學習解決方案來解決上面提到的問題。我們將從最簡單的方法開始,然後轉向更細緻的解決方案,比如特性工程、單詞向量和深度學習。

讀完這篇文章,你會知道如何:

  • 收集、準備和檢查資料。

  • 建立簡單的模型,並在必要時向深度學習過渡。

  • 解釋和理解你的模型,以確保你是在獲取資訊而不是噪音。

我們把這篇文章作為一個分步指南;它還可以作為高度有效的標準方法的高階概述。

這篇文章附帶了一個互動式筆記本,演示和應用所有這些技術。

互動式筆記本地址:https://github.com/hundredblocks/concrete_NLP_tutorial/blob/master/NLP_notebook.ipynb

Part

1

收集資料

示例資料來源

每一個機器學習問題都是從資料開始的,比如電子郵件、帖子或推文。文字資訊的來源包括:

  • 產品評論(在亞馬遜,Yelp和各種應用商店);

  • 使用者生成內容(推文, Facebook帖子,StackOverflow問題);

  • 故障排除(客戶請求、支援票、聊天記錄)。

“社交媒體災難”資料集

對於這篇文章,我們將使用CrowdFlower提供的稱為“社交媒體災難”的資料集,其中:

參與者查看了超過10,000條推文,其中包括“著火”、“隔離”和“防疫”等各種關鍵字的搜尋,然後指出這條推文是否提到了災難事件(而不是帶有關鍵字的電影評論或笑話,和一些非災難性的事件)。

我們的任務是檢測哪些推文是關於災難性事件的,而不是像電影這樣無關緊要的話題。這個任務的特別在於,兩個類都包含相同搜尋詞,因此我們將不得不使用更微妙的差異來區分它們。

在這篇文章的餘下部分中,我們將把有關災難的推文稱為“災難”,並把其他的推文稱為“無關”。

標籤

我們已經標記了資料,因此我們知道哪些推文屬於哪個類別。正如Richard Socher所描述的那樣,與試圖優化複雜的無監督方法相比,用查詢和標記足夠的資料來訓練模型,更快、更簡單、成本更低。

640?wx_fmt=png

Richard Socher的觀點

Part

2

清洗資料

我們遵循的第一條規則是:“資料的好壞影響著你的模型。”

資料科學家的關鍵技能之一就是知道下一步應該是研究模型還是資料。經驗告訴我們應該先檢視資料然後再洗資料集。乾淨的資料集將允許模型學習有意義的特性,而不是過度擬合無關的噪音。

以下是用來清洗你的資料的清單(詳見程式碼):

  1. 刪除所有不相關的字元,例如任何非字母數字字元(non alphanumeric character)。

  2. 把文字分成單獨的單詞來令牌化文字。

  3. 刪除不相關的單詞,比如“@”或url。

  4. 將所有字元轉換為小寫,如“hello”, “Hello”和“HELLO” 。

  5. 考慮將拼錯的單詞組合成一個單獨的表示(如“cool”“kewl”“cooool”)

  6. 考慮lemmatization(減少諸如“am”、“are”和“is”這樣的常見形式,例如“be”)

程式碼地址:https://github.com/hundredblocks/concrete_NLP_tutorial/blob/master/NLP_notebook.ipynb

令牌化地址:https://nlp.stanford.edu/IR-book/html/htmledition/tokenization-1.html

在遵循這些步驟並檢查其他錯誤之後,我們可以開始使用乾淨的、標記的資料來訓練模型。

Part

3

找到一個好的資料表示

機器學習模型以數值作為輸入。例如,對影象進行處理的模型,利用矩陣表示顏色通道中每個畫素的強度。

640?wx_fmt=png

以數字矩陣表示的笑臉

我們的資料集是句子的列表,為了讓我們的演算法從資料中提取模式,我們首先需要找到一種方法以演算法能夠理解的方式來表示它,也就是一個數字列表。

獨熱編碼(詞袋)

表示計算機文字的一種方法是將每個字元單獨編碼為一個數字(例如ASCII)。如果我們要將這個簡單的表示輸入到分類器中,那麼它必須只根據我們的資料來學習單詞的結構,這對於大多數資料集來說是不可能的。我們需要使用更高階的方法。

例如,我們可以在我們的資料集中建立一個包含所有單詞的詞彙表,併為詞彙表中的每個單詞建立一個唯一索引。每個句子都被表示成一個列表,這個列表的長度取決於不同單詞的數量。在這個列表中的每個索引中,我們標記出給定詞語在句子中出現的次數。這被稱為詞袋模型,因為它是一種完全無視句子中詞語順序的表現形式。以下是插圖說明:

640?wx_fmt=png

把句子表示為詞袋。左邊是句子,右邊是數字表示。向量中的每一個索引都代表一個特定的單詞。

視覺化嵌入

在“社交媒體災難”資料集中,我們大約有2萬個單詞,這意味著每個句子都將被表示成長度為20000的向量。這每個句子只包含了我們詞彙量的一小部分。

為了檢視嵌入是否捕獲了與我們問題相關的資訊(例如,推文是否與災難有關),視覺化它們並檢視分類是否正確,是一個好方法。由於詞彙表是非常大的,並且在20,000個維度中視覺化資料是不可能的,像PCA這樣的技術將有助於將資料壓縮到兩個維度。

640?wx_fmt=png

視覺化詞袋嵌入

這兩個類看起來並沒有很好地分離,這可能是嵌入的一個特性,或者僅僅是維度縮減。為了瞭解這些詞袋的特點是否有任何用途,我們可以用它們來訓練分類器。

Part

4

分類

當第一次嘗試時,最好的做法一般是從最簡單的工具開始著手解決問題。每當提到資料分類時,人們最喜歡用的是邏輯迴歸。這是非常簡單的訓練,結果是可以解釋的,你可以很容易地從模型中提取最重要的係數。

我們將資料分解到一個訓練集中,用於擬合我們的模型和測試集,以檢視它對不可見的資料的概括程度。經過訓練,我們的準確率達到75.4%。不是太糟糕。

Part

5

檢查

混淆矩陣

第一步是瞭解我們的模型所犯錯誤的型別,以及哪些錯誤是最不可取的。在我們的例子中,誤報將一個無關的推文歸類為災難,而漏報則將災難推文分類為“無關”。如果首要任務是對預測災難事件,我們就要降低我們的漏報率。如果我們在資源方面受到限制,我們可能會優先考慮降低誤報率以減少假警報。一個很好的視覺化這個資訊的方法是使用混淆矩陣,它比較了我們的模型預測和真實標籤。理想情況下,矩陣將是一條從左上到右下的對角線(我們的預測完全符合事實)。

640?wx_fmt=png

混淆矩陣(綠色是高比例,藍色是低比例)

我們的分類器的漏報率高於誤報率(比例)。換句話說,我們的模型最常見的錯誤是錯誤地將災難分類為“無關”。

解釋模型

為了驗證我們的模型並解釋它的預測,重要的是看一下它用哪些單詞來做決策。如果我們的資料有偏差,我們的分類器會在樣本資料中做出準確的預測,但是模型在現實世界中不會很好地泛化。在這裡,我們為“災難”和“無關”類找出最重要的單詞。用詞袋和邏輯迴歸來繪製單詞的重要度是很簡單的,因為我們可以提取和排列模型用於預測的係數。

640?wx_fmt=png

詞袋:單詞的重要度

我們的分類器正確地選擇了一些模式(廣島,大屠殺),但顯然似乎是過度擬合一些無意義的術語(heyoo, x1392)。現在,我們的詞袋模型是處理大量的詞彙,並對所有單詞一視同仁。然而,有些詞出現頻率非常高,而且只會對我們的預測造成干擾。接下來,我們將嘗試用一種方法來表示能夠解釋單詞頻率的句子,看看是否能從資料中獲得更多的訊號。

Part

6

詞彙結構

TF-IDF

為了幫助我們的模型更多地關注有意義的單詞,我們可以在我們的詞袋模型的頂部使用TF-IDF評分(術語頻率,逆文件頻率)。TF-IDF通過單詞在資料集中出現的頻率來衡量單詞,在我們的資料集裡,一些詞是非常罕見的,而有些詞太過頻繁,只會增加噪音。這是我們新嵌入的PCA投影。

640?wx_fmt=png

視覺化TF-IDF嵌入

我們可以看到,這兩種顏色之間有更明顯的區別。這將使我們的分類器更容易區分兩個組。讓我們看看這會不會帶來更好的效能。在我們新的嵌入式系統上訓練另一個邏輯迴歸,我們得到了76.2%的精確度。

一個輕微的改善。我們的模型是否開始研究更重要的詞彙?如果我們得到了更好的結果,同時防止模型“欺騙”我們,那麼我們就可以真正地考慮升級這個模型。

640?wx_fmt=png

TF-IDF:文字的重要度

它挑選的單詞看起來更有意義!雖然我們在測試集上的度量只稍微增加了一點,但是我們對我們的模型使用的術語有了更多的信心,因此在將它部署到與客戶互動的系統中會更好。

Part

7

利用語義

Word2Vec

我們的最新模型設法獲得高訊號單詞。然而,很有可能的是,如果我們部署這個模型,我們將會遇到以前在我們的訓練中沒有看到的單詞。之前的模型將無法準確地對這些推文進行分類,即使在訓練過程中看到了非常相似的單詞

為了解決這個問題,我們需要掌握詞語的語義。用來幫助我們捕捉語義的工具叫做Word2Vec。

使用預先訓練的單詞

Word2Vec是一種查詢單詞連續嵌入的技術。它聽過閱讀大量的文字來學習,並記住在類似的語境中出現的單詞。在對足夠的資料進行訓練之後,它會在詞彙表中為每個單詞生成一個300維的向量,這些單詞之間的意思相近。

論文的作者開源了一個在非常大的語料庫中預先訓練的模型,我們可以利用它將一些語義的知識包含進我們的模型中。預先訓練的向量可以在相關的資源庫中找到。

論文地址:https://arxiv.org/abs/1301.3781

資源庫地址:https://github.com/hundredblocks/concrete_NLP_tutorial

句子層面上的表示

讓句子快速嵌入分類器的方法,是平均在我們的句子所有單詞的Word2Vec分數。這是與以前方法類似的詞袋,但是這次我們只去掉了句子的語法,同時保留一些語義資訊。

640?wx_fmt=png

Word2Vec句子嵌入

下面是我們使用以前的技術實現的新嵌入的視覺化:

640?wx_fmt=png

視覺化Word2Vec嵌入

這兩組顏色看起來更加分離,我們的新嵌入應該幫助分類器找到兩個類之間的分離。在第三次(邏輯迴歸)訓練了相同的模型後,我們的準確率為77.7%,這是我們最好的結果。是時候檢查我們的模型了。

複雜性/可解釋性權衡

由於我們的嵌入沒有像我們以前的模型那樣表示為每個單詞的一維向量,所以很難看出哪些單詞與我們的分類最相關。雖然我們仍然可以使用邏輯迴歸的係數,但它們與我們的嵌入的300個維度有關,而不是單詞的索引。

對於如此低的精確度,失去所有的解釋能力似乎是一種苛刻的取捨。但是,對於更復雜的模型,我們可以利用像LIME這樣的黑箱直譯器來了解我們的分類器是如何工作的。

LIME

Github通過開源軟體包提供LIME。黑箱直譯器允許使用者通過擾動輸入(在我們的例子中是從句子中移除單詞)和觀察預測如何改變來解釋任何分類器在一個特定示例上的決定。

Github資源包地址:https://github.com/marcotcr/lime

讓我們來看看我們的資料集中的幾個句子的解釋。

640?wx_fmt=png

真正的災難詞被識別為“相關”

640?wx_fmt=png

詞語對分類的貢獻似乎不那麼明顯

但是,我們沒有時間去探索資料集中的數以千計的例子。我們要做的是在一個有代表性的測試示例樣本上執行LIME,看看哪些詞對於分類貢獻度最高。使用這種方法,我們可以得到單詞重要度分數,並驗證我們模型的預測。

640?wx_fmt=png

Word2Vec:文字的重要性

看起來模型提取出了高度相關的單詞,這些單詞暗示它做出可以理解的決定。這些看起來像是以前所有模型中最相關的詞彙,因此我們更願意部署到生產中。

Part

8

使用端到端的方法利用語法

我們已經介紹了快速有效的方法來生成緊湊的句子嵌入。然而,通過省略單詞的順序,我們放棄了句子的所有語法資訊。如果這些方法不能提供足夠的結果,則可以使用更復雜的模型,將整個句子作為輸入並預測標籤,而不需要建立中間表示。一種常見的方法是使用Word2Vec或其他方法,如GloVe或CoVe,將句子作為一個單詞向量的序列

640?wx_fmt=png

高效的端到端架構

卷積神經網路的句子分類訓練非常快,並且適用於作為入門級的深度學習架構。雖然卷積神經網路(CNN)主要以其在影象資料上的效能而著稱,但它們在與文字相關的任務上的效能也非常好,而且通常比大多數複雜的NLP方法(例如LSTM和編碼器/解碼器架構)要快得多。這個模型儲存了單詞的順序,並且學習了關於哪些單詞序列可以預測目標類的有價值的資訊。與以前的模式相反,它可以區分“Alex eats plants”和“Plants eat Alex.”。

訓練這個模型不需要比以前的方法做更多的工作(詳見程式碼),並且得到的模型會比以前的好得多,準確率高達79.5%。與上面的模型一樣,下一步應該使用我們描述的方法來探索和解釋預測,以驗證它確實是最佳模型。

程式碼地址:https://github.com/hundredblocks/concrete_NLP_tutorial/blob/master/NLP_notebook.ipynb

最後

成功方法的快速回顧:

  • 從一個快速簡單的模型開始。

  • 解釋其預測。

  • 理解所犯的錯誤。

  • 使用這些知識來提示下一步,無論是處理資料,還是一個更復雜的模型。

這些方法被應用到一個特定的示例案例中,使用定製的模型來理解和利用諸如推文之類的短文字,但是這些想法廣泛適用於各種問題。

640?wx_fmt=gif

ML & AI

640?wx_fmt=jpeg640?wx_fmt=png

長按,識別二維碼,加關注