怎樣用機器學習8步解決90%的天然語言處理問題?

歡迎關注咱們,AI教程、趣味科普、論文解讀,一網打盡!


文本數據無處不在git

無論你身處已經開張的公司仍是即將開展的新業務,均可以利用文本數據去驗證、優化和擴展產品性能。而從文本數據中學習和提取價值的研究科學就叫作天然語言處理(NLP)。github

NLP 天天都能產生新奇而又使人興奮的結果,也是一個很大的領域。然而,縱觀不少公司對NLP 的應用,下面這些應用頻繁出現:算法

  • 識別不一樣類型的用戶/顧客(例如,預測波動情況,終身價值,產品偏好)網絡

  • 精準檢測和提取不一樣種類的反饋(負面或正面評論/意見,說起的特別屬性,如衣服尺碼/合身與否)架構

  • 根據目標分類文本數據(例如,用戶請求的是基本幫助仍是緊急問題)機器學習

雖然當前網上已經有不少 NLP 論文和教程,可是不多介紹怎樣從頭開始有效解決這些問題的指南和竅門。工具

本文將怎樣幫到你post

本文會解釋如何用機器學習方法解決上面提到的問題,咱們會介紹一些最簡單也有效的方法,而後再談談複雜些的方法好比特徵工程、詞向量和深度學習。性能

閱讀本文後,你會知道怎樣:學習

  • 收集、準備和檢查數據

  • 搭建簡單的模型,若是須要,開始和轉移至深度學習

  • 演繹和理解你的模型,確保你在獲取正確的信息而不是噪聲數據

本文是一篇逐步解決問題的教程(建議先收藏,後面一步步動手實踐),也能夠看做解決 NLP 問題的標準方法的高度歸納。

第一步:收集數據

樣本數據來源

每一個機器學習問題都是以數據開始,好比郵件列表、博文或社交網站發佈的狀態等。

常見文本數據來源包括:

  • 產品評論(如電商網站、點評網站、應用商店上的評論)

  • 用戶生成內容(微博、推特、臉書上發佈的狀態;Quora、知乎等問答網站的問題)

  • 疑難解答(顧客請求,支持問題,聊天記錄)

「社交媒體災難」數據集(「Disasters on Social Media」)

在本文,咱們使用 CrowdFlower 提供的一個數據集,叫作 「社交媒體災難」

該數據集收集了超過1萬條推特推文,包含「着火」「隔離」「混亂」這樣的詞彙,而後註明推文中說起的災難事件是否發生過。

咱們的任務是檢測哪些推文是和真實災難有關,而不是某個不相關的話題好比災難電影。爲何是這樣?社交網站上可能會添加一項功能專門提醒執法官員出現了緊急狀況,但同時不會將災難電影的評論也考慮在內。這項任務的一個主要挑戰就是上面這兩種推文都包含一樣的搜索關鍵詞,所以咱們必須利用微妙的差別去區分它們。

如下咱們會將關於災難的推文引述爲「災難推文」,將關於其它事情的推文引述爲「無關推文」。

標籤

咱們已經將數據打上標籤,所以咱們知道哪些推文屬於哪一個類別。如圖 Richard Socher 以下所說,找到和標記足夠的數據來訓練模型,每每比試圖優化一個很複雜的無監督式方法要快得多、簡單的多,也省時省力的多。

第2步:清洗數據

咱們首先要清楚:「你的模型質量始終和數據的質量一致」

數據科學家的一項核心技能就是知道下一步是該處理數據仍是模型。一個好方法就是先檢查數據,而後清洗數據。一個乾淨的數據集會讓模型學習到有意義的特徵,而不會過擬合無關的噪聲數據。

下面是清洗數據的方法列表:

  • 刪除全部可有可無的文字好比任何非字符數值的文字。

  • 將文本數據分割爲單獨文字,也就是將文本數據進行tokenize(將一行拆分爲單詞長度的片斷)。

  • 將全部文字轉換爲小寫字母,目的是將「Hello」「hello」「HELLO」這樣的字詞一視同仁。

  • 考慮將拼錯的單詞或交替拼寫的單詞合併爲一個單獨的表達方式(好比cool/kewl/coool)。

  • 考慮詞形還原(例如將「am」「are」「is」這樣的詞縮減爲常見的表達形式「be」)。

