如何用Python和機器學習訓練中文文本情感分類模型?

利用Python機器學習框架scikit-learn,咱們本身作一個分類模型,對中文評論信息作情感分析。其中還會介紹中文停用詞的處理方法。html

疑惑

前些日子,我在微信後臺收到了一則讀者的留言。python

我一會兒有些懵——這怎麼還帶點播了呢?git

可是旋即我醒悟過來,好像是我本身以前挖了個坑。github

以前我寫過《 如何用Python從海量文本抽取主題? 》一文,其中有這麼一段:正則表達式

爲了演示的流暢,咱們這裏忽略了許多細節。不少內容使用的是預置默認參數,並且徹底忽略了中文停用詞設置環節,所以「這個」、「若是」、「可能」、「就是」這樣的停用詞纔會大搖大擺地出如今結果中。不過沒有關係,完成比完美重要得多。知道了問題所在,後面改進起來很容易。有機會我會寫文章介紹如何加入中文停用詞的去除環節。瀏覽器

根據「本身挖坑本身填」的法則,我決定把這一部分寫出來。bash

我可使用偷懶的辦法。微信

例如在原先的教程裏,更新中文停用詞處理部分,打個補丁。app

可是,最近我發現,好像至今爲止,咱們的教程歷來沒有介紹過如何用機器學習作情感分析。框架

你可能說,不對吧?

情感分析不是講過了嗎?老師你好像講過《 如何用Python作情感分析? 》,《 如何用Python作輿情時間序列可視化? 》和《 如何用Python和R對《權力的遊戲》故事情節作情緒分析? 》。

你記得真清楚,提出表揚。

可是請注意,以前這幾篇文章中,並無使用機器學習方法。咱們只不過調用了第三方提供的文本情感分析工具而已。

可是問題來了,這些第三方工具是在別的數據集上面訓練出來的,未必適合你的應用場景。

例若有些情感分析工具更適合分析新聞,有的更善於處理微博數據……你拿過來,倒是要對店鋪評論信息作分析。

這就如同你本身筆記本電腦裏的網頁瀏覽器,和圖書館電子閱覽室的網頁瀏覽器,可能類型、版本徹底同樣。可是你用起本身的瀏覽器,就是比公用電腦上的舒服、高效——由於你已經根據偏好,對本身瀏覽器上的「書籤」、「密碼存儲」、「稍後閱讀」都作了個性化設置。

我們這篇文章,就給你講講如何利用Python和機器學習,本身訓練模型,對中文評論數據作情感分類。

# 數據

個人一個學生,利用爬蟲抓取了大衆點評網站上的數萬條餐廳評論數據。

這些數據在爬取時,包含了豐富的元數據類型。

我從中抽取了評論文本和評星(1-5星),用於本文的演示。

從這些數據裏,咱們隨機篩選評星爲1,2,4,5的,各500條評論數據。一共2000條。

爲何只甩下評星數量爲3的沒有選擇?

你先思考10秒鐘,而後往下看,覈對答案。

答案是這樣的:

由於咱們只但願對情感作出(正和負)二元分類,4和5星能夠看做正向情感,1和2是負向情感……3怎麼算?

因此,爲了不這種邊界不清晰形成的混淆,我們只好把標爲3星的內容丟棄掉了。

整理好以後的評論數據,以下圖所示。

我已經把數據放到了演示文件夾壓縮包裏面。後文會給你提供下載路徑。

模型

使用機器學習的時候,你會遇到模型的選擇問題。

例如,許多模型均可以用來處理分類問題。邏輯迴歸、決策樹、SVM、樸素貝葉斯……具體到我們的評論信息情感分類問題,該用哪種呢?

幸虧,Python上的機器學習工具包 scikit-learn 不只給咱們提供了方便的接口,供咱們調用,並且還很是貼心地幫咱們作了小抄(cheat-sheet)。

這張圖看似密密麻麻,很是混亂,其實是一個很是好的迷宮指南。其中綠色的方框,是各類機器學習模型。而藍色的圓圈,是你作判斷的地方。

