不管是已經成熟的企業或是正要上線新業務,你均可以利用文本數據來驗證、提高以及擴展產品的功能。這種從文本數據中提取含義並進行學習的科學叫作天然語言處理(Natural Language Processing, NLP),是當前很是熱門的研究課題。算法
NLP 是一個很是大的研究領域且天天都在產生一些新的激動人心的成果。通過和上百家企業的合做,咱們 Insight 團隊從中發現了幾個關鍵的實際應用,這些應用會有更高的出現頻率:微信
識別使用者 / 客戶不一樣的用戶羣(例如預測用戶流失、生命週期價值、產品偏好等)網絡
精準檢測和提取反饋分類(例如正面和負面的評論 / 觀點,對諸如衣服尺寸、溫馨度等一些特別屬性的說起)架構
根據意圖進行文本分類(例如請求普通幫助,緊急問題處理)機器學習
鑑於 NLP 的文章和指南不少都存在於網絡上,咱們發現很難找到對處理這些問題完全有效的指導或建議。工具
咱們在這一年裏作了數百個項目,並吸收了全美頂尖團隊的建議,整理出這篇文章來講明如何使用機器學習解決上述問題。咱們將從最簡單可行的方法提及,而後進階到更細緻的解決方案,例如特徵工程、詞向量以及深度學習等。學習
讀完這篇文章,你將會知道如何去:測試
收集、準備和檢測數據大數據
從創建簡單模型開始,必要時使用深度學習來過渡優化
解釋和理解模型,來確保你實際捕獲的是有效信息而不是噪聲
這篇文章是一份按部就班的操做指南,也是一份對高效標準化過程的高度歸納。
文章還附帶了一份互動筆記,裏面對全部涉及到的技術都進行了論證和應用。你能夠嘗試邊運行代碼邊看下文。
每個機器學習問題都始於數據,好比一組郵件、帖子或是推文。文本信息的常見來源包括:
商品評價(來自 Amazon、Yelp 以及其餘 App 商城)
用戶產出的內容(推文、Facebook 的帖子、StackOverflow 的提問等)
問題解決(客戶請求、技術支持、聊天記錄)
在這篇文章中,咱們將使用 CrowdFlower 提供的一個數據集,名爲「社交媒體中的災難(Disasters on Social Media)」。
貢獻者們查看了超過 10000 條具備相似「着火」、「隔離」、「混亂」等搜索關鍵詞的推文,而後標記這個推文是否和災難事件有關(與之相反的是一些玩笑、電影點評或是一些非災難性的事件)。
咱們的任務是分辨出哪些推文是真正和災難事件相關的,而不是一些相似電影描述的不相關話題。爲何呢?一個潛在的應用是針對突發事件對執法人員進行專門的提醒,而不會被其餘無關信息,好比 Adam Sandler 新上映的電影所幹擾。這項任務中一個特別的挑戰是這兩種狀況在搜索推文的時候都用到了相同的檢索詞,因此咱們只能經過細微的差異去區分他們。
在下面的文章中,咱們將把與災難事件相關的推文稱爲「災難」,將其餘推文稱爲「不相關的」。
咱們已經標註過數據,因此知道推文是如何分類的。如 Richard Socher 所說,比起優化一個複雜的無監督學習方法,尋找和標記足夠多的數據來訓練模型會更加快捷、簡單和廉價。
Richard Socher 的高級技巧
咱們要遵循的首要原則是:「你的模型必須和你的數據同樣好。」
數據科學家的一個必備技能是知道本身的下一步操做是處理模型仍是數據。有一個好的經驗法則是先觀察數據而後進行數據清洗。一個乾淨的數據集能使模型學習到有意義的特徵而不會被一些不相關的噪聲影響。
能夠借鑑下方的列表來進行數據清洗:(查看代碼獲取更多信息)
去除一切不相關的字符,好比任何非字母數字的字符
標記你的文本,將他們拆分爲獨立的單詞
去除不相關的詞語,好比 @這類提醒或是 url 連接
將全部字母轉換成小寫,這樣「hello」,「Hello」,「HELLO」就會被當作一樣的單詞處理
將拼錯的單詞或是多種拼法的單詞與某個特定的表達綁定(好比:「cool」/「kewl」/「cooool」)
考慮詞形還原(好比將「am」,「are」,「is」都看作「be」)
完成這些步驟並檢查完其餘錯誤後,咱們就可使用這些乾淨的、標記過的數據進行模型訓練了!
機器學習模型會使用數值做爲輸入。例如處理圖像的模型會用矩陣來表示每一個顏色通道像素的亮度。
用數字矩陣表現的笑臉
咱們的數據集是一系列的句子,爲了使咱們的算法能從數據中提取特徵,首先須要找到一種算法可以理解的表達方式,好比一串數字。
一般爲計算機解釋文本的方法是將每個字符都編爲一個獨立的數字(例如 ASCII 碼)。若是使用這種簡單的表達來作分類器,須要咱們的數據從頭開始學習詞語的結構,這對大多數數據集來講是很難實現的。因此咱們須要一種更上層的方法。
例如,咱們能夠爲數據集中的全部單詞製做一張詞表,而後將每一個單詞和一個惟一的索引關聯。每一個句子都是由一串數字組成,這串數字是詞表中的獨立單詞對應的個數。經過列表中的索引,咱們能夠統計出句子中某個單詞出現的次數。這種方法叫作 詞袋模型,它徹底忽略了句子中單詞的順序。以下圖所示:
用詞袋模型表示句子。句子在左邊,模型表達在右邊。向量中的每個索引表明了一個特定的單詞。
在「社交媒體中的災難」樣本詞表中大概會有 20000 個單詞,這意味着每句句子都會用一個長度爲 20000 的向量來表示。向量的 大部分會被 0 填充,由於每句話只包含了詞表中很小的一個子集。
爲了看出嵌入的工做是否真正抓住了和問題相關的信息(好比推文是否與災難相關),有一個好方法是將它們可視化,而後觀察結果是否有很好的分佈。考慮到詞表一般很大,並且用 20000 維的數據作可視化是基本不可能的,因此咱們使用了 PCA 這種技術將數據降到二維。繪製以下:
詞袋模型嵌入的可視化
兩個分類看起來沒有很好的分離,這多是咱們選擇的嵌入方法的特徵或是單純由於維度的減小引發的。爲了瞭解詞袋模型的特徵是否會起一些做用,咱們能夠試着基於它訓練一個分類器。
當初次接觸一個問題,一般來講最好的方法是先挑選一個能解決問題的最簡單的工具。當提到數據分類時,通常最受歡迎的是通用性和可解釋性兼具的邏輯迴歸算法。這種算法很容易訓練並且結果也是可解釋的,你能夠很輕鬆地從模型中提取出最重要的一些係數。
咱們將數據分爲兩個集合,訓練集用於匹配模型,測試集用於觀察應用在未知數據上的效果。訓練後咱們獲得了 75.4% 的精確度。結果還不錯!推測出現最多的類(「不相關」)只能達到 57%。可是,即便是 75% 的精確度也已經足夠好了,咱們決不能在尚未理解模型的狀況下就開始應用它。
第一步是理解咱們的模型會產生哪些錯誤類型,哪些錯誤是咱們最不但願出現的。在例子中,誤報(false positive)是指將不相關的推文歸爲災難,漏報(false negative)是指將真實災難歸爲不相關的。若是須要優先響應全部潛在事件,咱們須要下降漏報率。若是是資源有限,咱們就須要優先下降誤報率來減小錯誤告警。咱們可使用混淆矩陣來可視化這些信息,它能將模型的預測與真實的標籤進行比較。理想狀態下,矩陣將造成一條貫穿左上角至右下角的對角線(此時預測值和真實值完美匹配)。
混淆矩陣(綠色是高比例,藍色是低比例)
咱們的分類器生成的漏報要比誤報多(按比例)。換句話說,咱們模型最多見的錯誤是將災難事件錯誤地劃分到了不相關的分類。若是誤報會形成法律實施上的高昂成本,這對咱們的分類器來講多是個好事。
爲了驗證咱們的模型並解釋它的預測,就須要觀察它是用哪些詞來作決策的。若是咱們的數據自己有誤差,分類器能基於樣例數據作出準確的預測,可是將模型應用在真實世界中的結果就不會很理想。咱們繪製出了災難類和不相關類中最重要的一些詞。用詞袋模型和邏輯迴歸來繪製單詞重要性很是簡單,咱們只須要將模型預測時使用的係數進行提取和排序。
詞袋模型:單詞重要性
咱們的分類器正確地找出了一些特徵(hiroshima, massacre),但很顯然在一些無心義的詞上出現了過擬合(heyoo, x1392)。如今,咱們的詞袋模型處理着大量的詞彙,且每一個單詞都是被平等對待的。可是,有些詞出現的頻率很是高,卻只會對預測提供噪聲。接下來,咱們會嘗試一種能解釋詞頻的方法來表達句子,來看是否能從數據中獲取更多信息。
爲了使咱們的模型能更多地關注有意義的單詞,咱們能夠在詞袋模型上進行 TF-IDF(Term Frequency, Inverse Document Frequency)評分。TF-IDF 根據單詞在數據集中的稀有程度打分,會對一些出現太過頻繁且只會增長噪聲的詞進行削減。下圖是咱們新嵌入的 PCA 投影圖:
TF-IDF 嵌入的可視化
上圖中咱們能夠看到,兩種顏色有了更清晰的區分。這能使咱們的分類器能更容易地區分兩個組。讓咱們看看這樣是否會造成更好的結果。用咱們新的嵌入訓練的另外一個邏輯迴歸模型獲得了 76.2% 的精確度。
這是一個很是微小的提高。咱們的模型開始注意到更重要的單詞了嗎?若是咱們在保證模型沒有「欺騙」行爲的狀況下獲得了更好的結果,那麼能夠認爲這個模型有了提高。
TF-IDF: 單詞重要性
被選出的單詞看起來更相關了!雖然咱們測試集的矩陣只有略微的增加,可是咱們對模型選用的詞彙有了更多的信心,所以能更放心地將它部署到一些須要和客戶交互的系統中。
咱們最新的模型設法注意到了高層的信號詞。可是若是咱們部署了這個模型,頗有可能會遇到在訓練集中沒有出現過的單詞。那麼以前的模型可能就沒法準確地爲這些推文分類,即便在訓練時已經遇到過相似的詞語。
爲了解決這個問題,咱們須要獲取到詞語的語義,也就是說咱們須要理解「good」和「positive」比「apricot」和「continent」更接近。咱們會使用一個叫作 Word2Vec 的工具來幫助咱們獲取含義。
Word2Vec 是一種用來爲單詞尋找連續嵌入的技術。它經過讀取大量文本並記憶出如今類似上下文中的單詞來進行學習。在通過足夠的數據訓練後,它會爲詞表中的每一個單詞生成一個 300 維的向量,具備類似含義的單詞會靠的更近。
這篇文章的做者開源了一個在很大的語料庫上預先訓練過的模型,咱們能夠利用它來爲咱們的模型引入一些語義的知識。預先訓練的向量能夠在這篇文章的資源庫中找到。
一種讓句子快速嵌入咱們分類器的方法是對句子中全部單詞取 Word2Vec 分數的平均值。用的是和以前同樣的詞袋方法,可是此次咱們在保留一些語義信息的時候,僅丟失了句子的語法。
Word2Vec 句子嵌入
下面是使用以前所說的技術造成的新嵌入的可視化:
Word2Vec 嵌入可視化
兩組顏色區分的更明顯了,此次新的嵌入會幫助咱們的分類器找到兩類之間的分隔。在對同一個模型訓練了三次以後(邏輯迴歸),咱們獲得了 77.7% 的準確率,這是至今最棒的結果了!是時候檢驗模型了。
鑑於在以前的模型中,咱們的嵌入不是表達成每一個單詞對應一個一維向量,這就更難判斷出哪些單詞和咱們的分類是最相關的。可是咱們仍然可使用邏輯迴歸的係數,由於它和咱們嵌入的 300 個維度相關而不和單詞的索引相關。
對於準確性上如此微弱的提高,丟失全部可解釋性彷佛是一種很苛刻的權衡。可是在使用更復雜的模型時,咱們能夠利用 LIME這類黑盒解釋器 來查看咱們的分類器是怎麼工做的。
LIME 能夠在 Github 的開源包裏獲取到。黑盒解釋器容許用戶利用一個典型的案例來解釋任何一個分類器的決定,能夠經過擾動輸入(在咱們的案例中,是從句子中移除單詞)來觀察預測的變化。
來看一下咱們數據集中句子的一組解釋。
正確的災難詞彙被分類爲「相關的」
這裏,單詞對分類的影響彷佛不明顯
但咱們沒有時間去探索數據集中成千上萬的案例。取而代之的是咱們會用 LIME 跑在具備表明性的測試樣本上來看哪些單詞會一直有很強的貢獻。使用這種方法,咱們就能像以前的模型同樣獲得單詞重要性得分,並驗證模型的預測。
Word2Vec: 單詞重要性
彷佛能找出高度相關詞語的模型就意味着可以作出可理解的決策。這些應該是使用以前模型產出的最相關的單詞,所以咱們能更安心地應用到生產中了。
以前文章的內容涵蓋了用於生成緊湊句子嵌入的快速有效的方法。可是,因爲忽略了單詞的順序,咱們失去了句子中全部語法信息。若是這些方法沒法提供足夠有效的結果,你能夠用一些更復雜的模型,它們會把整句句子做爲輸入,並在不須要構建中間表達的狀況下預測標籤。一般的作法是用 Word2Vec 或是一些更新的方法,好比 GloVe 或 CoVe,把句子當作一系列獨立的單詞向量。咱們下面便會這麼作。
一個高效的端到端架構(源)
用於句子分類的卷積神經網絡(Convolutional Neural Networks,CNN)訓練起來很是快,是很是好用的入門級深度學習架構。CNN 廣爲人知的是它在圖像數據上的表現,可是它在處理文本相關的任務時也能提供極好的效果,並且一般會比大多數複雜的 NLP 算法訓練的更快(例如 LSTMs 和 Encoder/Decoder 架構)。這個模型保留了單詞的順序,而且從咱們可預測單詞順序的目標類中學習有價值的信息。與以前的模型相反,他能夠區分出「Alex eats plants」和「Plants eat Alex」。
訓練這個模型並不會比以前的方法花費更多功夫(更詳細的內容能夠參考代碼),但效果會比以前的都好,精確度能達到 79.5%!用着上述的模型,咱們下一步的操做將是探索和解釋用咱們描述的方法作出的預測,來證明這的確是可以交付給用戶的最好的模型。如今,你能夠放心地嘗試親自操做了。
讓咱們把以前提到過的成功方法快速的過一下:
從一個快速簡單的模型開始
解釋它的預測
理解它產生的錯誤
用這些信息來判斷你的下一步操做,是否對你的數據起做用,或是須要一個更復雜的模型
這些方法應用到了特殊的案例上,用的是理解和處理像推文同樣小段文字的模型,可是這種思考模式能夠普遍地應用到其餘問題上。但願這篇文章能夠對你有所幫助,也但願能夠從你那裏聽到一些建議或是諮詢!請在下方盡情地留言,也能夠在這裏或是 Twitter 上聯繫 EmmanuelAmeisen。
更多幹貨內容,可關注AI前線,ID:ai-front,後臺回覆「AI」、「TF」、「大數據」可得到《AI前線》系列PDF迷你書和技能圖譜。