NLP:FastText

FastText

  fastText是facebook在2016年提出的一個文本分類算法,是一個有監督模型,其簡單高效,速度快,在工業界被廣泛的使用。在學術界,可以作爲baseline的一個文本分類模型。

原理

  FastText結構同CBOW的結構很像,但是FastText的輸出是對一個文本或句子的分類,而不再是中間詞根。FastText對於輸入的每個x,經過一個轉換矩陣A(本質是一個lookup表,關於這一點可以看我關於skip-gram和cbow的blog),得到對應的詞向量v,所有N個向量求和取平均,平均值經過矩陣B映射到預先設定好的n個類別,經過softmax就得到了概率,公式表示和示意圖如下:
softmax(BNn=1N(Axn))softmax\Big(\frac{B}{N}\sum_{n=1}^{N} (Ax_n)\Big)

xnx_n表示文檔的輸入特徵,A,B是權值矩陣。

  FastText有兩個重要優化,分別是Hierarchical Softmax、N-gram,但這兩個優化方法並不是FastText獨有的,Hierarchical Softmax可以看我的另一篇blog,N-gram就是連續考慮n個詞(或字符),如果只有一個詞(或字符)就是unigram(1-gram),考慮兩個連續詞(或字符)就是bigram(2-gram),考慮三個連續詞(或字符)就是3-gram,對於一個連續的句子,對詞級別和字符級別的bigram實例如下:

原始句子:我來到達觀數據參觀
分詞後:我 來到 達觀數據 參觀

字符級別bigram:我來 來到 到達 達觀 觀數 數據 據參 參觀
詞級別bigram:我/來到 來到/達觀數據 達觀數據/參觀

在上圖中我用黃字着重標出來了,FastText的輸入的每個xx都是ngram,這樣做能夠保證更加準確的獲取局部信息,同時論文指出,這樣做的效果同考慮所有詞的相互順序的效果類似。

Bag of words is invariant to word order but taking explicitly this order into account is often computationally very expensive. Instead, we use a bag of n-grams as additional features to capture some partial information about the local word order. This is very efficient in practice while achieving comparable results to methods that explicitly use the order

  同時由於FastText在平均前的工作相互獨立,所以可以利用多線程進行操作,在pypi的FastText庫中,默認利用的是12線程。

實戰

  這裏直接利用python的FastText庫,可以直接利用pip安裝:

pip install FastText

分類任務

  以真假新聞分辨爲例,給定一段新聞摘要,利用FastText進行分類,真新聞標記爲0,假新聞標記爲1,訓練集train_data.csv實例如下,前綴"__label__\_\_label\_\_“是一個標識,讓FastText知道這是這一特徵是標籤,那麼問題來了,爲什麼不規定第一個空格之前的是標籤呢?這是因爲標籤可能不止一個,每個標籤都要加上”__label__\_\_label\_\_"前綴。標籤後的數據經過了分詞處理,分詞之間通過空格分隔。這裏展示的是對原始數據直接分詞的結果,我並沒用進行類似刪掉標點符號,去停用詞的處理。

