1. 程式人生 > >如何成為一名自然語言處理工程師

如何成為一名自然語言處理工程師

作者 | 蘭紅雲
責編 | 何永燦

自然語言處理和大部分的機器學習或者人工智慧領域的技術一樣,是一個涉及到多個技能、技術和領域的綜合體。

所以自然語言處理工程師會有各種各樣的背景,大部分都是在工作中自學或者是跟著專案一起學習的,這其中也不乏很多有科班背景的專業人才,因為技術的發展實在是日新月異,所以時刻要保持著一種強烈的學習慾望,讓自己跟上時代和技術發展的步伐。本文作者從個人學習經歷出發,介紹相關經驗。

一些研究者將自然語言處理(NLP,Natural Language Processing)和自然語言理解(NLU,Natural Language Understanding)區分開,在文章中我們說的NLP是包含兩者的,並沒有將兩者嚴格分開。

圖片描述
圖1 自然語言處理工程師技能樹

自然語言處理學習路線

數學基礎

數學對於自然語言處理的重要性不言而喻。當然數學的各個分支在自然語言處理的不同階段也會扮演不同的角色,這裡介紹幾個重要的分支。

  • 代數

代數作為計算數學裡面很重要的一個分支,在自然語言處理中也有舉足輕重的作用。這一部分需要重點關注矩陣處理相關的一些知識,比如矩陣的SVD、QR分解,矩陣逆的求解,正定矩陣、稀疏矩陣等特殊矩陣的一些處理方法和性質等等。

對於這一部分的學習,既可以跟著大學的代數書一起學習,也可以跟著網上的各種公開課一起學習,這裡既可以從國內的一些開放學習平臺上學,也可以從國外的一些開放學習平臺上學。這裡放一個學習的連結,網易公開課的連結:

https://c.open.163.com/search/search.htm?query=線性代數#/search/all。(其他的資料或者平臺也都OK)。

  • 概率論

在很多的自然語言處理場景中,我們都是算一個事件發生的概率。這其中既有特定場景的原因,比如要推斷一個拼音可能的漢字,因為同音字的存在,我們能計算的只能是這個拼音到各個相同發音的漢字的條件概率。也有對問題的抽象處理,比如詞性標註的問題,這個是因為我們沒有很好的工具或者說能力去精準地判斷各個詞的詞性,所以就構造了一個概率解決的辦法。

對於概率論的學習,既要學習經典的概率統計理論,也要學習貝葉斯概率統計。相對來說,貝葉斯概率統計可能更重要一些,這個和貝葉斯統計的特性是相關的,因其提供了一種描述先驗知識的方法。使得歷史的經驗使用成為了可能,而歷史在現實生活中,也確實是很有用的。比如樸素貝葉斯模型、隱馬爾卡模型、最大熵模型,這些我們在自然語言處理中耳熟能詳的一些演算法,都是貝葉斯模型的一種延伸和例項。

  • 資訊理論

資訊理論作為一種衡量樣本純淨度的有效方法。對於刻畫兩個元素之間的習慣搭配程度非常有效。這個對於我們預測一個語素可能的成分(詞性標註),成分的可能組成(短語搭配)非常有價值,所以這一部分知識在自然語言處理中也有非常重要的作用。

同時這部分知識也是很多機器學習演算法的核心,比如決策樹、隨機森林等以資訊熵作為決策樁的一些演算法。對於這部分知識的學習,更多的是要理解各個熵的計算方法和優缺點,比如資訊增益和資訊增益率的區別,以及各自在業務場景中的優缺點。照例放上一個連結:http://open.163.com/special/opencourse/information.html

資料結構與演算法

這部分內容的重要性就不做贅述了。學習了上面的基礎知識,只是萬里長征開始了第一步,要想用機器實現對自然語言的處理,還是需要實現對應的資料結構和演算法。這一部分也算是自然語言處理工程師的一個看家本領。這一部分的內容也是比較多的,這裡就做一個簡單的介紹和說明。

首先資料結構部分,需要重點關注連結串列、樹結構和圖結構(鄰接矩陣)。包括各個結構的構建、操作、優化,以及各個結構在不同場景下的優缺點。當然大部分情況下,可能使用到的資料結構都不是單一的,而是有多種資料結構組合。比如在分詞中有非常優秀表現的雙陣列有限狀態機就使用樹和連結串列的結構,但是實現上採用的是連結串列形式,提升了資料查詢和匹配的速度。在熟練掌握各種資料結構之後,就是要設計良好的演算法了。