你看,我們要處理類別問題,對吧?

順着往下看,會要求你判斷數據是否有標記。咱們有啊。

繼續往下走,數據小於100K嗎?

考慮一下,咱們的數據有2000條,小於這個閾值。

接下來問是否是文本數據?是啊。

因而路徑到了終點。

Scikit-learn告訴咱們:用樸素貝葉斯模型好了。

小抄都作得如此照顧用戶需求,你對scikit-learn的品質應該有個預期了吧?若是你須要使用經典機器學習模型(你能夠理解成深度學習以外的全部模型),我推薦你先嚐試scikit-learn 。

向量化

如何用Python從海量文本抽取主題? 》一文裏,咱們講過天然語言處理時的向量化。

忘了?

不要緊。

子曰:

學而時習之,不亦樂乎?

這裏我們複習一下。

對天然語言文本作向量化(vectorization)的主要緣由,是計算機看不懂天然語言。

計算機,顧名思義,就是用來算數的。文本對於它(至少到今天)沒有真正的意義。

可是天然語言的處理,是一個重要問題,也須要自動化的支持。所以人就得想辦法,讓機器能儘可能理解和表示人類的語言。

假如這裏有兩句話:

I love the game.

I hate the game.

那麼咱們就能夠簡單粗暴地抽取出如下特徵(其實就是把全部的單詞都羅列一遍):

  • I
  • love
  • hate
  • the
  • game

對每一句話,都分別計算特徵出現個數。因而上面兩句話就轉換爲如下表格:

按照句子爲單位,從左到右讀數字,第一句表示爲[1, 1, 0, 1, 1],第二句就成了[1, 0, 1, 1, 1]。

這就叫向量化。

這個例子裏面,特徵的數量叫作維度。因而向量化以後的這兩句話,都有5個維度。

你必定要記住,此時機器依然不能理解兩句話的具體含義。可是它已經儘可能在用一種有意義的方式來表達它們。

注意這裏咱們使用的,叫作「一袋子詞」(bag of words)模型。

