手把手教你搞定90%的NLP問題
導(dǎo)讀:作者 Emmanuel Ameisen 將在這篇文章中一步步地指導(dǎo)你如何使用機(jī)器學(xué)習(xí)的方法來解決大部分的 NLP 問題,文中會(huì)列舉一個(gè)典型的分類案例——Twitter 的內(nèi)容是否和災(zāi)難事件相關(guān),來詳細(xì)說明我們應(yīng)該按怎樣的步驟來處理文本數(shù)據(jù)。
文本數(shù)據(jù)無處不在
不論是已經(jīng)成熟的企業(yè)或是正要上線新業(yè)務(wù),你都可以利用文本數(shù)據(jù)來驗(yàn)證、提升以及擴(kuò)展產(chǎn)品的功能。這種從文本數(shù)據(jù)中提取含義并進(jìn)行學(xué)習(xí)的科學(xué)叫做自然語言處理(Natural Language Processing, NLP),是當(dāng)前非常熱門的研究課題。
NLP 是一個(gè)非常大的研究領(lǐng)域且每天都在產(chǎn)生一些新的激動(dòng)人心的成果。經(jīng)過和上百家企業(yè)的合作,我們 Insight 團(tuán)隊(duì)從中發(fā)現(xiàn)了幾個(gè)關(guān)鍵的實(shí)際應(yīng)用,這些應(yīng)用會(huì)有更高的出現(xiàn)頻率:
- 識(shí)別使用者 / 客戶不同的用戶群(例如預(yù)測(cè)用戶流失、生命周期價(jià)值、產(chǎn)品偏好等)
- 精準(zhǔn)檢測(cè)和提取反饋分類(例如正面和負(fù)面的評(píng)論 / 觀點(diǎn),對(duì)諸如衣服尺寸、舒適度等一些特別屬性的提及)
- 根據(jù)意圖進(jìn)行文本分類(例如請(qǐng)求普通幫助,緊急問題處理)
鑒于 NLP 的文章和指南很多都存在于網(wǎng)絡(luò)上,我們發(fā)現(xiàn)很難找到對(duì)處理這些問題徹底有效的指導(dǎo)或建議。
這篇文章能幫到你什么
我們?cè)谶@一年里做了數(shù)百個(gè)項(xiàng)目,并吸取了全美***團(tuán)隊(duì)的建議,整理出這篇文章來說明如何使用機(jī)器學(xué)習(xí)解決上述問題。我們將從最簡(jiǎn)單可行的方法說起,然后進(jìn)階到更細(xì)致的解決方案,例如特征工程、詞向量以及深度學(xué)習(xí)等。
讀完這篇文章,你將會(huì)知道如何去:
- 收集、準(zhǔn)備和檢測(cè)數(shù)據(jù)
- 從建立簡(jiǎn)單模型開始,必要時(shí)使用深度學(xué)習(xí)來過渡
- 解釋和理解模型,來確保你實(shí)際捕獲的是有效信息而不是噪聲
這篇文章是一份循序漸進(jìn)的操作指南,也是一份對(duì)高效標(biāo)準(zhǔn)化過程的高度概括。
文章還附帶了一份互動(dòng)筆記,里面對(duì)所有涉及到的技術(shù)都進(jìn)行了論證和應(yīng)用。你可以嘗試邊運(yùn)行代碼邊看下文。
步驟一:收集數(shù)據(jù)
樣例數(shù)據(jù)源
每一個(gè)機(jī)器學(xué)習(xí)問題都始于數(shù)據(jù),比如一組郵件、帖子或是推文。文本信息的常見來源包括:
商品評(píng)價(jià)(來自 Amazon、Yelp 以及其他 App 商城)
用戶產(chǎn)出的內(nèi)容(推文、Facebook 的帖子、StackOverflow 的提問等)
問題解決(客戶請(qǐng)求、技術(shù)支持、聊天記錄)
“社交媒體中的災(zāi)難”數(shù)據(jù)集
在這篇文章中,我們將使用 CrowdFlower 提供的一個(gè)數(shù)據(jù)集,名為“社交媒體中的災(zāi)難(Disasters on Social Media)”。
貢獻(xiàn)者們查看了超過 10000 條具有類似“著火”、“隔離”、“混亂”等搜索關(guān)鍵詞的推文,然后標(biāo)記這個(gè)推文是否和災(zāi)難事件有關(guān)(與之相反的是一些玩笑、電影點(diǎn)評(píng)或是一些非災(zāi)難性的事件)。
我們的任務(wù)是分辨出哪些推文是真正和災(zāi)難事件相關(guān)的,而不是一些類似電影描述的不相關(guān)話題。為什么呢?一個(gè)潛在的應(yīng)用是針對(duì)突發(fā)事件對(duì)執(zhí)法人員進(jìn)行專門的提醒,而不會(huì)被其他無關(guān)信息,比如 Adam Sandler 新上映的電影所干擾。這項(xiàng)任務(wù)中一個(gè)特別的挑戰(zhàn)是這兩種情況在搜索推文的時(shí)候都用到了相同的檢索詞,所以我們只能通過細(xì)微的差別去區(qū)分他們。
在下面的文章中,我們將把與災(zāi)難事件相關(guān)的推文稱為“災(zāi)難”,將其他推文稱為“不相關(guān)的”。
標(biāo)簽
我們已經(jīng)標(biāo)注過數(shù)據(jù),所以知道推文是如何分類的。如 Richard Socher 所說,比起優(yōu)化一個(gè)復(fù)雜的無監(jiān)督學(xué)習(xí)方法,尋找和標(biāo)記足夠多的數(shù)據(jù)來訓(xùn)練模型會(huì)更加快捷、簡(jiǎn)單和廉價(jià)。
Richard Socher 的高級(jí)技巧
步驟二:清洗數(shù)據(jù)
我們要遵循的首要原則是:“你的模型必須和你的數(shù)據(jù)一樣好。”
數(shù)據(jù)科學(xué)家的一個(gè)必備技能是知道自己的下一步操作是處理模型還是數(shù)據(jù)。有一個(gè)好的經(jīng)驗(yàn)法則是先觀察數(shù)據(jù)然后進(jìn)行數(shù)據(jù)清洗。一個(gè)干凈的數(shù)據(jù)集能使模型學(xué)習(xí)到有意義的特征而不會(huì)被一些不相關(guān)的噪聲影響。
可以借鑒下方的列表來進(jìn)行數(shù)據(jù)清洗:(查看代碼獲取更多信息)
- 去除一切不相關(guān)的字符,比如任何非字母數(shù)字的字符
- 標(biāo)記你的文本,將他們拆分為獨(dú)立的單詞
- 去除不相關(guān)的詞語,比如 @這類提醒或是 url 鏈接
- 將所有字母轉(zhuǎn)換成小寫,這樣“hello”,“Hello”,“HELLO”就會(huì)被當(dāng)做同樣的單詞處理
- 將拼錯(cuò)的單詞或是多種拼法的單詞與某個(gè)特定的表達(dá)綁定(比如:“cool”/“kewl”/“cooool”)
- 考慮詞形還原(比如將“am”,“are”,“is”都看做“be”)
完成這些步驟并檢查完其他錯(cuò)誤后,我們就可以使用這些干凈的、標(biāo)記過的數(shù)據(jù)進(jìn)行模型訓(xùn)練了!
步驟三:找到好的數(shù)據(jù)表達(dá)方式
機(jī)器學(xué)習(xí)模型會(huì)使用數(shù)值作為輸入。例如處理圖像的模型會(huì)用矩陣來表示每個(gè)顏色通道像素的亮度。
用數(shù)字矩陣表現(xiàn)的笑臉
我們的數(shù)據(jù)集是一系列的句子,為了使我們的算法能從數(shù)據(jù)中提取特征,首先需要找到一種算法能夠理解的表達(dá)方式,比如一串?dāng)?shù)字。
獨(dú)熱編碼(One-hot encoding)- 詞袋模型(Bag of Words)
通常為計(jì)算機(jī)解釋文本的方法是將每一個(gè)字符都編為一個(gè)獨(dú)立的數(shù)字(例如 ASCII 碼)。如果使用這種簡(jiǎn)單的表達(dá)來做分類器,需要我們的數(shù)據(jù)從頭開始學(xué)習(xí)詞語的結(jié)構(gòu),這對(duì)大多數(shù)數(shù)據(jù)集來說是很難實(shí)現(xiàn)的。所以我們需要一種更上層的方法。
例如,我們可以為數(shù)據(jù)集中的所有單詞制作一張?jiān)~表,然后將每個(gè)單詞和一個(gè)唯一的索引關(guān)聯(lián)。每個(gè)句子都是由一串?dāng)?shù)字組成,這串?dāng)?shù)字是詞表中的獨(dú)立單詞對(duì)應(yīng)的個(gè)數(shù)。通過列表中的索引,我們可以統(tǒng)計(jì)出句子中某個(gè)單詞出現(xiàn)的次數(shù)。這種方法叫做 詞袋模型,它完全忽略了句子中單詞的順序。如下圖所示:
用詞袋模型表示句子。句子在左邊,模型表達(dá)在右邊。向量中的每一個(gè)索引代表了一個(gè)特定的單詞。
嵌入可視化
在“社交媒體中的災(zāi)難”樣本詞表中大概會(huì)有 20000 個(gè)單詞,這意味著每句句子都會(huì)用一個(gè)長度為 20000 的向量來表示。向量的 大部分會(huì)被 0 填充,因?yàn)槊烤湓捴话嗽~表中很小的一個(gè)子集。
為了看出嵌入的工作是否真正抓住了和問題相關(guān)的信息(比如推文是否與災(zāi)難相關(guān)),有一個(gè)好方法是將它們可視化,然后觀察結(jié)果是否有很好的分布。考慮到詞表通常很大,而且用 20000 維的數(shù)據(jù)做可視化是基本不可能的,所以我們使用了 PCA 這種技術(shù)將數(shù)據(jù)降到二維。繪制如下:
詞袋模型嵌入的可視化
兩個(gè)分類看起來沒有很好的分離,這可能是我們選擇的嵌入方法的特征或是單純因?yàn)榫S度的減少引起的。為了了解詞袋模型的特征是否會(huì)起一些作用,我們可以試著基于它訓(xùn)練一個(gè)分類器。
步驟四:分類
當(dāng)初次接觸一個(gè)問題,通常來說***的方法是先挑選一個(gè)能解決問題的最簡(jiǎn)單的工具。當(dāng)提到數(shù)據(jù)分類時(shí),一般***的是通用性和可解釋性兼具的邏輯回歸算法。這種算法很容易訓(xùn)練而且結(jié)果也是可解釋的,你可以很輕松地從模型中提取出最重要的一些系數(shù)。
我們將數(shù)據(jù)分為兩個(gè)集合,訓(xùn)練集用于匹配模型,測(cè)試集用于觀察應(yīng)用在未知數(shù)據(jù)上的效果。訓(xùn)練后我們得到了 75.4% 的精確度。結(jié)果還不錯(cuò)!推測(cè)出現(xiàn)最多的類(“不相關(guān)”)只能達(dá)到 57%。但是,即使是 75% 的精確度也已經(jīng)足夠好了,我們決不能在還沒有理解模型的情況下就開始應(yīng)用它。
步驟五:檢驗(yàn)
混淆矩陣
***步是理解我們的模型會(huì)產(chǎn)生哪些錯(cuò)誤類型,哪些錯(cuò)誤是我們最不希望出現(xiàn)的。在例子中,誤報(bào)(false positive)是指將不相關(guān)的推文歸為災(zāi)難,漏報(bào)(false negative)是指將真實(shí)災(zāi)難歸為不相關(guān)的。如果需要優(yōu)先響應(yīng)所有潛在事件,我們需要降低漏報(bào)率。如果是資源有限,我們就需要優(yōu)先降低誤報(bào)率來減少錯(cuò)誤告警。我們可以使用混淆矩陣來可視化這些信息,它能將模型的預(yù)測(cè)與真實(shí)的標(biāo)簽進(jìn)行比較。理想狀態(tài)下,矩陣將形成一條貫穿左上角至右下角的對(duì)角線(此時(shí)預(yù)測(cè)值和真實(shí)值***匹配)。
混淆矩陣(綠色是高比例,藍(lán)色是低比例)
我們的分類器生成的漏報(bào)要比誤報(bào)多(按比例)。換句話說,我們模型最常見的錯(cuò)誤是將災(zāi)難事件錯(cuò)誤地劃分到了不相關(guān)的分類。如果誤報(bào)會(huì)造成法律實(shí)施上的高昂成本,這對(duì)我們的分類器來說可能是個(gè)好事。
解釋和說明模型
為了驗(yàn)證我們的模型并解釋它的預(yù)測(cè),就需要觀察它是用哪些詞來做決策的。如果我們的數(shù)據(jù)本身有偏差,分類器能基于樣例數(shù)據(jù)做出準(zhǔn)確的預(yù)測(cè),但是將模型應(yīng)用在真實(shí)世界中的結(jié)果就不會(huì)很理想。我們繪制出了災(zāi)難類和不相關(guān)類中最重要的一些詞。用詞袋模型和邏輯回歸來繪制單詞重要性非常簡(jiǎn)單,我們只需要將模型預(yù)測(cè)時(shí)使用的系數(shù)進(jìn)行提取和排序。
詞袋模型:?jiǎn)卧~重要性
我們的分類器正確地找出了一些特征(hiroshima, massacre),但很顯然在一些無意義的詞上出現(xiàn)了過擬合(heyoo, x1392)?,F(xiàn)在,我們的詞袋模型處理著大量的詞匯,且每個(gè)單詞都是被平等對(duì)待的。但是,有些詞出現(xiàn)的頻率非常高,卻只會(huì)對(duì)預(yù)測(cè)提供噪聲。接下來,我們會(huì)嘗試一種能解釋詞頻的方法來表達(dá)句子,來看是否能從數(shù)據(jù)中獲取更多信息。
步驟六:解釋詞語結(jié)構(gòu)
TF-IDF
為了使我們的模型能更多地關(guān)注有意義的單詞,我們可以在詞袋模型上進(jìn)行 TF-IDF(Term Frequency, Inverse Document Frequency)評(píng)分。TF-IDF 根據(jù)單詞在數(shù)據(jù)集中的稀有程度打分,會(huì)對(duì)一些出現(xiàn)太過頻繁且只會(huì)增加噪聲的詞進(jìn)行削減。下圖是我們新嵌入的 PCA 投影圖:
TF-IDF 嵌入的可視化
上圖中我們可以看到,兩種顏色有了更清晰的區(qū)分。這能使我們的分類器能更容易地區(qū)分兩個(gè)組。讓我們看看這樣是否會(huì)形成更好的結(jié)果。用我們新的嵌入訓(xùn)練的另一個(gè)邏輯回歸模型得到了 76.2% 的精確度。
這是一個(gè)非常微小的提升。我們的模型開始注意到更重要的單詞了嗎?如果我們?cè)诒WC模型沒有“欺騙”行為的情況下得到了更好的結(jié)果,那么可以認(rèn)為這個(gè)模型有了提升。
TF-IDF: 單詞重要性
被選出的單詞看起來更相關(guān)了!雖然我們測(cè)試集的矩陣只有略微的增長,但是我們對(duì)模型選用的詞匯有了更多的信心,因此能更放心地將它部署到一些需要和客戶交互的系統(tǒng)中。
步驟七:利用語義
Word2Vec
我們***的模型設(shè)法注意到了高層的信號(hào)詞。但是如果我們部署了這個(gè)模型,很有可能會(huì)遇到在訓(xùn)練集中沒有出現(xiàn)過的單詞。那么之前的模型可能就無法準(zhǔn)確地為這些推文分類,即使在訓(xùn)練時(shí)已經(jīng)遇到過類似的詞語。
為了解決這個(gè)問題,我們需要獲取到詞語的語義,也就是說我們需要理解“good”和“positive”比“apricot”和“continent”更接近。我們會(huì)使用一個(gè)叫做 Word2Vec 的工具來幫助我們獲取含義。
使用預(yù)先訓(xùn)練過的單詞
Word2Vec 是一種用來為單詞尋找連續(xù)嵌入的技術(shù)。它通過讀取大量文本并記憶出現(xiàn)在相似上下文中的單詞來進(jìn)行學(xué)習(xí)。在經(jīng)過足夠的數(shù)據(jù)訓(xùn)練后,它會(huì)為詞表中的每個(gè)單詞生成一個(gè) 300 維的向量,具有相似含義的單詞會(huì)靠的更近。
這篇文章的作者開源了一個(gè)在很大的語料庫上預(yù)先訓(xùn)練過的模型,我們可以利用它來為我們的模型引入一些語義的知識(shí)。預(yù)先訓(xùn)練的向量可以在這篇文章的資源庫中找到。
句子級(jí)別的表達(dá)
一種讓句子快速嵌入我們分類器的方法是對(duì)句子中所有單詞取 Word2Vec 分?jǐn)?shù)的平均值。用的是和之前一樣的詞袋方法,但是這次我們?cè)诒A粢恍┱Z義信息的時(shí)候,僅丟失了句子的語法。
Word2Vec 句子嵌入
下面是使用之前所說的技術(shù)形成的新嵌入的可視化:
Word2Vec 嵌入可視化
兩組顏色區(qū)分的更明顯了,這次新的嵌入會(huì)幫助我們的分類器找到兩類之間的分隔。在對(duì)同一個(gè)模型訓(xùn)練了三次之后(邏輯回歸),我們得到了 77.7% 的準(zhǔn)確率,這是至今最棒的結(jié)果了!是時(shí)候檢驗(yàn)?zāi)P土恕?/p>
復(fù)雜性 / 可解釋性的權(quán)衡
鑒于在之前的模型中,我們的嵌入不是表達(dá)成每個(gè)單詞對(duì)應(yīng)一個(gè)一維向量,這就更難判斷出哪些單詞和我們的分類是最相關(guān)的。但是我們?nèi)匀豢梢允褂眠壿嫽貧w的系數(shù),因?yàn)樗臀覀兦度氲?300 個(gè)維度相關(guān)而不和單詞的索引相關(guān)。
對(duì)于準(zhǔn)確性上如此微弱的提升,丟失所有可解釋性似乎是一種很苛刻的權(quán)衡。但是在使用更復(fù)雜的模型時(shí),我們可以利用 LIME這類黑盒解釋器 來查看我們的分類器是怎么工作的。
LIME
LIME 可以在 Github 的開源包里獲取到。黑盒解釋器允許用戶利用一個(gè)典型的案例來解釋任何一個(gè)分類器的決定,可以通過擾動(dòng)輸入(在我們的案例中,是從句子中移除單詞)來觀察預(yù)測(cè)的變化。
來看一下我們數(shù)據(jù)集中句子的一組解釋。
正確的災(zāi)難詞匯被分類為“相關(guān)的”
這里,單詞對(duì)分類的影響似乎不明顯
但我們沒有時(shí)間去探索數(shù)據(jù)集中成千上萬的案例。取而代之的是我們會(huì)用 LIME 跑在具有代表性的測(cè)試樣本上來看哪些單詞會(huì)一直有很強(qiáng)的貢獻(xiàn)。使用這種方法,我們就能像之前的模型一樣得到單詞重要性得分,并驗(yàn)證模型的預(yù)測(cè)。
Word2Vec: 單詞重要性
似乎能找出高度相關(guān)詞語的模型就意味著能夠做出可理解的決策。這些應(yīng)該是使用之前模型產(chǎn)出的最相關(guān)的單詞,因此我們能更安心地應(yīng)用到生產(chǎn)中了。
步驟八:用端到端方法處理語法
之前文章的內(nèi)容涵蓋了用于生成緊湊句子嵌入的快速有效的方法。但是,由于忽略了單詞的順序,我們失去了句子中所有語法信息。如果這些方法無法提供足夠有效的結(jié)果,你可以用一些更復(fù)雜的模型,它們會(huì)把整句句子作為輸入,并在不需要構(gòu)建中間表達(dá)的情況下預(yù)測(cè)標(biāo)簽。通常的做法是用 Word2Vec 或是一些更新的方法,比如 GloVe 或 CoVe,把句子當(dāng)做一系列獨(dú)立的單詞向量。我們下面便會(huì)這么做。
一個(gè)高效的端到端架構(gòu)(源)
用于句子分類的卷積神經(jīng)網(wǎng)絡(luò)(Convolutional Neural Networks,CNN)訓(xùn)練起來非???,是非常好用的入門級(jí)深度學(xué)習(xí)架構(gòu)。CNN 廣為人知的是它在圖像數(shù)據(jù)上的表現(xiàn),但是它在處理文本相關(guān)的任務(wù)時(shí)也能提供極好的效果,而且通常會(huì)比大多數(shù)復(fù)雜的 NLP 算法訓(xùn)練的更快(例如 LSTMs 和 Encoder/Decoder 架構(gòu))。這個(gè)模型保留了單詞的順序,并且從我們可預(yù)測(cè)單詞順序的目標(biāo)類中學(xué)習(xí)有價(jià)值的信息。與之前的模型相反,他可以區(qū)分出“Alex eats plants”和“Plants eat Alex”。
訓(xùn)練這個(gè)模型并不會(huì)比之前的方法花費(fèi)更多功夫(更詳細(xì)的內(nèi)容可以參考代碼),但效果會(huì)比之前的都好,精確度能達(dá)到 79.5%!用著上述的模型,我們下一步的操作將是探索和解釋用我們描述的方法做出的預(yù)測(cè),來證實(shí)這的確是能夠交付給用戶的***的模型。現(xiàn)在,你可以放心地嘗試親自操作了。
***
讓我們把之前提到過的成功方法快速的過一下:
- 從一個(gè)快速簡(jiǎn)單的模型開始
- 解釋它的預(yù)測(cè)
- 理解它產(chǎn)生的錯(cuò)誤
- 用這些信息來判斷你的下一步操作,是否對(duì)你的數(shù)據(jù)起作用,或是需要一個(gè)更復(fù)雜的模型
這些方法應(yīng)用到了特殊的案例上,用的是理解和處理像推文一樣小段文字的模型,但是這種思考模式可以廣泛地應(yīng)用到其他問題上。希望這篇文章可以對(duì)你有所幫助,也希望可以從你那里聽到一些建議或是咨詢!請(qǐng)?jiān)谙路奖M情地留言,也可以在這里或是 Twitter 上聯(lián)系 EmmanuelAmeisen。