伴隨著大資料的不斷擴張,單機的演算法越來越難發揮價值,所以多數場景下都要研發並行的演算法。這裡面又涉及到一些工具的應用,也就是程式設計技術的使用。例如基於Hadoop的MapReduce開發和Spark開發都是很好的並行化演算法開發工具,但是實現機制卻有很大的差別,同時程式設計的便利程度也不一樣。

當然這裡面沒有絕對的孰好孰壞,更多的是個人使用的習慣和業務場景的不同而不同。比如兩個都有比較成熟的機器學習庫,一些常用的機器學習演算法都可以呼叫庫函式實現,程式語言上也都可以採用Java,不過Spark場景下使用Scala會更方便一些。因為這一部分是偏實操的,所以我的經驗會建議例項學習的方法,也就是跟著具體的專案學習各種演算法和資料結構。最好能對學習過的演算法和資料結構進行總結回顧,這樣可以更好的得到這種方法的精髓。因為基礎的元素,包括資料結構和計算規則都是有限的,所以多樣的演算法更多的是在不同的場景下,對於不同元素的一個排列組合,如果能夠融會貫通各個基礎元素的原理和使用,不管是對於新知識的學習還是對於新解決方案的構建都是非常有幫助的。

對於工具的選擇,建議精通一個,對於其他工具也需要知道,比如精通Java和MapReduce,對於Spark和Python也需要熟悉,這樣可以在不同的場景下使用不同的工具,提升開發效率。這一部分實在是太多、太廣,這裡不能全面地介紹,大家可以根據自己的需求,選擇合適的學習資料進行學習。這裡給出一個學習基礎演算法(包含排序、圖、字串處理等)的課程連結:https://algs4.cs.princeton.edu/home/

語言學

這一部分就更多是語文相關的知識,比如一個句子的組成成分包括:主、謂、賓、定、狀、補等。對於各個成分的組織形式也是多種多樣。比如對於主、謂、賓,常規的順序就是:主語→謂語→賓語。當然也會有:賓語→主語→賓語(飯我吃了)。這些知識的積累有助於我們在模型構建或者解決具體業務的時候,能夠事半功倍,因為這些知識一般情況下,如果要被機器學習,都是非常困難的,或者會需要大量的學習素材,或許在現有的框架下,機器很難學習到。如果把這些知識作為先驗知識融合到模型中,對於提升模型的準確度都是非常有價值的。

在先期的研究中,基於規則的模型,大部分都是基於語言模型的規則進行研究和處理的。所以這一部分的內容對於自然語言處理也是非常重要的。但是這部分知識的學習就比較雜一些,因為大部分的自然語言處理工程師都是語言學專業出身,所以對於這部分知識的學習,大部分情況都是靠碎片化的積累,當然也可以花一些精力,系統性學習。對於這部分知識的學習,個人建議可以根據具體的業務場景進行學習,比如在專案處理中要進行同義詞挖掘,那麼就可以跟著“百科”或者“搜尋引擎”學習同義詞的定義,同義詞一般會有什麼樣的形式,怎麼根據句子結構或者語法結構判斷兩個詞是不是同義詞等等。

深度學習

隨著深度學習在視覺和自然語言處理領域大獲成功,特別是隨著AlphaGo的成功,深度學習在自然語言處理中的應用也越來越廣泛,大家對於它的期望也越來越高。所以對於這部分知識的學習也幾乎成為了一個必備的環節(實際上可能是大部分情況,不用深度學習的模型,也可以解決很多業務)。

對於這部分知識,現在流行的幾種神經網路都是需要學習和關注的,特別是迴圈神經網路,因為其在處理時序資料上的優勢,在自然語言處理領域尤為收到追捧,這裡包括單項RNN、雙向RNN、LSTM等形式。同時新的學習框架,比如對抗學習、增強學習、對偶學習,也是需要關注的。其中對抗學習和對偶學習都可以顯著降低對樣本的需求,這個對於自然語言處理的價值是非常大的,因為在自然語言處理中,很重要的一個環節就是樣本的標註,很多模型都是嚴重依賴於樣本的好壞,而隨著人工成本的上升,資料標註的成本越來越高,所以如果能顯著降低標註資料需求,同時提升效果,那將是非常有價值的。

現在還有一個事物正在如火如荼地進行著,就是知識圖譜,知識圖譜的強大這裡就不再贅述,對於這部分的學習可能更多的是要關注資訊的連結、整合和推理的技術。不過這裡的每一項技術都是非常大的一個領域,所以還是建議從業務實際需求出發去學習相應的環節和知識,滿足自己的需求,連結http://www.chinahadoop.cn/course/918

自然語言處理現狀

