弱人工智能的時代已經到來,人們天天的生活都離不開算法所提供的服務。好比:資訊類APP是根據用戶偏好作的個性化推薦;出行類APP背後是算法在作最優化調度;購物類APP是根據歷史購買行爲和商品間類似度進行推薦。這樣的例子還有不少不少,就不一一列舉了。python
可見算法對於一家互聯網公司有多麼的重要,而市場上優秀的算法工程師卻很是稀少,所以各大互聯網公司不惜開出高薪來吸引人才,同時算法工程師的職業生命週期還很長,對絕大多數的開發者來講是一個很是理想的職業。linux
NLP的全稱是Natuarl Language Processing,中文意思是天然語言處理,是人工智能領域的一個重要方向。隨着機器學習不斷的發展,在圖像識別、語音識別等方向都取得了巨大的進步。相比較而言NLP卻落後了一些,這與NLP所要解決問題的複雜度有關。git
人類語言是抽象的信息符號,其中蘊含着豐富的語義信息,人類能夠很輕鬆地理解其中的含義。而計算機只能處理數值化的信息,沒法直接理解人類語言,因此須要將人類語言進行數值化轉換。不只如此,人類間的溝通交流是有上下文信息的,這對於計算機也是巨大的挑戰。github
NLP就是解決上述問題的技術集合,不是某個單一的技術點,而是一整套技術體系,其複雜度可見一斑。所以,NLP算法工程師的薪資待遇要遠高於行業的平均水平。正則表達式
本文但願經過言簡意賅的方式,幫助你們創建一個關於NLP的總體知識體系,方便你們快速入門NLP,爭取早日成爲大牛,走上人生巔峯,:-P。算法
咱們首先來看看NLP的任務類型,以下圖所示:json
主要劃分爲了四大類:windows
其中「類別」能夠理解爲是標籤或者分類,而「序列」能夠理解爲是一段文本或者一個數組。簡單概況NLP的任務就是從一種數據類型轉換成另外一種數據類型的過程,這與絕大多數的機器學習模型相同或者相似,因此掌握了NLP的技術棧就等於掌握了機器學習的技術棧。數組
爲了可以完成上述的NLP任務,咱們須要一些預處理,是NLP任務的基本流程。預處理包括:收集語料庫、文本清洗、分詞、去掉停用詞(可選)、標準化和特徵提取等。bash
圖中紅色的部分就是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值,用來衡量它的重要程度,計算公式以下:
其中的式子中是該詞在文件中的出現次數,而分母則是在文件中全部詞的出現次數之和。
而的式子中表示語料庫中的文件總數,表示包含詞 的文件數目,而是對結果作平滑處理。
Embedding是將詞嵌入到一個由神經網絡的隱藏層權重構成的空間中,讓語義相近的詞在這個空間中距離也是相近的。Word2vec就是這個領域具備表達性的方法,大致的網絡結構以下:
輸入層是通過One-Hot編碼的詞,隱藏層是咱們想要獲得的Embedding維度,而輸出層是咱們基於語料的預測結果。不斷迭代這個網絡,使得預測結果與真實結果愈來愈接近,直到收斂,咱們就獲得了詞的Embedding編碼,一個稠密的且包含語義信息的詞向量,能夠做爲後續模型的輸入。
綜上所述,咱們就將NLP預處理的部分講解清楚了,已經涵蓋了大部分的NLP內容,接下來咱們來聊聊NLP的一些具體業務場景。
NLP的業務場景很是豐富,我簡單的梳理了一下:
你們不要被這些眼花繚亂的業務場景給搞暈了,其實上面的這些業務都是基於咱們以前講的NLP預處理的輸出,只是應用了不一樣的機器學習模型,好比:SVM、LSTM、LDA等等。
這些機器學習模型大部分是分類模型(序列標註也是一種分類模型),只有少部分是聚類模型。這些模型就是泛化的了,並不僅是針對於NLP任務的。要想講清楚這部份內容,就須要另開一個關於「機器學習入門」的主題,這裏就不過多的展開了。
小結:只要你們掌握了NLP的預處理,就算入門NLP了,由於後續的處理都是一些常見的機器學習模型和方法。
NLP是一個很是有挑戰性的工做,同時也是一個很是有發展空間的工做,因此你們只要克服了前期的入門門檻,那麼迎接你的將是一片廣闊的天地。道阻且長,行則將至。
最後,仍是要安利一下我寫的掘金小冊《深刻理解NLP的中文分詞:從原理到實踐》,它將系統的幫助你學習NLP的中文分詞的相關知識,而中文分詞對於NLP的重要意義,經過本文你們也應該十分清楚了。掌握中文分詞的技術,不只對於提升NLP任務的結果質量有很大的幫助,同時對於理解機器學習也有很大的促進做用。
若是你以爲以上內容對你有所幫助,但願素質三連:點贊、轉發、評論,也但願你們多多支持個人掘金小冊,多謝多謝!