點擊連接可查看上述步驟的代碼。

遵循以上步驟後,再檢查一下其它的錯誤,而後咱們就能夠開始清理和標記數據用於訓練模型了!

第三步:找到合適的數據表示形式

機器學習模型將數值做爲輸入。例如,模型在處理圖像時,會讓一個矩陣表示每一個顏色通道中每一個像素的密度。

咱們的數據集是一系列的句子,因此爲了能讓咱們的算法提取出數據的模式,咱們首先須要找到一個合適方式表示數據,能讓咱們的算法理解它,好比,一列數字。

獨熱編碼(One-hot encoding)(詞袋模型)

爲計算機表示文本數據的一個天然方式就是將每一個字單獨編碼爲一個數字(例如 ASCII)。若是咱們用這種簡單表示形式的數據輸入分類器,那麼它必須從頭開始根據咱們的數據學習詞彙的結構,這對大多數數據集來講是行不通的。咱們須要一種更高水平的方法。

例如,咱們能夠給數據集中全部特殊的詞建立一個詞表,爲詞表中每一個詞關聯一個特殊索引。而後將每一個句子表示爲一個列,和詞表中特殊詞的數目同樣長。在這個列的每一個索引上,咱們標記出給定詞在句子中出現的次數。這種方法就叫作詞袋模型,由於它的表示形式徹底忽略了句子中詞彙的順序。該模型以下圖所示:

可視化詞嵌入模型

在本文的「社交媒體災難」樣本中,咱們的詞表中大約有 2 萬個詞彙,這意味着每一個句子會表示爲一個長度爲 20000 的向量。該向量大部分狀況下元素爲 0,由於每一個句子只是詞表的一個很是小的子集。

爲了看清咱們的嵌入是否獲取了和咱們的問題相關的信息(例如,推文是否關於災難),將它們可視化是個很好的方式,能夠看清是否很好地進行了分類。因爲詞表一般很大,於是可視化 2 萬個維度的數據是不可能的,像 PCA(主成分分析)這樣的方法有助於將數據降至 2 個維度,以下圖所繪:

這兩個類別看起來並無很好的分離,這多是由於咱們嵌入的某個特徵,或僅僅是下降的特徵維度。要想看看詞袋模型學習到的特徵有沒有用,咱們能夠根據它們訓練一個分類器。

第四步:分類

當解決一個問題時,一般最好的實踐方法就是先以能解決問題的最簡單的工具開始。無論是何時分類數據,從功能性和可解釋性的角度講,最多見的方式是邏輯迴歸。訓練邏輯迴歸很是簡單,結果也是可解釋的,咱們能夠很容易地從模型中提取最重要的係數。

咱們將咱們的數據切分爲一個用於訓練模型的訓練集,和一個用於檢驗模型性能的測試集。在訓練後,咱們的模型準確率達到了 75.4%。emmmm...還不賴!不過,即使 75%的準確率足以知足咱們的要求,咱們也必須在應用模型前對它有個全面的瞭解。

第五步:檢查

混淆矩陣

第一步是理解咱們模型所犯錯誤的類型,以及咱們最不但願出現哪一種錯誤。在本文例子中,假陽性是將「不相關推文」分類爲「災難推文」,假陰性是將「災難推文」分類爲「不相關推文」。若是優先選項是對每一個潛在的事件作出反應,咱們會但願下降假陰性。然而,若是資源受限,咱們可能會優先下降假陽性,以下降錯誤警報。將這種信息可視化的一個好方法就是用混淆矩陣,它會將咱們模型的預測和實際標籤進行比較。理想情況下,矩陣會是一個自左上角至右下角的對角線(咱們模型的預測和實際狀況匹配的很好)。

