信息抽取--新词提取

(纯属为了记录自己学习的点滴过程,引用资料都附在参考列表)

1 基本概念

什么是新词(是什么)
新词是一个相对的概念,每个人的标准都不一样,所以我们这里定义: 词典之外的词语(OOV)称作新词。

为什么要进行新词提取(为什么)
新词的提取对中文分词而言具有重要的意义,因为语料库的标注成本很高。那么如何修订领域词典呢,此时,无监督的新词提取算法就体现了现实意义。

怎么进行新词提取(怎么办)

  • 提取出大量文本(生语料)中的词语,无论新旧。
  • 用词典过滤掉已有的词语,于是得到新词。

步骤 2 很容易,关键是步骤 1,如何无监督的提取出文本中的单词。给定一段文本,随机取一个片段,如果这个片段左右的搭配很丰富,并且片段内部成分搭配很固定,则可以认为这是一个词。将这样的片段筛选出来,按照频次由高到低排序,排在前面的有很高概率是词。

如果文本足够大,再用通用的词典过滤掉“旧词”,就可以得到“新词”。

片段外部左右搭配的丰富程度(越丰富说明不确定性越大,这样可以引进熵这个概念进行度量了),可以用信息熵来衡量,而片段内部搭配的固定程度可以用子序列的互信息来衡量。

信息熵
在信息论中,信息熵( entropy )指的是某条消息所含的信息量。它度量一个随机事件的不确定性,熵越大,不确定性越大,反之亦然。
对于随机变量 X X X,信息熵定义如下:
H ( x ) = − ∫ x p ( x ) log ⁡ p ( x ) d x H(x) = -\int_x p(x) \log p(x) dx H(x)=xp(x)logp(x)dx

  • 举一个简单的例子

给定字符串 S 作为词语备选,X 定义为该字符串左边可能出现的字符(左邻字),则称 H(X) 为 S 的左信息熵,类似的,定义右信息熵 H(Y),例如下列句子:

两只蝴蝶飞啊飞
这些蝴蝶飞走了

那么对于字符串蝴蝶,它的左信息熵为1,而右信息熵为0。因为生语料库中蝴蝶的右邻字一定是飞。假如我们再收集一些句子,比如“蝴蝶效应”“蝴蝶蜕变”之类,就会观察到右信息熵会增大不少。

互信息(Mutual Information)
度量两个随机变量 X , Y X,Y X,Y的相关程度,用狭隘的大白话理解随机变量的相关性,就是随机变量越相关,二者同时发生或者互斥的可能性越大,数学定义如下:
I ( X ; Y ) = E p ( 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 ) = 1 p(X, Y) = 1 p(X,Y)=1,此时互信息退化为:
I ( X ; Y ) = log ⁡ p ( x , y ) p ( x ) p ( y ) = log ⁡ p ( h u , d i e ) p ( h u ) p ( d i e ) = log ⁡ 1 / 8 1 8 × 1 8 = 3 I(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×811/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 解决思路

原理上参考了下面两篇论文:

  1. 丁溪源 ,《基于大规模语料的中文新词抽取算法的设计与实现》;
  2. Matrix67的博文,《互联网时代的社会语言学:基于SNS的文本数据挖掘》,这哥们也很有意思,北大文科生,喜欢研究有趣的数学;

实现上参考了github:

  1. https://github.com/Moonshile/ChineseWordSegmentation

4 实现

# -*- coding:utf-8 -*-

from pyhanlp import *
from tests.test_utility import ensure_data

HLM_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 参考文献

  1. 何晗《自然语言处理入门》;
  2. 宗成庆《统计自然语言处理》;
  3. 李航《统计学习方法》;

6 需要解决的问题

  1. 阅读“解决思路”中的论文及代码;
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值