下面這張圖(來自 ~https://goo.gl/2jJ9Kp~ ),形象化表示出這個模型的含義。

一袋子詞模型不考慮詞語的出現順序,也不考慮詞語和先後詞語之間的鏈接。每一個詞都被看成一個獨立的特徵來看待。

你可能會問:「這樣不是很不精確嗎?充分考慮順序和上下文聯繫,不是更好嗎?」

沒錯,你對文本的順序、結構考慮得越周全,模型能夠得到的信息就越多。

可是,凡事都有成本。只須要用基礎的排列組合知識,你就能計算出獨立考慮單詞,和考慮連續n個詞語(稱做 n-gram),形成的模型維度差別了。

爲了簡單起見,我們這裏仍是先用一袋子詞吧。有空我再給你講講……

打住,不能再挖坑了。

中文

上一節我們介紹的,是天然語言向量化處理的通則。

處理中文的時候,要更加麻煩一些。

由於不一樣於英文、法文等拉丁語系文字,中文自然沒有空格做爲詞語之間的分割符號。

咱們要先將中文分割成空格鏈接的詞語。

例如把:

「我喜歡這個遊戲」

變成:

「我 喜歡 這個 遊戲」

這樣一來,就能夠仿照英文句子的向量化,來作中文的向量化了。

你可能擔憂計算機處理起中文的詞語,跟處理英文詞語有所不一樣。

這種擔憂不必。

由於我們前面講過,計算機其實連英文單詞也看不懂。

在它眼裏,不論什麼天然語言的詞彙,都只是某種特定組合的字符串而已。 不論處理中文仍是英文,都須要處理的一種詞彙,叫作停用詞。

中文維基百科裏,是這麼定義停用詞的:

在信息檢索中,爲節省存儲空間和提升搜索效率,在處理天然語言數據(或文本)以前或以後會自動過濾掉某些字或詞,這些字或詞即被稱爲Stop Words(停用詞)。

我們作的,不是信息檢索,而已文本分類。

對我們來講,你不打算拿它作特徵的單詞,就能夠看成停用詞。

仍是舉剛纔英文的例子,下面兩句話:

I love the game.

I hate the game.

告訴我,哪些是停用詞?

直覺會告訴你,定冠詞 the 應該是。

沒錯,它是虛詞,沒有什麼特殊意義。

它在哪兒出現,都是一個意思。

一段文字裏,出現不少次定冠詞都很正常。把它和那些包含信息更豐富的詞彙(例如love, hate)放在一塊兒統計,就容易干擾咱們把握文本的特徵。

因此,我們把它看成停用詞,從特徵裏面剔除出去。

觸類旁通,你會發現分詞後的中文語句:

「我 喜歡 這個 遊戲」

其中的「這個」應該也是停用詞吧?

答對了!

要處理停用詞,怎麼辦呢?固然你能夠一個個手工來尋找,可是那顯然效率過低。

有的機構或者團隊處理過許多停用詞。他們會發現,某種語言裏,停用詞是有規律的。

他們把常見的停用詞總結出來,聚集成表格。之後只須要查表格,作處理,就能夠利用先前的經驗和知識,提高效率,節約時間。

在scikit-learn中,英語停用詞是自帶的。只須要指定語言爲英文,機器會幫助你自動處理它們。

可是中文……

scikit-learn開發團隊裏,大概缺乏足夠多的中文使用者吧。

好消息是,你可使用第三方共享的停用詞表。

這種停用詞表到哪裏下載呢?

我已經幫你找到了 一個 github 項目 ,裏面包含了4種停用詞表,來自哈工大、四川大學和百度等天然語言處理方面的權威單位。

這幾個停用詞表文件長度不一樣,內容也差別很大。爲了演示的方便與一致性,我們統一先用哈工大這個停用詞表吧。

我已經將其一併存儲到了演示目錄壓縮包中,供你下載。 # 環境 請你先到 這個網址 下載本教程配套的壓縮包。

下載後解壓,你會在生成的目錄裏面看到如下4個文件。

下文中,咱們會把這個目錄稱爲「演示目錄」。

請必定注意記好它的位置哦。

要裝Python,最簡便辦法是安裝Anaconda套裝。

請到 這個網址 下載Anaconda的最新版本。

請選擇左側的 Python 3.6 版本下載安裝。

若是你須要具體的步驟指導,或者想知道Windows平臺如何安裝並運行Anaconda命令,請參考我爲你準備的 視頻教程

打開終端,用cd命令進入演示目錄。若是你不瞭解具體使用方法,也能夠參考 視頻教程 。 咱們須要使用許多軟件包。若是每個都手動安裝,會很是麻煩。

我幫你作了個虛擬環境的配置文件,叫作environment.yaml ,也放在演示目錄中。

請你首先執行如下命令:

conda env create -f environment.yaml

這樣,所需的軟件包就一次性安裝完畢了。

以後執行,

source activate datapy3

進入這個虛擬環境。

注意必定要執行下面這句:

python -m ipykernel install --user --name=datapy3

只有這樣,當前的Python環境纔會做爲核心(kernel)在系統中註冊。 確認你的電腦上已經安裝了 Google Chrome 瀏覽器。若是沒有安裝請到這裏 下載 安裝。

以後,在演示目錄中,咱們執行:

jupyter notebook

Google Chrome會開啓,並啓動 Jupyter 筆記本界面:

你能夠直接點擊文件列表中的demo.ipynb文件,能夠看到本教程的所有示例代碼。

你能夠一邊看教程的講解,一邊依次執行這些代碼。

可是,我建議的方法,是回到主界面下,新建一個新的空白 Python 3 (顯示名稱爲datapy3的那個)筆記本。

請跟着教程,一個個字符輸入相應的內容。這能夠幫助你更爲深入地理解代碼的含義,更高效地把技能內化。

準備工做結束,下面咱們開始正式輸入代碼。

代碼

咱們讀入數據框處理工具pandas。

import pandas as pd
複製代碼

利用pandas的csv讀取功能,把數據讀入。

注意爲了與Excel和系統環境設置的兼容性,該csv數據文件採用的編碼爲GB18030。這裏須要顯式指定,不然會報錯。

df = pd.read_csv('data.csv', encoding='gb18030')
複製代碼

咱們看看讀入是否正確。

df.head()
複製代碼

前5行內容以下:

看看數據框總體的形狀是怎麼樣的:

df.shape
複製代碼
(2000, 2)
複製代碼

咱們的數據一共2000行,2列。完整讀入。

咱們並不許備把情感分析的結果分紅4個類別。咱們只打算分紅正向和負向。

這裏咱們用一個無名函數來把評星數量>3的,當成正向情感,取值爲1;反之視做負向情感,取值爲0。

def make_label(df):
    df["sentiment"] = df["star"].apply(lambda x: 1 if x>3 else 0)
複製代碼

編制好函數以後,咱們實際運行在數據框上面。

make_label(df)
複製代碼

看看結果:

df.head()
複製代碼

從前5行看來,情感取值就是根據咱們設定的規則,從評星數量轉化而來。

下面咱們把特徵和標籤拆開。

X = df[['comment']]
y = df.sentiment
複製代碼

X 是咱們的所有特徵。由於咱們只用文本判斷情感,因此X實際上只有1列。

X.shape
複製代碼
(2000, 1)
複製代碼

而y是對應的標記數據。它也是隻有1列。

y.shape
複製代碼
(2000,)
複製代碼

咱們來看看 X 的前幾行數據。

X.head()
複製代碼

注意這裏評論數據仍是原始信息。詞語沒有進行拆分。

爲了作特徵向量化,下面咱們利用結巴分詞工具來拆分句子爲詞語。

import jieba
複製代碼

咱們創建一個輔助函數,把結巴分詞的結果用空格鏈接。

這樣分詞後的結果就如同一個英文句子同樣,單次之間依靠空格分割。

def chinese_word_cut(mytext):
    return " ".join(jieba.cut(mytext))
複製代碼

有了這個函數,咱們就可使用 apply 命令,把每一行的評論數據都進行分詞。

X['cutted_comment'] = X.comment.apply(chinese_word_cut)
複製代碼

咱們看看分詞後的效果:

X.cutted_comment[:5]
複製代碼

單詞和標點之間都用空格分割,符合咱們的要求。

下面就是機器學習的常規步驟了:咱們須要把數據分紅訓練集和測試集。

爲何要拆分數據集合?

在《貸仍是不貸:如何用Python和機器學習幫你決策?》一文中,我已解釋過,這裏複習一下:

若是期末考試以前,老師給你一套試題和答案,你把它背了下來。而後考試的時候,只是從那套試題裏面抽取一部分考。你憑藉超人的記憶力得到了100分。請問你學會了這門課的知識了嗎?不知道若是給你新的題目,你會不會作呢?答案仍是不知道。因此考試題目須要和複習題目有區別。

一樣的道理,假設我們的模型只在某個數據集上訓練,準確度很是高,可是歷來沒有見過其餘新數據,那麼它面對新數據表現如何呢?

你內心也沒底吧?

因此咱們須要把數據集拆開,只在訓練集上訓練。保留測試集先不用,做爲考試題,看模型通過訓練後的分類效果。

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)
複製代碼

