參考場景:文本情緒的分析

文中涉及的「數據目錄」和「源代碼目錄」見雲盤:pan.baidu.com/s/1slJntR

互聯網上存在著各種各樣的文本內容,在這些文字中其實蘊藏著很多信息,比如當時的心情、有無政治傾向、對所評論的商品是否滿意,等等。這裡,以豆瓣電影的大約 10 萬條評論數據(數據目錄下 douban_comments.csv)作為研究對象,嘗試去自動分析某條評論對該電影的整體觀感是正面的還是負面的。

這個數據我們應該比較熟悉,因為在前面有關貝葉斯的章節中已經使用過這個數據。

這個例子中的程序可見源代碼目錄下 sentiment.py,運行之前需要先安裝用於自然語言計算的庫 NLTK(nltk.org/)。如果要在 KNIME 中進行類似的計算,需要先額外安裝中文文本處理的插件(KNIME Labs Extensions > KNIME Textprocessing Chinese Language Pack)。

1、理解情緒分析

這裡所謂的「情緒」,和人的情緒並不相同,而更多的是對某些特定目標(商品、電影、藝人等等)的一種心理趨勢,也就是說,這樣的分析主要目的是通過文本數據來量化心理上的一種傾向。比如,在電商網站完成了一個訂單之後,大多數人寫的評價,並不會明顯帶有什麼情緒,但是,評論的內容會反映了用戶對這個產品是不是滿意,我們可以把這稱為「購物情緒」。以此類推,就會有「政治情緒」、「電影情緒」、「圖書情緒」……等等。

對於這些「情緒」的判斷,一般和情緒的判斷類似,主要目的是判斷情緒屬於「好」的還是「壞」的。或者,換種更加通用一點的說法,是偏「正面」一點的、還是偏「負面」一點的。當然,也可以進一步分得更細緻一點,比如非常好、一般、較差、很差等等,本質上都是一個分類問題,無非是區分類別多少的差別而已。

2、對文本進行分詞、預處理

對於主要是中文的文本內容,首先要做的事情就是對文本進行分詞,因為中文文本的意思是根據「詞」而不是「單字」決定的。在進行分詞以後,還需要清理掉一些基本不包含有效信息的詞,比如標點符號、數字、助詞等並不包含信息量的停止詞(見數據目錄下 stop-words.txt 文件)等等,經過這樣處理的文本才是可以用於下一步分析的數據。

下面是一段對這個豆瓣電影的評論數據進行分詞和預處理的示例代碼:

# 讀取停止詞表dict_stop = pd.read_fwf("stop-words.txt", header=None)[0].values# 定義中文分詞器,注意,這裡在返回分詞結果時就進行了過濾thu = thulac.thulac()def tokenizer(text): try: cuts = thu.cut(text) # 排除空格、以及停止詞表中的詞 return [c[0] for c in cuts if c[0] not in dict_stop and c[0].strip() != ] except Exception as e: return []# 讀取數據並預處理data = pd.read_csv(douban_comments.csv")data[words] = data[Comment].apply(tokenizer)

3、詞語隱含信息的不確定性

在前面介紹常見機器學習方法的時候,我們嘗試過對分詞結果直接使用樸素貝葉斯方法來進行預測,準確率約為70%。現在,讓我們來看一下直接使用詞語可能存在的問題:

比如這樣幾條評分為一星或兩星的評論:

  • 不出意料得爛,喜歡這部電影的孩子,大概也喜歡變4
  • 超級難看。。。
  • 華麗又昂貴的一坨!

從詞語上,裡面包含了不少正面的辭彙,比如第一條評論中,出現了兩次「喜歡」;第二條評論的「超級」非常正面,但其實是修飾了後面的「難看」;第三條幾乎都是正面的辭彙,但其實是想表達一坨……可見,語言中的詞語有很多前後關聯、以及語境的關係,非常複雜。因此,對於自然語言的理解一直是機器學習和人工智慧領域研究的重要課題。

現在,我們要盡量提升對這些評論文本的理解,應該想到,詞語是可以聯繫起來理解的,這在自然語言處理中稱為 N-Gram (N 元語法)模型,所謂的 N 就是用 N 個相鄰的詞聯繫在一起進行理解。

下面,我們就採用了 NLTK 提取了每條評論中的單詞、雙詞、三詞,將它們都作為需要進行計算的詞對象:

def bag_of_words(words): return dict([(word, True) for word in words])def gram_words(words, n=100): try: bigram_finder = BigramCollocationFinder.from_words(words) bigrams = bigram_finder.nbest(BigramAssocMeasures.chi_sq, n) trigrams_finder = TrigramCollocationFinder.from_words(words) trigrams = trigrams_finder.nbest(TrigramAssocMeasures.chi_sq, n) return bag_of_words(words + bigrams + trigrams) except Exception as e: return []data[words] = data[Comment].apply(tokenizer) # 用分詞器分成單詞data[gram_words] = data[words].apply(gram_words) # 通過單詞提取雙詞、三詞

通過這樣的多重的辭彙提取,總共提取了約 155.6萬個不同的詞對象,其中約 74.8萬個詞是在打分大於3分的評論中出現過的,約 92.2萬個詞是在打分小於等於3分的評論中出現過的。大致的結果如下:

打分大於3分的評論:

打分小於等於3分的評論:

基於這樣的「分詞」,後續我們就可以同樣採用樸素貝葉斯方法進行分類,但是,我們會發現預測的準確率並沒有顯著提高。

4、詞語包含信息量的多少

為什麼提取了更多的詞,但是並沒有起到效果?這是因為我們雖然提取了更多的辭彙,但是很多辭彙可能只出現了一次兩次,而且並不帶有能夠表達情緒的信息,這些過多的詞反而可能干擾了分析的結果。在數據分析中,「信息量」是需要重點關注的一個很重要的角度,選取儘可能多信息量的數據,不僅有助於減少分析的數據,還能減少無效信息的干擾。因此,我們需要在分析中嘗試選取部分包含較多信息量的詞進行分析。

一個詞包含的信息量如何去衡量?這在統計上有很多方法。比如,在前面介紹樸素貝葉斯方法時所用的示例(源代碼目錄下 naive_bayes_douban_movies.py 文件)中,就使用了 TF-IDF 這種在信息檢索領域被普遍採用的方法。TF-IDF 的主要思想認為,如果一個詞在一個文檔中出現的頻率較高,但是在其它文檔中出現的頻率較低,那麼代表這個詞包含的信息量較多,能夠對文檔有較好的區分能力。

在 NLTK 中,還提供了其它好幾種統計詞信息量的方法,比如卡方(Chi-Square)統計、PMI 統計等,這裡我們採用卡方統計來進行計算,對所有的詞進行評分:

# 提取所有片語的信息量word_scores = {}N_pos = cond_word_fd[pos].N()N_neg = cond_word_fd[neg].N()N = N_pos + N_negfor word, freq in word_fd.items(): pos_score = BigramAssocMeasures.chi_sq(cond_word_fd[pos][word], (freq, N_pos), N) neg_score = BigramAssocMeasures.chi_sq(cond_word_fd[neg][word], (freq, N_neg), N) word_scores[word] = pos_score + neg_score

有了詞的信息量數據後,就可以按信息量評分來對所有的詞進行排序,然後優先選擇信息量多的詞參與到計算中來。在源代碼目錄下的 sentiment.py 文件中,有詳細的尋找較優的片語數量,然後進行訓練預測的步驟。

這樣,大概選取所有片語中,包含信息量較多的不到十分之一的詞,就可以達到一個較優的預測性能,模型的準確度可以提高到約 79%。下面是選取不同比例片語時( 片語總數155.6萬,最小的比例為 1/100 ),準確率的變化情況:

5、思考:沒有監督的數據怎麼分析?

雖然有很多數據是有評分等標籤可以用於對情感進行監督分類的,但是,像微博、論壇帖子等很多場景下,文本內容也可能是不存在可以用於監督的標籤的。對於這樣的數據,怎麼來進行情感趨勢的判斷?

一種簡單的辦法是使用情感詞典,比如在數據目錄下有一個 chinese-sentiment.zip 文件中,就包含了若干分別表達正面情感和負面情感的辭彙。通過情感詞典,就可以對每個文本中的詞進行匹配,如果某個詞在詞典中出現,就可以標記出這個詞的情感傾向,繼而統計這個文本中所有詞的情感傾向以及信息量的多少,來綜合推斷這個文檔的情感傾向。當然,根據不同的場景,如果還能有針對地補充一些面向具體業務的情感詞典,可能會有更好的效果。

6、練習

這裡有淘寶某件爆款商品的評論數據(數據目錄下的 taobao_comment.xlsx 文件),試著從這些評論中,計算出這個商品總體的滿意度是多少。


推薦閱讀:

關於自然語言處理(NLP)的閑談(寫在前面)
我們分析了300萬字文本,終於知道了什麼是直男癌
【譯文】使用文本挖掘技術分析Twitter用戶對電影的評價
基於半監督學習技術的達觀文本過濾系統
【乾貨】--手把手教你完成文本情感分類

TAG:文本挖掘 | 分詞 |