NLP極簡入門指南,助你通過面試,踏入NLP的大門

弱人工智能的時代已經到來,人們每天的生活都離不開算法所提供的服務。比如:資訊類APP是根據用戶偏好做的個性化推薦;出行類APP背後是算法在做最優化調度;購物類APP是根據歷史購買行為和商品間相似度進行推薦。這樣的例子還有很多很多,就不一一列舉了。

可見算法對於一家互聯網公司有多麼的重要,而市場上優秀的算法工程師卻非常稀少,因此各大互聯網公司不惜開出高薪來吸引人才,同時算法工程師的職業生命週期還很長,對絕大多數的開發者來說是一個非常理想的職業。

NLP的全稱是Natuarl Language Processing,中文意思是自然語言處理,是人工智能領域的一個重要方向。隨著機器學習不斷的發展,在圖像識別、語音識別等方向都取得了巨大的進步。相比較而言NLP卻落後了一些,這與NLP所要解決問題的複雜度有關。

自然語言處理

人類語言是抽象的信息符號,其中蘊含著豐富的語義信息,人類可以很輕鬆地理解其中的含義。而計算機只能處理數值化的信息,無法直接理解人類語言,所以需要將人類語言進行數值化轉換。不僅如此,人類間的溝通交流是有上下文信息的,這對於計算機也是巨大的挑戰。

NLP就是解決上述問題的技術集合,不是某個單一的技術點,而是一整套技術體系,其複雜度可見一斑。因此,NLP算法工程師的薪資待遇要遠高於行業的平均水平。

本文希望通過言簡意賅的方式,幫助大家建立一個關於NLP的整體知識體系,方便大家快速入門NLP,爭取早日成為大牛,走上人生巔峰,:-P

我們首先來看看NLP的任務類型,如下圖所示:

NLP任務分類

主要劃分為了四大類:

類別到序列序列到類別同步的序列到序列異步的序列到序列

其中“類別”可以理解為是標籤或者分類,而“序列”可以理解為是一段文本或者一個數組。簡單概況NLP的任務就是從一種數據類型轉換成另一種數據類型的過程,這與絕大多數的機器學習模型相同或者類似,所以掌握了NLP的技術棧就等於掌握了機器學習的技術棧。

NLP的預處理

為了能夠完成上述的NLP任務,我們需要一些預處理,是NLP任務的基本流程。預處理包括:收集語料庫、文本清洗、分詞、去掉停用詞(可選)、標準化和特徵提取等。

NLP預處理

圖中紅色的部分就是NLP任務的預處理流程,有別於其它機器學習任務的流程,下面我就來分佈介紹一下:

語料庫

對於NLP任務來說,沒有大量高質量的語料,就是巧婦難為無米之炊,是無法工作的。

而獲取語料的途徑有很多種,最常見的方式就是直接下載開源的語料庫,如:維基百科的語料庫。

但這樣開源的語料庫一般都無法滿足業務的個性化需要,所以就需要自己動手開發爬蟲去抓取特定的內容,這也是一種獲取語料庫的途徑。

當然,每家互聯網公司根據自身的業務,也都會有大量的語料數據,如:用戶評論、電子書、商品描述等等,都是很好的語料庫。

現在,數據對於互聯網公司來說就是石油,其中蘊含著巨大的商業價值。所以,小夥伴們在日常工作中一定要養成收集數據的習慣,遇到好的語料庫一定要記得備份(當然是在合理合法的條件下),它將會對你解決問題提供巨大的幫助。

文本清洗

我們通過不同的途徑獲取到了想要的語料庫之後,接下來就需要對其進行清洗。因為很多的語料數據是無法直接使用的,其中包含了大量的無用符號、特殊的文本結構。

數據類型分為:

結構化數據:關係型數據、json等 半結構化數據:XML、HTML等 非結構化數據:Word、PDF、文本、日誌等

需要將原始的語料數據轉化成易於處理的格式,一般在處理HTML、XML時,會使用Python的lxml庫,功能非常豐富且易於使用。對一些日誌或者純文本的數據,我們可以使用正則表達式進行處理。

正則表達式是使用單個字符串來描述、匹配一系列符合某個句法規則的字符串。Python的示例代碼如下:

import re # 定義中文字符的正則表達式 re_han_default = re.compile("([\u4E00-\u9FD5]+)", re.U) sentence = "我/愛/自/然/語/言/處/理" # 根據正則表達式進行切分 blocks= re_han_default.split(sentence) for blk in blocks: # 校驗單個字符是否符合正則表達式 if blk and re_han_default.match(blk): print(blk)

輸出:

我 愛 自 然 語 言 處 理

除了上述的內容之外,我們還需要注意中文的編碼問題,在windows平臺下中文的默認編碼是GBK(gb2312),而在linux平臺下中文的默認編碼是UTF-8。在執行NLP任務之前,我們需要統一不同來源語料的編碼,避免各種莫名其妙的問題。

如果大家事前無法判斷語料的編碼,那麼我推薦大家可以使用Python的chardet庫來檢測編碼,簡單易用。既支持命令行:chardetect somefile,也支持代碼開發。

分詞

中文分詞和英文分詞有很大的不同,英文是使用空格作為分隔符,所以英文分詞基本沒有什麼難度。而中文是字與字直接連接,中間沒有任何的分隔符,但中文是以“詞”作為基本的語義單位,很多NLP任務的輸入和輸出都是“詞”,所以中文分詞的難度要遠大於英文分詞。

中文分詞是一個比較大的課題,相關的知識點和技術棧非常豐富,可以說搞懂了中文分詞就等於搞懂了大半個NLP。中文分詞經歷了20多年的發展,克服了重重困難,取得了巨大的進步,大體可以劃分成兩個階段,如下圖所示:

中文分詞

目前,主流的中文分詞技術採用的都是基於詞典最大概率路徑+未登錄詞識別(HMM)的方案,其中典型的代表就是jieba分詞,一個熱門的多語言中文分詞包。

如果對中文分詞感興趣的朋友,想進一步詳細瞭解,我推薦你看一看我寫的一本掘金小冊《深入理解NLP的中文分詞:從原理到實踐》(點擊

瞭解更多鏈接),裡面詳細地講解了中文分詞的各種實現方法,並深度分析了jiebe的Python源碼,讓你可以從零開始徹底掌握中文分詞的技術,同時也講解了多種NLP的實際案例,相信你一定會收穫很多。

標準化

標準化是為了給後續的處理提供一些必要的基礎數據,包括:去掉停用詞、詞彙表、訓練數據等等。

當我們完成了分詞之後,可以去掉停用詞,如:“其中”、“況且”、“什麼”等等,但這一步不是必須的,要根據實際業務進行選擇,像關鍵詞挖掘就需要去掉停用詞,而像訓練詞向量就不需要。

詞彙表是為語料庫建立一個所有不重複詞的列表,每個詞對應一個索引值,並索引值不可以改變。詞彙表的最大作用就是可以將詞轉化成一個向量,即One-Hot編碼。

假設我們有這樣一個詞彙表:

我 愛 自然 語言 處理

那麼,我們就可以得到如下的One-Hot編碼:

我: [1, 0, 0, 0, 0] 愛: [0, 1, 0, 0, 0] 自然:[0, 0, 1, 0, 0] 語言:[0, 0, 0, 1, 0] 處理:[0, 0, 0, 0, 1]

這樣我們就可以簡單的將詞轉化成了計算機可以直接處理的數值化數據了。雖然One-Hot編碼可以較好的完成部分NLP任務,但它的問題還是不少的。

當詞彙表的維度特別大的時候,就會導致經過One-Hot編碼後的詞向量非常稀疏,同時One-Hot編碼也缺少詞的語義信息。由於這些問題,才有了後面大名鼎鼎的Word2vec,以及Word2vec的升級版BERT

除了詞彙表之外,我們在訓練模型時,還需要提供訓練數據。模型的學習可以大體分為兩類:

監督學習,在已知答案的標註數據集上,模型給出的預測結果儘可能接近真實答案,適合預測任務非監督學習,學習沒有標註的數據,是要揭示關於數據隱藏結構的一些規律,適合描述任務

根據不同的學習任務,我們需要提供不同的標準化數據。一般情況下,標註數據的獲取成本非常昂貴,非監督學習雖然不需要花費這樣的成本,但在實際問題的解決上,主流的方式還選擇監督學習,因為效果更好。