咱們的分類器建立的假陰性樣本要多於假陽性樣本。換句話說,咱們模型的常見錯誤是沒有準確地將「災難推文」分類爲「不相關推文」。若是假陽性樣本表明執法人員的成本很高,那麼這種錯誤能夠算是咱們模型的一個好的誤差。

解釋和演繹模型

爲了驗證模型和演繹模型的預測,查看模型使用什麼詞彙作出決策很是重要。若是咱們的數據存在偏置,那麼分類器會對樣本數據作出準確的預測,但模型在現實狀況中不會很好地泛化未見數據。這裏咱們爲「災難推文」和「不相關推文」劃分出最重要的詞彙。使用詞袋模型和邏輯迴歸劃出詞彙的重要性很簡單,由於咱們只需提取模型用於作出預測的係數,並將係數排名。

咱們的分類器正確地識別出一些模式,但很明顯在某些無心義的詞上存在過擬合現象。如今,咱們的詞袋模型能處理龐大詞彙表內的不一樣詞彙,並對全部的詞彙分配相同的權重。然而,其中有些詞出現的很是頻繁,只會給模型的預測帶來干擾。下一步,咱們會嘗試用可以計算詞彙頻率的方式表示句子,以此弄清咱們是否能從數據中獲取更多的信號。

第六步:計算詞彙結構

TF-IDF 嵌入模型

爲了幫助咱們的模型更多的關注有意義的詞彙,咱們能夠在詞袋模型上使用 TF-IDF 評分(詞頻-逆向文件頻率)。TF-IDF 會根據詞彙在數據集中的稀有程度爲詞彙賦予權值,不考慮詞彙是否過於頻繁。下面是咱們 TF-IDF 嵌入模型的 PCA 映射:

從上圖咱們能夠看到,兩種顏色之間的不一樣更加清晰。這能讓咱們的分類器更容易地將兩組數據分離。咱們看看這是否會提升模型的性能。用新模型上訓練另外一個邏輯迴歸後,咱們獲得了 76.2%的正確率。

雖然稍微有些改善,但咱們的模型開始選擇更重要的詞彙了嗎?若是咱們在防止模型「做弊」的同時,獲得的結果也愈來愈好,那麼咱們就能夠真的相信模型確實獲得了改進。

模型選擇的詞彙看起來比以前相關多了!雖然咱們測試集中的權值僅增長了一點點,但咱們對模型有足夠的信心,這樣就能夠放心大膽地部署模型了。

第七步:利用語義信息

Word2Vec

TF-IDF 嵌入模型可以學習到信號更高頻的詞彙,可是若是咱們部署這個模型,咱們極可能會遇到在訓練集中從未見過的詞彙。以前的模型就不能準確分類這些推文,即使在訓練中見過很是相近的詞彙。

爲了解決這個問題,咱們須要獲取詞彙的語義意義,也就是說咱們須要理解像「good」(好的)和「positive」(正的)這樣的詞彙之間的語義,比「apricot」(杏子)和「continent」(大洲)之間的語義要相近的多。幫咱們獲取詞彙語義意義的工具叫作Word2Vec。

使用預訓練模型

Word2Vec 是 Google 開源的一款用於詞向量計算的工具。它能夠經過閱讀大量的文本和記憶哪些詞傾向於出如今相同語境中進行學習。在用足夠多的數據訓練 Word2Vec 後,它會爲詞表中的每一個詞彙生成一個 300 維度的向量,而且意思相近的詞彙離得更近。

有人開源了一個用超大數據集訓練而成的預訓練模型,咱們能夠利用它將一些語義方面的知識添加進咱們的模型。預訓練向量能夠在本教程的相關代碼倉庫中找到。

語句分級表示

爲咱們的分類器獲得句式嵌入(sentence embedding)的快速方法就是用 Word2Vec 給咱們句子中全部的詞評分。這其實就是咱們剛纔用的詞袋模型法,但此次咱們只丟棄句子的語法,而保留語義信息。