這裏,咱們設定了 random_state 取值,這是爲了在不一樣環境中,保證隨機數取值一致,以便驗證我們模型的實際效果。

咱們看看此時的 X_train 數據集形狀。

X_train.shape
複製代碼
(1500, 2)
複製代碼

可見,在默認模式下,train_test_split函數對訓練集和測試集的劃分比例爲 3:1。

咱們檢驗一下其餘3個集合看看:

y_train.shape
複製代碼
(1500,)
複製代碼
X_test.shape
複製代碼
(500, 2)
複製代碼
y_test.shape
複製代碼
(500,)
複製代碼

一樣都正確無誤。

下面咱們就要處理中文停用詞了。

咱們編寫一個函數,從中文停用詞表裏面,把停用詞做爲列表格式保存並返回:

def get_custom_stopwords(stop_words_file):
    with open(stop_words_file) as f:
        stopwords = f.read()
    stopwords_list = stopwords.split('\n')
    custom_stopwords_list = [i for i in stopwords_list]
    return custom_stopwords_list
複製代碼

咱們指定使用的停用詞表,爲咱們已經下載保存好的哈工大停用詞表文件。

stop_words_file = "stopwordsHIT.txt"
stopwords = get_custom_stopwords(stop_words_file)
複製代碼

看看咱們的停用詞列表的後10項:

stopwords[-10:]
複製代碼

這些大部分都是語氣助詞,做爲停用詞去除掉,不會影響到語句的實質含義。

下面咱們就要嘗試對分詞後的中文語句作向量化了。

咱們讀入CountVectorizer向量化工具,它依據詞語出現頻率轉化向量。

from sklearn.feature_extraction.text import CountVectorizer
複製代碼

咱們創建一個CountVectorizer()的實例,起名叫作vect。

注意這裏爲了說明停用詞的做用。咱們先使用默認參數創建vect。

vect = CountVectorizer()
複製代碼

而後咱們用向量化工具轉換已經分詞的訓練集語句,而且將其轉化爲一個數據框,起名爲term_matrix

term_matrix = pd.DataFrame(vect.fit_transform(X_train.cutted_comment).toarray(), columns=vect.get_feature_names())
複製代碼

咱們看看term_matrix的前5行:

term_matrix.head()
複製代碼

咱們注意到,特徵詞語五花八門,特別是不少數字都被看成特徵放在了這裏。

term_matrix的形狀以下:

term_matrix.shape
複製代碼
(1500, 7305)
複製代碼

行數沒錯,列數就是特徵個數,有7305個。

下面咱們測試一下,加上停用詞去除功能,特徵向量的轉化結果會有什麼變化。

vect = CountVectorizer(stop_words=frozenset(stopwords))
複製代碼

下面的語句跟剛纔同樣:

term_matrix = pd.DataFrame(vect.fit_transform(X_train.cutted_comment).toarray(), columns=vect.get_feature_names())
複製代碼
term_matrix.head()
複製代碼

能夠看到,此時特徵個數從剛纔的7305個,下降爲7144個。咱們沒有調整任何其餘的參數,所以減小的161個特徵,就是出如今停用詞表中的單詞。

可是,這種停用詞表的寫法,依然會漏掉很多漏網之魚。

首先就是前面那一堆顯眼的數字。它們在此處做爲特徵毫無道理。若是沒有單位,沒有上下文,數字都是沒有意義的。

所以咱們須要設定,數字不能做爲特徵。

在Python裏面,咱們能夠設定token_pattern來完成這個目標。

這一部分須要用到正則表達式的知識,咱們這裏沒法詳細展開了。

但若是你只是須要去掉數字做爲特徵的話,按照我這樣寫,就能夠了。

另外一個問題在於,咱們看到這個矩陣,其實是個很是稀疏的矩陣,其中大部分的取值都是0.

這沒有關係,也很正常。

畢竟大部分評論語句當中只有幾個到幾十個詞語而已。7000多的特徵,單個語句顯然是覆蓋不過來的。

然而,有些詞彙做爲特徵,就值得注意了。

首先是那些過於廣泛的詞彙。儘管咱們用了停用詞表,可是不免有些詞彙幾乎出如今每一句評論裏。什麼叫作特徵?特徵就是能夠把一個事物與其餘事物區別開的屬性。

假設讓你描述今天見到的印象最深入的人。你怎麼描述?

我看見他穿着小丑的衣服,在繁華的商業街踩高蹺,一邊走還一邊拋球,和路人打招呼。

仍是……

我看見他有兩隻眼睛,一隻鼻子。

