轉眼間已經工作了一段時間了,回想起2014年初學機器學習時的付出、艱苦和努力,感覺都是值得的。從現在往前看,我是沿着“計算機->統計學->數據分析->數據挖掘->機器學習->文本挖掘”的路徑走過來的,我覺得這個思路還是屬於比較傳統的進階方法,學習的內容有不少的冗余,但相對來說更穩健一些。今天寫這篇文章的目的是想總結一下我最近關於文本挖掘的工作體會以及我對機器學習的一些新的看法,只為探討,還望與大家共勉。
我先來說一些文本挖掘的東西。似乎大家做Text Mining的不太多,可能並不太感冒,我就大體說一下我對Text Mining的理解吧(我覺得不管做哪一種數據挖掘,方法和思路應該都是相通的,您試着看一下,說不定會有些啟發)。
文本挖掘,顧名思義,就是挖掘本文信息中潛在的有價值的信息。文本數據與數值數據的區別有三:第一,非結構化且數據量大;第二,它與人的語言是對接的;第三,文字的含義不唯一。下面我稍微展開來說。
首先,文本數據的數據量是非常之巨大的,一百萬條結構化數據可能才幾十到幾百兆,而一百萬條文本數據就已經是GB了。當然文本數據的數據量無法與每天的log數據相比,但在基礎數據中算是占比很大的數據類型了。大數據容量的數據和大數據條目的數據處理方式完全不一樣,普通的機器甚至都無法按條處理;其次呢,文本數據是非結構化數據。非結構化意味着沒有任何的列可供你定義和參考。舉個例子來說:如果我們想要提取用戶登錄的行為數據,只要提取用戶的id、登錄時間、行為時間、行為內容之類的數據就可以很完整的表達用戶的行為;但對於文本數據卻沒法這么做,比如:“今天的天真好啊!”,提什么呢?當然可以提出這句話的主語等句法結構來,但那已經是挖掘之后的結果了,而不是挖掘以前的原始提取。
第二點是最重要的,就是文本數據與人的思想直接對接。如果我獲取一對情侶的短信數據,男生對女生發“我愛你”的次數和時間能直接反應男生對女生的態度。比如,男生總在對女生噓寒問暖之后說一句“我愛你”,並且一個月內經常說,可能代表男生真的很喜歡這個女孩;而如果男生每次說我愛你之后對女生各種不耐煩或敷衍,那么這個男生可能與女生有些間隙了。當然,我只是舉了個例子,不過卻能證明文本挖掘也許這能挖掘出人的真實的態度。
第三點是文字的含義是不唯一的。這也是文本挖掘最大的難題所在。“你吃飯嗎?”——“我也不知道”,請問這個到底是想吃飯還是不想吃飯?當然,這個需要從上下文去解讀,但是在沒有上下文的時候也會出現這兩句話的(比如我們在宿舍)。如果按我們人的理解,大多數情況下,是這個人不太想吃飯,但可能出於某種原因(比如跟朋友一起去吃或者完了就沒飯了)而又想去吃。反正根據我自己的經驗,一般說不知道的最后都去吃飯了……那么,如何讓計算機去理解這樣的句子呢?目前來說,還是比較難的。
這是文本數據與數值數據最大的區別,就是難以量化。
那么對於難以量化的數據該怎么處理呢?
方法就是數據挖掘中的“數據轉換”。
我們最終的目的是要量化一段文本(比如文本主題是哪一類、文本是什么態度等等),可以通過把文本轉換成其他數據結構的數據,然后再根據該結構的類型判斷數據的類別。比如我們把文本中能表達含義的基本單位“詞”組織成詞典,然后判斷詞典的類別,我們就知道文本的類別了。舉個例子:“我喜歡劉亦菲”,分詞之后通過代詞詞典知道“我”是一個代詞,用當前用戶的id替換掉代詞,比如我的id是“小袁”,那么這句話就變成了“小袁喜歡劉亦菲”,再通過正向謂詞詞典知道“喜歡”是一個正向謂詞,而劉亦菲是一個專有名詞,那么當我們想要知道在所有用戶中喜歡劉亦菲的有誰時,可以輸出“小袁”。這在輿情分析和熱點分析中的作用是非常大的。
當然,上面的方法只是一個例子,且不具有實用性。因為建立詞典的代價是非常大的,更何況上面的例子還需要很多個詞典,並且詞典也很難包含所有的詞。所以,好多人就想出了一些新的方法,我在這里就不一一列舉了。
當我們能夠量化文本了之后,我們就可以抽取文本信息了。比如,我想知道近一個月的熱門電影有哪些,我們就可以抽取出最近一個月的影評數據,然后抽取評論信息中的主語和賓語,通過自然語言處理方法進行消岐和消除指代后就可以找到文本的命名實體,通過對找到的實體進行聚類就能找到熱門電影有哪些了。
那么機器學習在文本挖掘中有哪些應用呢?
(1)話題識別
話題識別屬於文本分類,實驗中常見的例子就是把新聞文本分類成“財經、教育、體育、娛樂”等等。我目前常用的方法主要是“word2vector”和“word to bags”。 word2vector即“詞向量”,通過計算文本中詞出現的位置、詞性和頻率等特征,判斷新文本是否來自於此類。比如識別文字是評論性文本還是新聞類文本的一種方案就是評論性語句中出現的情態動詞和感嘆詞比較多且位置不固定。“word to bags”是詞袋,在topic model中應用的比較多。“word to bags”計算每個詞出現在每個類別的概率,然后通過TF-IDF或者信息增益或者概率找到類別信息含量高的詞語,通過判斷這些詞語的共線程度進行文本分類。
(2)情感分類
情感分析就是用戶的態度分析。現在大多數情感分析系統都是對文本進行“正負二項分類的”,即只判斷文本是正向還是負向的,有的系統也能做到三分類(中立)。比如,我要分析用戶對2013年“馬航370事件”的態度,只要找到該事件的話題文本,通過台大情感詞典等工具判斷情感詞的極性,然后根據一定規則組合情感詞的頻度和程度即可判斷文本的情感。但這種方法無法判斷文本的評價刻面。比如,我現在有一百萬條“小米手機評價”信息,我可以通過上面的方法了解大約有百分之多少的用戶對小米手機是不滿意的,但卻無法知道這些不滿意的用戶是對小米手機的哪一個方面不滿意以及占的比率(比如是外形還是性能)。常用的方法是構建小米手機相關詞的種子詞典,通過詞典找到用戶評論的刻面,再構建句法樹找到評論該刻面的謂語和修飾副詞,通過情感詞典量化出情感極性,最后將量化后的評論刻面、修飾詞、程度副詞帶入SVM進行文本分類。不過在這里並不適合使用naive bayes,因為在多刻面多分類中,naive bayes很容易出現過擬合。
(3)命名實體識別
所謂的命名實體識別是指讓計算機自動識別出自己不認識的詞。比如:“胡歌唱歌非常好聽!”,計算機如何才能知道“胡歌”是一個詞而不應該是“歌唱”是一個詞呢?“胡歌”這個詞對於絕大多數詞庫而言都不太可能存在,那么怎么能讓機器識別出這個詞並且以最大的可能認為這個詞是正確的呢?我認為在所有的方法中,CRF的效果最好,甚至比HMM要好得多。CRF又稱條件隨機場,它能夠記錄訓練數據中每個特征的狀態及其周圍特征的狀態,當多個特征同時出現的時候,找出每個特征在多個特征組合中最有可能出現的狀態。也就是說,CRF以“物以類聚”為基本論點,即大多數詞出現的環境是有規律的,並不是雜亂無章的。選取特征的時候,以“字”為單位明顯要比以“詞”為單位好很多,因為命名實體的詞是以字為單位才能理解的,比如“陳小春”,我們是以“陳/小/春”的意思來理解的,而不是“陳/小春”或者“陳小/春”。
(4)推薦系統
文本挖掘在推薦系統中的價值在於特征詞權重的計算。比如我們給用戶推薦一本新書。我們可以按照下面的方式進行建模:首先找到用戶評論中關於書籍的所有特征詞匯,建立特征詞典;然后通過文本分析和時間序列分析結合用戶評論的內容和時間緊湊度計算特征詞的權重,表示某個用戶關心的某個特征的程度。對建立好的用戶評論特征程度表進行倒排索引,找到每個特征詞的所有評價用戶及其評價的權重,最后根據要推薦的書籍的特征找到可以推薦的用戶列表,找到評論權重高的用戶並把書籍推薦給他。
好了先說這么多,不過在最后,我想總結一下關於機器學習的一些認識的問題。
有一些學習機器學習的朋友曾經問我,為什么他學機器學習有一段時間了但是感覺沒學一樣,也不知道究竟該怎么用。我覺得有三種可能:第一,看待問題不夠宏觀;第二,沒有從實際出發去思考機器學習這門技術;第三,前面的基礎沒打好,導致看后面的內容不知所以然。舉個例子來說,我們常常要對網站的評論進行挖掘,努力找出評論信息中能代表用戶特征、行為、習慣、愛好、態度等信息的內容。要完成這樣的一份工作需要這么幾個步驟:獲取原始數據、數據清洗、數據轉換、歸約和降維、選擇特征項、選擇分類器、建立特征抽取模型、訓練數據、分類數據、結果評測、模型調整……如果我們不能宏觀的以解決問題為目的而以使用某種技術方法的角度去看待這個任務,我們根本無從下手,因為某種技術僅僅是解決問題的一種手段,而不是必要的一個步驟。這是第一個錯誤的來源。
再來說第二個錯誤。所謂的“從實際出發”是指我們並往往不是“因為要解決某個問題而使用某種技術”,而經常是“因為我會某種技術而去解決某個問題”。舉個例子,當我第一次看明白SVM的時候我很興奮,我找了一大堆數據來跑SVM,比如對影評或微博評論進行態度情感分類之類的工作。可是當我做到特征抽取的時候就發現我很難量化出一段文字描述的內容及其程度來。后來想了好多辦法來解決,最終把向量空間變異成了語言空間模型,才實現了最終的結果,而且精讀也不是很高。這個時候基本也已經不是原來的SVM了。在整個過程中,我強行的使用某種方法去解決一個問題,最終導致工作趨於失敗的方向(雖然勉強實現了,但結果差強人意。后來發現使用bayes效果更好)。我認為第二個錯誤是絕大多數新手都會犯的錯誤,我在這方面犯了無數次跟頭,希望大家引以為戒。
最后一個錯誤也很普遍,也是很多同學經常出現的老大難的問題,典型例子就是理論推導。比如,SVM中引入拉格朗日乘子α來處理掉w和b,將兩個參數的推待求方程變為了一個參數的待求方程。那么引入拉格朗日參數的原因是什么?甚至會問“拉格朗日是什么來着?”這些都需要我們回頭去查資料的。如果數學和計算機的理論不夠,我們很難往下推動學習的進展,也難以理解算法采用某種方法的原理是什么。
不過,在我們最求所以然的時候,也要在某些細枝末節上學會“不求甚解”。好多同學(包括我在內)都曾經因為一個積分算不出來而失去了學下去的整個動力。其實我很建議大家有的時候不要太過於糾結為什么積分結果是這樣,為什么結果形式變了,而應該多想一想為什么要求這個結果?這個結果有什么用?這對大家更深入的理解算法有用得多。那么為什么不建議大家去想計算的細節呢?因為在實際應用中計算過程被計算機給代替了。
好了,碼了這么多字,有點累了。還是那句話,只是一個階段性總結,寫的不周到的地方,還望大家指出,小弟不勝感激!
——小袁NLP