__label__1 【 傳 深圳 房企 老闆 在 澳門 賭輸 價值 百億 大樓 】 據 媒體報道 , 網友 爆料 稱 深圳 房企京基 集團 董事長 陳華 在 澳門 賭博 輸掉 了 估值 百億 的 深圳 地標 — — 京基 100 大廈 的 控股權 , 現該 大廈 正辦 過戶 手續 。 目前 , 京基 方面 未 對 傳聞 作出 迴應 。 ...                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     
__label__1 楊瀾 : 雖然 我入 了 美國 籍 , 但 我 出身 於 中國 , 所以 從 原產地 角度 而言 , 我 不 出席 美國 兩會 而 出席 中國 的 兩會 是 “ 天經地義 ” 。 楊瀾 的 荒唐 邏輯 , 實在 匪夷所思 。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
__label__1 【 《 背影 》 因 違反 交規 被 逐出 教材 ? 】 南京大學中文系 教授 問 學生 , 從 小學 到 高中 , 難道 沒 一篇 課文 感動 你 ? 如 朱自清 《 背影 》 。 一 學生 答 , 《 背影 》 早 從 課本上 撤掉 了 。 爲什麼 , 學生 答 : “ 違反 交通規則 ” 。 文中 父親 跳 下 站臺 、 穿過 鐵道 到 對面 給 兒子 買 橘子 , 是 違反 交規 的 ...                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
__label__0 【 她們 登上 警車 尬 舞 後來 被 警察 """" 團滅 """" 了 】 7 月 10 日 凌晨 , 貴州 都勻市 4 名 女孩 在 酒吧 喝完 酒 , 爬 上 路邊 警車 尬 舞 。 當天 下午 , 4 名 女孩 被 警方 抓獲 。 4 人 因涉嫌 尋釁滋事 被行 拘 8 日 , 由於 不滿 18 週歲 且 是 初次 違反 治安管理 處罰法 , 不 執行 處罰 , 警方 對 其 進行 了 批評 , 令 監護人 帶回家 嚴加管教

  測試集數據test_data.csv同train_data.csv格式相同。如果模型訓練好後,我們想直接調用predict方法判斷一個句子的類別,這個句子首先應該經過了分詞,然後把該句子存成字符串或者字符串數組,格式如下,這是一個一維數組。

['幫轉 請 叫 我 小 B 龜 : Mico 是 中美 混血 男孩 , 3 週歲 , 身高 1 米左右 , 偏瘦 , 寸頭 , 離開 時 身穿 綠色 棉布 大衣 、 深藍色 褲子 、 咖色 皮鞋 , 能 說 簡單 的 中文 及 英文 。 於 1 月 7 日 16 : 33 分 左右 , 在 廈門 愛綠 雙語 幼兒園 門口 育秀 路段 ( 大潤發 ) 被 搶走 , 至今 下落 未 明 , 媽媽 已近 崩潰 , 望 知情者 提供線索 , 我 是 他 媽媽 的 朋友 , 求 擴散 !', 
'【 海航 允許 攜帶 寵物 進入 客艙 統一 收費 800 元 】 近日 , 海南 航空 試行 “ 客艙 運輸 寵物 ” 產品 服務 , 要求 爲 一般 家庭 馴養 的 貓 、 狗 , 需 6 個 月 以上 , 健康 , 未 懷孕 , 未 在 48 小時 內 分娩 ; 旅客 需爲 寵物 佩戴 口套 、 穿戴 紙尿褲 , 並 全程 將 其 置於 寵物 箱中 , 不得 餵食 。 每 只 收費 800 元 。 其他 乘客 如 不想 挨着 寵物 , 可 申請 調換 座位 。 | 海航 : 寵物 ...', 
'【 城管 給 賣菜 老太 打傘 老太 臨別時 道謝 】 “ 這樣 的 城管 多 幾個 還 行 。 ” 9 月 4 日 開始 , 一張 “ 城管 給 小販 撐傘 ” 的 照片 在 朋友圈 瘋傳 。 照片 中 , 一位 城管 模樣 的 男子 左手 提 着 一個 水杯 , 右手 舉着 一把 紅花 雨傘 。 傘下 , 一個 身體 佝僂 的 老太太 正在 收拾 擺在 地上 的 蔬菜 。 via 重慶晚報 | 重慶 城管 給 ...']

  具體代碼如下:

import fasttext

# 訓練模型,具體參數可以看blog最後引用文獻部分,列出的官網網址
model = fasttext.train_supervised(input="./train_data.csv", epoch=25, wordNgrams=2)

# 測試,k表示考慮top k,由於是二分類,所以k=1
print(model.test("/home/mec/liangdongtian/fake_news_detection/data/test_data.csv", k=1))
# 輸出:(7695, 0.9815464587394412, 0.9815464587394412),表示共有7695條數據,準確率召回率均是0.982