隨著知識圖譜在搜尋領域的大獲成功,以及知識圖譜的推廣如火如荼地進行中,現在的自然語言處理有明顯和知識圖譜結合的趨勢。特別是在特定領域的客服系統構建中,這種趨勢就更明顯,因為這些系統往往要關聯很多領域的知識,而這種知識的整合和表示,很適合用知識圖譜來解決。隨著知識圖譜基礎工程技術的完善和進步,對於圖譜構建的容易程度也大大提高,所以自然語言處理和知識圖譜的結合就越來越成為趨勢。

語義理解仍然是自然語言處理中一個難過的坎。目前各項自然語言處理技術基本已經比較成熟,但是很多技術的效果還達不到商用的水平。特別是在語義理解方面,和商用還有比較大的差距。比如聊天機器人現在還很難做到正常的聊天水平。不過隨著各個研究機構和企業的不斷努力,進步也是飛速的,比如微軟小冰一直在不斷的進步。

對於新的深度學習框架,目前在自然語言處理中的應用還有待進一步加深和提高。比如對抗學習、對偶學習等雖然在影象處理領域得到了比較好的效果,但是在自然語言處理領域的效果就稍微差一些,這裡面的原因是多樣的,因為沒有深入研究,就不敢妄言。

目前人機對話、問答系統、語言翻譯是自然語言處理中的熱門領域,各大公司都有了自己的語音助手,這一塊也都在投入大量的精力在做。當然這些上層的應用,也都依賴於底層技術和模型的進步,所以對於底層技術的研究應該說一直是熱門,在未來一段時間應該也都還是熱門。之前聽一個教授講過一個故事,他是做parser的,開始的時候很火,後來一段時間因為整個自然語言處理的效果差強人意,所以作為其中一個基礎工作的parser就隨之受到冷落,曾經有段時間相關的期刊會議會員銳減,但是最近整個行業的升溫,這部分工作也隨之而受到重視。不過因為他一直堅持在這個領域,所以建樹頗豐,最近也成為熱門領域和人物。

所以在最後引用一位大牛曾經說過的話:“任何行業或者領域做到頭部都是非常有前途的,即使是打球,玩遊戲。”(大意)

個人經驗

筆者是跟著專案學習自然語言處理的,非科班出身,所以的經驗難免會有偏頗,說出來僅供大家參考, 有不足和紕漏的地方敬請指正。

知識結構

要做演算法研究,肯定需要一定的知識積累,對於知識積累這部分,我的經驗是先學數學理論基礎,學的順序可以是代數→概率論→隨機過程。當然這裡面每一科都是很大的一個方向,學的時候不必面面俱到,所有都深入理解,但是相對基礎的一些概念和這門學科主要講的是什麼問題一定要記住。

在學習了一些基礎數學知識之後,就開始實現——編寫演算法。這裡的演算法模型,建議跟著具體的業務來學習和實踐,比如可以先從識別垃圾郵件這樣的demo進行學習實驗,這樣的例子在網上很容易找到,但是找到以後,一定不要看看就過去,要一步一步改寫拿到的demo,同時可以改進裡面的引數或者實現方法,看看能不能達到更好的效果。個人覺得學習還是需要下苦功夫一步一步模仿,然後改進,才能深入的掌握相應的內容。對於學習的資料,上學時期的各個教程即可。

工具

工欲善其事必先利其器,所以好的工具往往能事半功倍。在工具的選擇上,個人建議,最高優先順序的是Python,畢竟其的宣傳口語是:人生苦短,請用Python。第二優先順序的是Java,基於Java可以和現有的很多框架進行直接互動,比如Hadoop、Spark等等。對於工具的學習兩者還是有很大的差別的,Python是一個指令碼語言,所以更多的是跟著“命令”學,也就是要掌握你要實現什麼目的來找具體的執行語句或者命令,同時因為Python不同版本、不同包對於同一個功能的函式實現差別也比較大,所以在學習的時候,要多試驗,求同存異。

對於Java就要學習一些基礎的資料結構,然後一步一步的去編寫自己的邏輯。對於Python當然也可以按照這個思路,Python本身也是一個高階程式語言,所以掌握了基礎的資料結構之後,也可以一步一步的實現具體的功能,但是那樣好像就失去了slogan的意義。

緊跟時代

自然語言處理領域也算是一個知識密集型的行業,所以知識的更新迭代非常的快,要時刻關注行業、領域的最新進展。這個方面主要就是看一些論文和關注一些重要的會議,對於論文的獲取,Google Scholar、arxiv都是很好的工具和資源(請注意維護智慧財產權)。會議就更多了KDD、JIST、CCKS等等。

作者簡介:蘭紅雲,滴滴演算法工程師,負責演算法策略相關工作。主要專注於機器學習和自然語言處理方向。著有《自然語言處理技術入門與實踐》。

如何成為一名

這裡寫圖片描述