下面是用剛纔提到的方法將咱們的新嵌入可視化後的效果:

這兩種顏色羣組看起來進一步分離,咱們的新嵌入應該幫助了分類器發小兩種類別的分離之處。又一次訓練這個模型後,咱們獲得了 77.7% 的準確率,迄今最好結果!是時候檢查模型了。

複雜性與可解釋性之間的權衡取捨

因爲新模型沒有像以前模型那樣,將單詞表示爲一個一維向量,於是查看和咱們的分類最相關的詞彙更難了。雖然咱們仍然能獲取邏輯迴歸的係數,但它們和咱們詞彙的 300 個維度相關而非詞彙的索引。

雖然模型的準確度有所提升,但若是沒法進行可解釋性分析那就有點得不償失了。然而,若是模型的複雜性進一步提升,咱們能夠用 LIME 這樣的「黑盒解釋器」,從而對分類器的工做原理有一點了解。

LIME

能夠在 GitHub 上獲取 LIME 的開源工具包

黑盒解釋器可讓用戶經過擾亂輸入(在咱們的案例中是從句子中移除單詞)和查看預測的改變狀況,根據一個特定的例子就能解釋任何分類器作出的決策。

咱們看幾個對咱們數據集中的語句所作的解釋:

圖:正確分類的災難性詞彙被歸類爲「相關」

圖:這個詞對分類的影響彷佛不太明顯

然而,咱們並無時間探究數據集中的數千個樣本。相反,咱們會在測試集的表明樣本上運行 LIME ,看看哪些詞對分類預測的影響一直很大。經過這種方式,咱們能夠像以前同樣獲取單詞的重要性分數,驗證模型的預測結果。

看來模型可以提取高度相關的詞彙,代表它能作出可解釋的決定。這些詞的相關度在全部模型中彷佛是最高的,所以咱們會更願意部署這樣的模型。

第八步:用端到端的方法使用語法信息

咱們已經介紹過怎樣快速高效地生成緊湊的句子嵌入。不過,經過省略了詞彙的順序,咱們也放棄了句子的所有語法信息。若是這些方法未能產生滿意的結果,你可使用更復雜的模型:將整個句子做爲輸入和預測標籤,並沒有需建立中間表示。這麼作的一個常見方法是將句子看做詞向量的序列,使用 Word2Vec 或一些新工具如 GloVe 和 coVe 等均可以。

下面咱們詳細說說。

用於語句分類的卷積神經網絡(CNN)訓練起來很快,做爲一個入門級的深度學習架構效果也很好。雖然 CNN 向來以處理圖像數據著稱,但它們在處理文本相關的任務上一樣效果良好,並且經常比大多數複雜的天然語言處理方法速度快得多(好比 LSTM)。CNN 在保留詞彙順序的同時,還會學習詞彙序列等有價值的信息。相較於以前的模型,它能區分出「Alex eats plants」(Alex 吃植物)和「Plants eat Alex」(植物吃 Alex)之間的不一樣。

相比先前模型,訓練 CNN 並不須要作更多工做,點擊查看詳細代碼 ,並且獲得的模型比咱們以前的模型性能還要好,準確率達到了 79.5% !

與前面介紹的步驟同樣,下一步應該是用咱們講的方法探究和解釋模型的預測結果,以驗證確實是能夠部署的最佳模型。到了這一步,你應該能本身完成這裏的操做了。

最後小結

咱們迅速回顧一下各步所用的方法:

  • 首先以一個簡單迅速的模型着手

  • 解釋模型的預測結果

  • 弄懂模型犯了什麼類型的錯誤

  • 根據這些知識決定你的下一步——處理數據仍是應用更復雜的模型

雖然本教程所用的方法只用於特定的例子——使用合適的模型進行理解和應用推文這樣的短文本,但這種理念和思路適用於各類問題。但願本文對你有所幫助,若有問題和建議,歡迎提出!

向你推薦:

一文讀懂CNN如何用於NLP

邊看邊練的簡明機器學習教程

相關文章
相關標籤/搜索