# 推斷,用例是上面給的一維測試數組
print(model.predict(data))
# 輸出:([['__label__1'], ['__label__0'], ['__label__0']], array([[0.99721408],[0.99995029], [0.99978548]]))
# 輸出解釋:對於三個新聞摘要,模型認爲第一個是假的,後兩個是真的,實際也確實如此;後面給的數組表示判斷的概率,我們可以通過下面代碼輸出看出,和另一個label是互補的。
print(model.predict(tmp, k=2))
# 輸出:([['__label__1', '__label__0'], ['__label__0', '__label__1'], ['__label__0', '__label__1']], 
       array([[9.97214079e-01, 2.80591869e-03],
       [9.99950290e-01, 6.97360520e-05],
       [9.99785483e-01, 2.34513165e-04]]))

# 保存模型
model.save_model("fake_news_detected_model.bin")

# 讀取模型
model2 = fasttext.load_model("fake_news_detected_model.bin")

詞向量表示

  FastText除了可以對文檔進行分類,還可以執行CBOW和Skip-gram來學習詞向量表示:

import fasttext

# 詞向量表示
model = fasttext.train_unsupervised(input="./train_data.csv", epoch=1, lr=0.5, minn=1, maxn=3, model='cbow')

# 獲取詞向量:
model.get_word_vector("奶奶")
# 輸出:
"""
array([ 102059.4   ,  -68441.32  ,  304470.2   ,  311754.75  ,
       -230531.8   ,   25913.648 , -182974.78  , -190766.12  ,
       -644414.1   , -132576.38  ,  108882.25  , -332925.12  ,
         12349.384 , -463407.5   , -232429.98  , -185747.69  ,
         80663.14  ,   53180.64  ,  -18819.648 , -410663.25  ,
       -398879.12  ,   96190.484 ,  341425.25  , -256364.27  ,
         62487.023 ,   41527.76  ,  375745.1   ,  -79907.46  ,
       -112595.57  , -504839.22  ,  115009.78  ,  213641.34  ,
       -193202.36  ,   89021.52  , -162374.52  , -533262.1   ,
         33116.242 ,  -39390.29  ,  416710.5   ,  163098.66  ,
       -410393.94  ,  625811.7   ,   17629.508 , -312635.75  ,
       -259025.39  , -113679.305 , -347809.4   ,  -37010.855 ,
          5223.478 ,  249829.23  , -453246.5   ,   65942.984 ,
        180671.67  , -257055.95  ,  209196.62  ,  158813.66  ,
         -6870.5166, -177275.7   ,   81687.23  , -440451.38  ,
          9726.117 , -367380.03  ,  136241.1   , -275263.84  ,
       -116055.7   ,  199297.5   ,  277341.53  ,   -3254.2344,
       -357637.62  ,  167770.25  ,   49575.13  , -199634.33  ,
        -27568.742 ,  210491.83  ,  287567.53  , -174878.77  ,
       -117145.234 , -493248.25  , -128043.22  ,  258058.11  ,
        -50932.105 , -398822.56  , -164988.56  , -444483.72  ,
         63238.523 ,  215993.94  , -288719.78  ,   75995.94  ,
       -139015.2   ,  -56318.47  , -212303.69  , -176017.08  ,
       -239202.4   ,  118557.68  ,  205427.66  , -133535.67  ,
         61893.58  ,  -22306.602 ,  -90023.414 , -298827.75  ],
      dtype=float32)
"""

# facebook的實現是有get_nearest_neighbors()這一方法的,獲取輸入詞語意相近的詞,但是可惜pypi裏包含的FastText沒有實現這個,不然可以看看FastText模型學習到的語意相關詞

參考文獻:

論文地址:https://arxiv.org/pdf/1607.01759.pdf

FastText官方文檔:https://fasttext.cc/docs/en/supervised-tutorial.html

FastText在pypi的介紹:https://pypi.org/project/fasttext/

fastText原理和文本分類實戰,看這一篇就夠了:https://blog.csdn.net/feilong_csdn/article/details/88655927

fastText原理及實踐:https://blog.csdn.net/John_xyz/article/details/79421618

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章