帶標註的訓練數據大概如下所示(情感分析的訓練數據):

距離 川沙 公路 較近 公交 指示 蔡陸線 麻煩 建議 路線 房間 較為簡單 __label__1 商務 大床 房 房間 很大 床有 2M 寬 整體 感覺 經濟 實惠 不錯 ! __label__1 半夜 沒 暖氣 住 ! __label__0

其中每一行就是一條訓練樣本,__label__0和__label__1是分類信息,其餘的部分就是分詞後的文本數據。

特徵提取

為了能夠更好的訓練模型,我們需要將文本的原始特徵轉化成具體特徵,轉化的方式主要有兩種:統計Embedding

原始特徵:需要人類或者機器進行轉化,如:文本、圖像。具體特徵:已經被人類進行整理和分析,可以直接使用,如:物體的重要、大小。

統計的方式主要是計算詞的詞頻(TF)和逆向文件頻率(IDF):

詞頻,是指某一個給定的詞在該文件中出現的頻率,需要進行歸一化,避免偏向長文本逆向文件頻率,是一個詞普遍重要性的度量,由總文件數目除以包含該詞的文件數目

那麼,每個詞都會得到一個TF-IDF值,用來衡量它的重要程度,計算公式如下:

TFIDF計算公式

Embedding是將詞嵌入到一個由神經網絡的隱藏層權重構成的空間中,讓語義相近的詞在這個空間中距離也是相近的。Word2vec就是這個領域具有表達性的方法,大體的網絡結構如下:

Word2vec

輸入層是經過One-Hot編碼的詞,隱藏層是我們想要得到的Embedding維度,而輸出層是我們基於語料的預測結果。不斷迭代這個網絡,使得預測結果與真實結果越來越接近,直到收斂,我們就得到了詞的Embedding編碼,一個稠密的且包含語義信息的詞向量,可以作為後續模型的輸入。

綜上所述,我們就將NLP預處理的部分講解清楚了,已經涵蓋了大部分的NLP內容,接下來我們來聊聊NLP的一些具體業務場景。

NLP的業務場景

NLP的業務場景非常豐富,我簡單的梳理了一下:

文本糾錯:識別文本中的錯別字,給出提示以及正確的建議情感傾向分析:對包含主觀信息的文本進行情感傾向性判斷評論觀點抽取:分析評論關注點和觀點,輸出標籤對話情緒識別:識別會話者所表現出的情緒類別及置信度文本標籤:輸出能夠反映文章關鍵信息的多維度標籤文章分類:輸出文章的主題分類及對應的置信度新聞摘要:抽取關鍵信息並生成指定長度的新聞摘要

大家不要被這些眼花繚亂的業務場景給搞暈了,其實上面的這些業務都是基於我們之前講的NLP預處理的輸出,只是應用了不同的機器學習模型,比如:SVM、LSTM、LDA等等。

這些機器學習模型大部分是分類模型(序列標註也是一種分類模型),只有少部分是聚類模型。這些模型就是泛化的了,並不只是針對於NLP任務的。要想講清楚這部分內容,就需要另開一個關於“機器學習入門”的主題,這裡就不過多的展開了。

小結:只要大家掌握了NLP的預處理,就算入門NLP了,因為後續的處理都是一些常見的機器學習模型和方法。

結束語

NLP是一個非常有挑戰性的工作,同時也是一個非常有發展空間的工作,所以大家只要克服了前期的入門門檻,那麼迎接你的將是一片廣闊的天地。道阻且長,行則將至。

最後,還是要安利一下我寫的掘金小冊《深入理解NLP的中文分詞:從原理到實踐》,它將系統的幫助你學習NLP的中文分詞的相關知識,而中文分詞對於NLP的重要意義,通過本文大家也應該十分清楚了。掌握中文分詞的技術,不僅對於提高NLP任務的結果質量有很大的幫助,同時對於理解機器學習也有很大的促進作用。

如果你覺得以上內容對你有所幫助,希望素質三連:點贊、轉發、評論,也希望大家多多支持我的掘金小冊《深入理解NLP的中文分詞:從原理到實踐》(點擊瞭解更多鏈接),多謝多謝!