後者絕對不算是好的特徵描述,由於難以把你要描述的個體區分出來。

物極必反,那些過於特殊的詞彙,其實也不該該保留。由於你瞭解了這個特徵以後,對你的模型處理新的語句情感判斷,幾乎都用不上。

這就如同你跟着神仙學了屠龍之術,然而以後一生也沒有見過龍……

因此,以下面兩個代碼段所示,咱們一共多設置了3層特徵詞彙過濾。

max_df = 0.8 # 在超過這一比例的文檔中出現的關鍵詞(過於平凡),去除掉。
min_df = 3 # 在低於這一數量的文檔中出現的關鍵詞(過於獨特),去除掉。
複製代碼
vect = CountVectorizer(max_df = max_df,
                       min_df = min_df,
                       token_pattern=u'(?u)\\b[^\\d\\W]\\w+\\b',
                       stop_words=frozenset(stopwords))
複製代碼

這時候,再運行咱們以前的語句,看看效果。

term_matrix = pd.DataFrame(vect.fit_transform(X_train.cutted_comment).toarray(), columns=vect.get_feature_names())
複製代碼
term_matrix.head()
複製代碼

能夠看到,那些數字全都不見了。特徵數量從單一詞表法去除停用詞以後的7144個,變成了1864個。

你可能會以爲,太惋惜了吧?好容易分出來的詞,就這麼扔了?

要知道,特徵多,毫不必定是好事兒。

尤爲是噪聲大量混入時,會顯著影響你模型的效能。

好了,評論數據訓練集已經特徵向量化了。下面咱們要利用生成的特徵矩陣來訓練模型了。

咱們的分類模型,採用樸素貝葉斯(Multinomial naive bayes)。

from sklearn.naive_bayes import MultinomialNB
nb = MultinomialNB()
複製代碼

注意咱們的數據處理流程是這樣的:

  1. 特徵向量化;
  2. 樸素貝葉斯分類。

若是每次修改一個參數,或者換用測試集,咱們都須要從新運行這麼多的函數,確定是一件效率不高,且使人頭疼的事兒。並且只要一複雜,出現錯誤的概率就會增長。

幸虧,Scikit-learn給咱們提供了一個功能,叫作管道(pipeline),能夠方便解決這個問題。

它能夠幫助咱們,把這些順序工做鏈接起來,隱藏其中的功能順序關聯,從外部一次調用,就能完成順序定義的所有工做。

使用很簡單,咱們就把 vect 和 nb 串聯起來,叫作pipe。

from sklearn.pipeline import make_pipeline
pipe = make_pipeline(vect, nb)
複製代碼

看看它都包含什麼步驟:

pipe.steps
複製代碼

看,咱們剛纔作的工做,都在管道里面了。咱們能夠把管道當成一個總體模型來調用。

下面一行語句,就能夠把未經特徵向量化的訓練集內容輸入,作交叉驗證,算出模型分類準確率的均值。

from sklearn.cross_validation import cross_val_score
cross_val_score(pipe, X_train.cutted_comment, y_train, cv=5, scoring='accuracy').mean()
複製代碼

我們的模型在訓練中的準確率如何呢?

0.820687244673089
複製代碼

這個結果,仍是不錯的。

回憶一下,整體的正向和負向情感,各佔了數據集的一半。

若是咱們創建一個「笨模型」(dummy model),即全部的評論,都當成正向(或者負向)情感,準確率多少?

對,50%。

目前的模型準確率,遠遠超出這個數值。超出的這30%多,其實就是評論信息爲模型帶來的肯定性。

可是,不要忘了,咱們不能光拿訓練集來講事兒,對吧?下面我們給模型來個考試。

咱們用訓練集,把模型擬合出來。

pipe.fit(X_train.cutted_comment, y_train)
複製代碼

而後,咱們在測試集上,對情感分類標記進行預測。

pipe.predict(X_test.cutted_comment)
複製代碼

這一大串0和1,你看得是否眼花繚亂?

