Etu Blog-藍衣人的視界

掌握大數據趨勢,解析消費者意圖

 

玩轉文字探勘以 word2vec 以及 ptt 資料為例

 

文字探勘以及自然語言處理一直以來是數據分析世界非常重要的一部份,藉由對文字的處理,可以做出很有趣的應用。舉例來說,像是輿情分析系統,是利用分析社群網路資料來了解目前社群網路上面熱門的討論話題...

,更進一步得出社群對於這個討論話題的熱門評論,來得到社群使用者對於議題的觀感。在商業上面則可以知道說對於某個品牌在社群的討論度以及意見是如何,以提供行銷上面的參考。Etu 在許多合作的專案上使用到了許多不同的文字探勘技術,其中 word2vec 是個很有趣也頻繁地被使用的技術,筆者想藉由撰寫本文來向大家介紹這個很適合拿來做文字模糊搜尋的演算法。

 

word2vec 簡介

word2vec 正如其名就是 word to vector 是一個能把文字變成向量的演算法
用更口語的表達來說, word2vec 是在做一項翻譯的工作,把詞(word)轉換成電腦可以了解的模式(vector)。當然,如果它只有這項功能的話,筆者並不需要特別把它拿出來寫的。最有趣的事情是 word2vec 在做翻譯這項工作的時候,他同時可以讀取出詞裡的概念。舉個 word2vec 的經典例子來說,當我們想到英國的時候,可能就會想到它的首都倫敦。而word2vec 在經過訓練以後是有能力做到這樣的推想的。更棒的是他的訓練速度非常快,因此實用價值非常地高。

 

為什麼 word2vec 可以讀取出詞與詞的概念呢?這個跟他的演算方法有關。用一句話解釋就是他會把這個詞附近的相鄰詞考慮進來。實際上實作有兩種的演算法,第一種稱作 Continuous Bag Of Words(CBOW),此方法會利用上下文的詞來當作神經網路的輸入,最後預測這個目標的詞是什麼.而第二種則是 Skip-Gram 演算法,剛好跟第一種演算法相反,他所輸入的是當前的詞來預測這一段的文章上下文的詞.這兩種演算法可以在使用 word2vec 的時候進行選擇,會有不同的效果。

 

讓我們用口語的方式再說明一次上述演算法的概念。我們現在從一篇文章隨機取出了兩個詞,在學習的過程中,這兩個詞分別的上下文會被導入 word2vec 來決定他們向量的數值。而這個向量是一個 N(本文取 100 來做測試) 個長度的數字,同一個詞,例如:台灣,向量值必定是一樣的。

 

在訓練的過程中,如果這兩個向量的上下文被判定為相似的,那 word2vec 會調整向量裡的數值來讓彼此在向量空間裡的距離拉近,而反之則會把他拉遠。 從這個概念裡面可以推想的到,最後學習完成的模型會把同樣概念的詞在向量空間裡面聚集在一起,這可能是國家的名稱例如:法國、英國、德國,而抽象的概念也會被聚集在一起例如:高興、快樂、愉悅。

 

因此學習完成後我們可以任意抽出兩個詞,並得到他的詞向量,並用詞向量來計算他們之間的距離。這個實際距離的概念也就是抽象意義上面他們兩個詞的相似性,所以我們可以說當這兩個向量數值是相似的時候,他在抽象意義上面的關係是很近的。

 

(編按:我們是如何計算兩個詞的相似性呢? word2vec 使用 Cosine Similarity 來計算兩個詞的相似性。這是一個 -1 到 1 的數值,如果兩個詞完全一樣就是 1。像是「台灣」這個詞和他自身的 Cosine Similarity 就是 1) 而除了比較相似性以外, word2vec 還可以有類推這個概念。從引用至 google open source blog 的圖來看,我們可以看到國家的距離是彼此相近的,中國、俄國、日本…等,而相對應首都的距離也是相近的。接下來就是有趣的地方了,可以觀察到每個國家和其首都的距離都是類似的,如圖中每條虛線的所示。如果我們把這種對應關係改成數學上的表示的話就是「巴黎 - 法國 = 柏林 - 德國」。這真的是非常酷炫的對應關係。所以我們可以在向量上面有這樣的表示方法「巴黎 - 法國 + 德國 = ?」。聰明的你應該可以想到我們可以用這個方法來推斷未知國家的首都在哪?

 


圖 1. 活動花絮
( 圖片出處:google opensource blog ),Sheng-Wen Tsai 整理 )

 

分析資料來源

我們從台灣著名的論壇 PTT 八卦版,利用網路爬蟲蒐集了 53179 篇文章,做一些過濾以後把文章的內文以及推文視作同一篇文章以後送入 word2vec 。進入 word2vec 之前會先做中文的斷詞,因為其輸入必須為空白分隔的詞。因此這裡使用結巴來對文章做斷詞,這裡有個簡單的範例展示斷詞的結果如下:

蘋果日報 華航 空服員 罷工 今天 接任 華航 董事長 何煖 軒 昨晚 說 華航 應 同意 空服員 暫停 桃園 報到 恢復 月 日前 勞動 條件 工作 狀態 蘋果 即時 報導

 

有趣的結果

當然是先來看看最近很夯的寶可夢,會找出什麼東西來呢?

model.most_similar(u"寶可夢",topn=7)

精靈 0.841851711273
pokemon 0.815947473049
go 0.814610183239
神奇寶貝0.768447518349
pokmon 0.724099516869
紐澳地區 0.699946522713
手機遊戲 0.693551421165

可以看到和寶可夢相關相似的詞有哪些,有趣的是其中 pokemon 和 pokmon 兩個都出現了,這個原因可能是論壇上很多人都拼錯英文的關係。那我們再嘗試把 pokemon 丟入搜尋,看會不會找出對應的結果。

model.most_similar(u"pokemon",topn=7)

go 0.916369259357
寶可夢 0.815947532654
pokmon 0.765063524246
niantic 0.753145098686
精靈 0.736871242523
實境 0.720480561256
紐澳地區 0.714234352112

結果是不是很相似呢?接著我們嘗試找出概念相似的詞,例如國民黨之於 KMT,就像是民進黨之於什麼呢?在向量裡的計算就可以表示成「國民黨 - KMT = 民進黨 - ?」

model.most_similar(positive=u"kmt 民進黨".split(" "), negative=[u"國民黨"],topn=5)

dpp 0.891826570034
ddp 0.672499418259
執政 0.599427700043
執政黨 0.597405433655
dop 0.59016430378

從這個結果來看,看來很多時候使用者會有打字錯誤的問題。
最後的一個實驗,我們嘗試找出對於某個關鍵字,論壇上面使用者可能的推文。而詳盡的尋找方式這裡因爲篇幅的關係而略過,但以下是對於關鍵字pokemon找出的有趣推文。

X好想玩 (這裡將髒話隱碼)
請正名寶可夢
想玩+1
使用同行
鮑鯉龍
你被騙了
http://i.imgur.com/kmuAXKN.png?1
http://i.imgur.com/TvYBuvJ.png
那不是小朋友在玩的嗎怎麼一堆成年人這麼幼稚玩那個?

以上這些是一些初步的結果,還可以增加輸入資料,最佳化文章處理以及斷詞的功能,更甚者增加新的分析方式,都可以產生出更有趣的分析結果。
希望大家都能享受 Data is everywhere 的浪潮,跟我們一起玩 Data ,一起創造 Data 更多的價值。

 

本文作者為 Etu 數據工程師 蔡勝文(Sheng-Wen Tsai)