信息抽取--新词提取
(純屬為了記錄自己學習的點滴過程,引用資料都附在參考列表)
1 基本概念
什么是新詞(是什么)
新詞是一個相對的概念,每個人的標準都不一樣,所以我們這里定義: 詞典之外的詞語(OOV)稱作新詞。
為什么要進行新詞提取(為什么)
新詞的提取對中文分詞而言具有重要的意義,因為語料庫的標注成本很高。那么如何修訂領域詞典呢,此時,無監督的新詞提取算法就體現了現實意義。
怎么進行新詞提取(怎么辦)
- 提取出大量文本(生語料)中的詞語,無論新舊。
- 用詞典過濾掉已有的詞語,于是得到新詞。
步驟 2 很容易,關鍵是步驟 1,如何無監督的提取出文本中的單詞。給定一段文本,隨機取一個片段,如果這個片段左右的搭配很豐富,并且片段內部成分搭配很固定,則可以認為這是一個詞。將這樣的片段篩選出來,按照頻次由高到低排序,排在前面的有很高概率是詞。
如果文本足夠大,再用通用的詞典過濾掉“舊詞”,就可以得到“新詞”。
片段外部左右搭配的豐富程度(越豐富說明不確定性越大,這樣可以引進熵這個概念進行度量了),可以用信息熵來衡量,而片段內部搭配的固定程度可以用子序列的互信息來衡量。
信息熵
在信息論中,信息熵( entropy )指的是某條消息所含的信息量。它度量一個隨機事件的不確定性,熵越大,不確定性越大,反之亦然。
對于隨機變量XXX,信息熵定義如下:
H(x)=?∫xp(x)log?p(x)dxH(x) = -\int_x p(x) \log p(x) dxH(x)=?∫x?p(x)logp(x)dx
- 舉一個簡單的例子
給定字符串 S 作為詞語備選,X 定義為該字符串左邊可能出現的字符(左鄰字),則稱 H(X) 為 S 的左信息熵,類似的,定義右信息熵 H(Y),例如下列句子:
兩只蝴蝶飛啊飛
這些蝴蝶飛走了
那么對于字符串蝴蝶,它的左信息熵為1,而右信息熵為0。因為生語料庫中蝴蝶的右鄰字一定是飛。假如我們再收集一些句子,比如“蝴蝶效應”“蝴蝶蛻變”之類,就會觀察到右信息熵會增大不少。
互信息(Mutual Information)
度量兩個隨機變量X,YX,YX,Y的相關程度,用狹隘的大白話理解隨機變量的相關性,就是隨機變量越相關,二者同時發生或者互斥的可能性越大,數學定義如下:
I(X;Y)=Ep(x,y)log?p(x,y)p(x)p(y)I(X; Y) = E_{p(x,y)} \log \frac{p(x,y)}{p(x)p(y)} I(X;Y)=Ep(x,y)?logp(x)p(y)p(x,y)?
- 還是上面“蝴蝶”的例子:
X=字符串前綴,Y=字符串后綴X = 字符串前綴,Y=字符串后綴X=字符串前綴,Y=字符串后綴,分析“蝴蝶”🦋這個字符串,
此時兩者的聯合分布只有一個取值“蝴蝶”,即p(X,Y)=1p(X, Y) = 1p(X,Y)=1,此時互信息退化為:
I(X;Y)=log?p(x,y)p(x)p(y)=log?p(hu,die)p(hu)p(die)=log?1/818×18=3I(X; Y) = \log \frac{p(x,y)}{p(x)p(y)}\\ = \log \frac{p(hu,die)}{p(hu)p(die)}\\ = \log \frac{1/8}{\frac{1}{8} \times \frac{1}{8}}\\ = 3\\ I(X;Y)=logp(x)p(y)p(x,y)?=logp(hu)p(die)p(hu,die)?=log81?×81?1/8?=3
在上面的計算中,p(x),p(y)p(x),p(y)p(x),p(y)的計算都沒有問題,但是在計算p(x,y)p(x,y)p(x,y)時,總語料總詞頻是未知的,但是總詞頻不影響互信息的大小排名,我們在最后抉擇時使用的是互信息排名。
高內聚低耦合
這是一種解決問題非常牛*的思路;
上面的“信息熵”、“互信息”提取新詞分別體現的就是高內聚、低耦合;
軟件工程設計要體現高內聚、低耦合原則;
主成分分析的意義高內聚、低耦合原則;
似乎人類善于把一個問題進行轉化,特征轉化后可以分解成一些盡量互不相關模塊,這些模塊似乎是事物的本質。
nlp后續還會繼續使用這種思想。。。
2 問題
提取四大名著和微博中的熱詞。
3 解決思路
原理上參考了下面兩篇論文:
實現上參考了github:
4 實現
# -*- coding:utf-8 -*-from pyhanlp import * from tests.test_utility import ensure_dataHLM_PATH = ensure_data("紅樓夢.txt", "http://file.hankcs.com/corpus/紅樓夢.zip") XYJ_PATH = ensure_data("西游記.txt", "http://file.hankcs.com/corpus/西游記.zip") SHZ_PATH = ensure_data("水滸傳.txt", "http://file.hankcs.com/corpus/水滸傳.zip") SAN_PATH = ensure_data("三國演義.txt", "http://file.hankcs.com/corpus/三國演義.zip") WEIBO_PATH = ensure_data("weibo-classification", "http://file.hankcs.com/corpus/weibo-classification.zip")def test_weibo():for folder in os.listdir(WEIBO_PATH):print(folder)big_text = ""for file in os.listdir(os.path.join(WEIBO_PATH, folder)):with open(os.path.join(WEIBO_PATH, folder, file), encoding='utf-8') as src:big_text += "".join(src.readlines())word_info_list = HanLP.extractWords(big_text, 100)print(word_info_list)def extract(corpus):print("%s 熱詞" % corpus)word_info_list = HanLP.extractWords(IOUtil.newBufferedReader(corpus), 100)print(word_info_list)# print("%s 新詞" % corpus)# word_info_list = HanLP.extractWords(IOUtil.newBufferedReader(corpus), 100, True)# print(word_info_list)if __name__ == '__main__':extract(HLM_PATH)extract(XYJ_PATH)extract(SHZ_PATH)extract(SAN_PATH)test_weibo()# 更多參數word_info_list = HanLP.extractWords(IOUtil.newBufferedReader(HLM_PATH), 100, True, 4, 0.0, .5, 100)print(word_info_list)運行結果:
packages/pyhanlp/static/data/test/紅樓夢.txt 熱詞 [什么, 鳳姐, 賈母, 黛玉, 姑娘, 寶釵, 怎么, 丫頭, 如今, 老太太, 賈政, 奶奶, 自己, 賈璉, 平兒, 老爺, 東西, 告訴, 咱們, 姨媽, 薛姨媽, 所以, 探春, 紫鵑, 鴛鴦, 湘云, 如此, 妹妹, 婆子, 賈珍, 李紈, 答應, 尤氏, 晴雯, 媳婦, 屋里, 打發, 劉姥姥, 小丫頭, 林黛玉, 薛蟠, 香菱, 孩子, 姊妹, 到底, 連忙, 明白, 丫鬟, 麝月, 姨娘, 哥哥, 賈蓉, 小廝, 果然, 意思, 周瑞, 怎么樣, 主意, 已經, 越發, 跟前, 瞧瞧, 房中, 喜歡, 賈赦, 惜春, 句話, 雨村, 賈蕓, 吩咐, 況且, 悄悄, 嫂子, 兄弟, 素日, 芳官, 金桂, 賈環, 言語, 雪雁, 時候, 多少, 許多, 嬤嬤, 迎春, 林之孝, 糊涂, 十分, 女孩, 伏侍, 奴才, 預備, 衣服, 請安, 林姑娘, 收拾, 趙姨娘, 鶯兒, 年紀, 父親] /Users/kitty/anaconda3/envs/nlp/lib/python3.6/site-packages/pyhanlp/static/data/test/西游記.txt 熱詞 [行者, 八戒, 師父, 三藏, 大圣, 唐僧, 沙僧, 菩薩, 和尚, 怎么, 妖精, 甚么, 悟空, 國王, 徒弟, 呆子, 聞言, 如何, 今日, 兄弟, 寶貝, 取經, 鐵棒, 認得, 果然, 東土, 性命, 觀看, 神通, 公主, 玉帝, 變作, 哥哥, 門外, 土地, 歡喜, 陛下, 太宗, 貧僧, 金箍, 變做, 爺爺, 模樣, 多少, 十分, 兵器, 袈裟, 怪物, 變化, 手段, 近前, 往西, 唬得, 娘娘, 衣服, 豬八戒, 左右, 仔細, 吩咐, 金箍棒, 師徒們, 曉得, 奈何, 觀音, 安排, 言語, 孫悟空, 釘鈀, 叩頭, 毫毛, 關文, 半空, 五百, 拜佛, 遞與, 妖邪, 筋斗, 汝等, 抬頭, 徑至, 戰兢兢, 許多, 孩兒, 扯住, 齊天大圣, 葫蘆, 皇帝, 收拾, 壁廂, 小的們, 忍不住, 佛祖, 未曾, 玄奘, 往西天, 本事, 造化, 白馬, 求經, 揭諦] /Users/kitty/anaconda3/envs/nlp/lib/python3.6/site-packages/pyhanlp/static/data/test/水滸傳.txt 熱詞 [宋江, 李逵, 武松, 如何, 哥哥, 林沖, 吳用, 頭領, 兄弟, 智深, 太尉, 戴宗, 盧俊義, 梁山泊, 燕青, 先鋒, 好漢, 花榮, 晁蓋, 柴進, 石秀, 王慶, 楊志, 呼延灼, 魯智深, 太公, 秦明, 公孫勝, 張順, 史進, 兄長, 朱仝, 阮小, 知府, 關勝, 張清, 商議, 莊客, 楊雄, 李俊, 性命, 弟兄, 東京, 西門, 怎地, 許多, 隨即, 和尚, 收拾, 甚么, 小嘍羅, 高太尉, 宋公明, 慌忙, 眾頭領, 向前, 樸刀, 時遷, 朝廷, 認得, 雷橫, 樞密, 徐寧, 西門慶, 安排, 喚做, 解珍, 王婆, 員外, 劉唐, 瓊英, 分付, 解寶, 十余, 尋思, 酒店, 大怒, 方臘, 孫立, 董平, 左右, 童貫, 旋風, 高俅, 梁中書, 索超, 喬道清, 吳學究, 必然, 黃信, 長老, 大蟲, 師父, 押司, 傳令, 施恩, 朱貴, 迎接, 城池, 將佐] /Users/kitty/anaconda3/envs/nlp/lib/python3.6/site-packages/pyhanlp/static/data/test/三國演義.txt 熱詞 [玄德, 孔明, 卻說, 司馬, 丞相, 關公, 云長, 荊州, 夏侯, 呂布, 張飛, 諸葛, 商議, 孫權, 魏延, 趙云, 左右, 劉備, 司馬懿, 姜維, 次日, 東吳, 袁紹, 十余, 周瑜, 陛下, 都督, 黃忠, 背后, 太守, 有詩, 孟獲, 先鋒, 鄧艾, 諸葛亮, 張遼, 江東, 奈何, 曹仁, 徐州, 成都, 徐晃, 忽然, 喊聲, 魯肅, 眾官, 祁山, 百姓, 十里, 龐德, 百余, 接應, 劉表, 董卓, 許褚, 分付, 糧草, 許都, 皇叔, 孫策, 文武, 追趕, 五千, 洛陽, 五百, 兄弟, 關興, 星夜, 挺槍, 孫乾, 西川, 子龍, 準備, 袁術, 司馬昭, 劉璋, 曹洪, 張翼, 甘寧, 夏侯淵, 一彪, 英雄, 孟達, 乘勢, 陸遜, 呂蒙, 朝廷, 于禁, 首級, 襄陽, 曹丕, 埋伏, 傳令, 堅守, 投降, 張苞, 遣使, 龐統, 心腹, 郭淮] 動漫 [騰訊, 海賊王, 分享, 作品, 游戲, 世界, 我們, 微博, 火影, 文化, 電影, 視頻, 喜歡, 啦啦, 沒有, 系列, 開始, 轉發, 歡迎, 什么, 可以, 第二, 國際, 公司, 嘉年華, ay, 精彩, 評論, 原創, 官方, 連載, 金龍獎, 自己, 故事, 首屆, 預告, 地址, 希望, 制作, 經典, 關注, 雜志, 播出, 今天, 已經, 學院, 四格, 北京, 爆笑, 電視, 主題, 支持, 陳維東, 武漢, COS, 朋友, 產業, 短片, 目前, 圣誕, 生活, 頒獎, 頻道, 設計, com, 搞笑, 產品, 進行, 英雄, 聯盟, 少女, 將于, 未來, 期精彩, 盛典, 感謝, 即將, 宣傳, 論壇, 工作, 藝術, 內容, 更多, 創意, 那些, 詳情, 獲獎, 期待, 屆中國, 各位, 繼續, 加入, 有限, 文字, 濟公, 推薦, 政府, 消息, 公布, 劇場] 美食 [轉發, 原文, 評論, 火鍋, 餐廳, 微博, 放入, 咖啡, 來自, 分鐘, 即可, 圣誕, 北京, 可以, 做法, 我們, 活動, 今天, 推薦, 洗凈, 套餐, 喜歡, 雞蛋, 什么, 倒入, 巧克力, 分享, 新浪, 歡迎, 地址, 制作, 優惠, 朋友, 蛋糕, 關注, 沒有, 土豆, 免費, 葡萄, 營養, 蘿卜, 團購, 開業, 福州, 時間, 時候, 詳情, 價格, 不錯, 壽司, 少許, 健康, 辣椒, 開始, 適量, 品嘗, 牛排, 生活, 羊肉, 料理, 牛奶, 特色, 翻炒, 口感, 攪拌, 均勻, 享受, 特別, 消費, 廣場, 電話, 拌勻, 機會, 已經, 服務, 葡萄酒, 正宗, 豆腐, 調料, 更多, 排骨, 獲得, 知道, 下午, 麻辣, 自己, 時光, 世界, 花椒, 雞翅, 香蕉, 吃貨, 粉絲, 白糖, 經典, 產品, 香天下, 糯米, 廈門, 撈出] ...- 雖然沒有在古典文學語料上訓練過,但新詞識別模塊依舊可以成功識別出很多詞。
5 參考文獻
6 需要解決的問題
總結
以上是生活随笔為你收集整理的信息抽取--新词提取的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 折半查找法(二分查找法)
- 下一篇: [超详细保姆教程]Python3.8 实