不要緊,scikit-learn給咱們提供了很是多的模型性能測度工具。

咱們先把預測結果保存到y_pred

y_pred = pipe.predict(X_test.cutted_comment)
複製代碼

讀入 scikit-learn 的測量工具集。

from sklearn import metrics
複製代碼

咱們先來看看測試準確率:

metrics.accuracy_score(y_test, y_pred)
複製代碼
0.86
複製代碼

這個結果是否是讓你很吃驚?沒錯,模型面對沒有見到的數據,竟然有如此高的情感分類準確性。

對於分類問題,光看準確率有些不全面,我們來看看混淆矩陣。

metrics.confusion_matrix(y_test, y_pred)
複製代碼
array([[194,  43],
       [ 27, 236]])
複製代碼

混淆矩陣中的4個數字,分別表明:

  • TP: 原本是正向,預測也是正向的;
  • FP: 原本是負向,預測倒是正向的;
  • FN: 原本是正向,預測倒是負向的;
  • TN: 原本是負向,預測也是負向的。

下面這張圖(來自 https://goo.gl/5cYGZd )應該能讓你更爲清晰理解混淆矩陣的含義:

寫到這兒,你大概能明白我們模型的性能了。

可是總不能只把我們訓練出的模型和無腦「笨模型」去對比吧?這也太不公平了!

下面,咱們把老朋友 SnowNLP 呼喚出來,作個對比。

若是你把它給忘了,請複習《如何用Python作情感分析?

from snownlp import SnowNLP
def get_sentiment(text):
    return SnowNLP(text).sentiments
複製代碼

咱們利用測試集評論原始數據,讓 SnowNLP 跑一遍,得到結果。

y_pred_snownlp = X_test.comment.apply(get_sentiment)
複製代碼

注意這裏有個小問題。 SnowNLP 生成的結果,不是0和1,而是0到1之間的小數。因此咱們須要作一步轉換,把0.5以上的結果看成正向,其他看成負向。

y_pred_snownlp_normalized = y_pred_snownlp.apply(lambda x: 1 if x>0.5 else 0)
複製代碼

看看轉換後的前5條 SnowNLP 預測結果:

y_pred_snownlp_normalized[:5]
複製代碼

好了,符合咱們的要求。

下面咱們先看模型分類準確率:

metrics.accuracy_score(y_test, y_pred_snownlp_normalized)
複製代碼
0.77
複製代碼

與之對比,我們的測試集分類準確率,但是0.86哦。

咱們再來看看混淆矩陣。

metrics.confusion_matrix(y_test, y_pred_snownlp_normalized)
複製代碼
array([[189,  48],
       [ 67, 196]])
複製代碼

對比的結果,是 TP 和 TN 兩項上,我們的模型判斷正確數量,都要超出 SnowNLP。

小結

回顧一下,本文介紹瞭如下知識點:

  1. 如何用一袋子詞(bag of words)模型將天然語言語句向量化,造成特徵矩陣;
  2. 如何利用停用詞表、詞頻閾值和標記模式(token pattern)移除不想幹的僞特徵詞彙,下降模型複雜度。
  3. 如何選用合適的機器學習分類模型,對詞語特徵矩陣作出分類;
  4. 如何用管道模式,歸併和簡化機器學習步驟流程;
  5. 如何選擇合適的性能測度工具,對模型的效能進行評估和對比。

但願這些內容可以幫助你更高效地處理中文文本情感分類工做。

討論

你以前用機器學習作過中文情感分類項目嗎?你是如何去除停用詞的?你使用的分類模型是哪一個?得到的準確率怎麼樣?歡迎留言,把你的經驗和思考分享給你們,咱們一塊兒交流討論。

喜歡請點贊。還能夠微信關注和置頂個人公衆號「玉樹芝蘭」(nkwangshuyi)

若是你對數據科學感興趣,不妨閱讀個人系列教程索引貼《如何高效入門數據科學?》,裏面還有更多的有趣問題及解法。

相關文章
相關標籤/搜索