参考资料
主要参考了以下两篇文章:
互联网时代的社会语言学:基于SNS的文本数据挖掘
基于信息熵和互信息的新词识别
分词依据
对于一个给定的文本,从中抽取一个片段,如果这个片段的内部成分搭配稳定,并且左右搭配很丰富,则认为是一个词。将这样的片段抽取出来,按照出现的频率排序,选择排在前面的那些作为我们发现的词语。再进一步通过固有词典过滤掉已经存在的“旧词”,剩下的就是“新词”了。
如何理解“内部成分搭配稳定”和“左右搭配丰富”呢?
假设有2个字符组成的片段“AB”出现在文本中若干次,如果A出现了,B总会紧接着出现,B出现了,A也出现,即A、B总是成对出现,而不会出现AC、AD或者EB、BF这种,我们就认为“AB”这个片段的内部成分搭配是最稳定的,A或B单独出现的次数越多,则“AB”的稳定性越低。
即使A、B总是一起出现,但是假设“AB”后面跟的字符总是C,即“AB”的右搭配只有一个,我们也认为“AB”不能成词(可能“ABC”是一个词也说不定),如果“AB”后面可以接CDEFG……各种字,我们就说“AB”的右搭配很丰富,左搭配同理。
内部搭配的稳定性和左右搭配的丰富程度涉及到两个概念,“互信息”和“信息熵”
互信息的概念
以下摘自维基百科
在概率论和信息论中,两个随机变量的互信息(Mutual Information,简称MI)或转移信息(transinformation)是变量间相互依赖性的量度。
一般地,两个离散随机变量 X 和 Y 的互信息可以定义为:
由于我们在分词的时候是不考虑同义词的情况的,即不同的字符串代表不同的词。对于一个已知的文本片段和它的分割点,这两个“随机变量”只有一个值,上面的公式可以简化为:
对于一个长度大于2的文本片段,它的分割点不止一个,例如“ABC”可以分为“AB”和“C”或者“A”和“BC”,这时候一个文本片段就会有多个互信息值,我们取最小的一个作为词的聚合度。
为什么要取最小的呢?考虑这样一种实际情况,“的蝙蝠”这个文本片段, 如果把它分割成“的蝙”和“蝠”这两个子片段,它的聚合度是很高的,“的蝙”几乎不会单独出现,“蝠”也很少和其他字搭配,但是"的蝙蝠"却不是一个词。因为把它拆成“的”和“蝙蝠”后,聚合度是很低的,因为“的”有无数种搭配,“蝙蝠”也可以组合成“只蝙蝠”、“蝙蝠侠”等。
实际上,通过这种方法发现的新词以两字词居多,三字词较少,而且多是由两字词再加一个字组成的。这可能和中国人的用词习惯有关。聚合度很高的三字词(“加拿大”、“红领巾”)不多见,但是,四字词反而多了一些(成语)。
而且,由两字词加一个字组成的词可能和那个两字词都作为新词被抽出来。例如前面提到的“蝙蝠侠”这个词,如果训练文本是关于影视的,“蝙蝠侠”很可能作为新词出现,而“蝙蝠”可能因为单独出现次数过少,就没有被筛选出来。这个时候如果再给训练集加入等量的关于动物的文本,“蝙蝠”就很有可能作为新词出现了,这个时候“蝙蝠侠”的词频和聚合度会降低,但是依然超过其他的词,所以它也是一个新词。
信息熵的概念
以下摘自维基百科:
在信息论中,熵(英语:entropy)是接收的每条消息中包含的信息的平均量,又被称为信息熵、信源熵、平均自信息量。
matrix67的文章对这个概念有一个直观的解释,这里直接抄过来:
依据Boltzmann's H-theorem,香农把随机变量X的熵值 Η(希腊字母Eta)定义如下,其值域为{x1, ..., xn}:
其中,P为X的概率质量函数(probability mass function),E为期望函数,而I(X)是X的资讯量(又称为资讯本体)。I(X)本身是个随机变数。
当取自有限的样本时,熵的公式可以表示為:
对于一个词,我们统计出它所有的左邻字集合,每个字在文本中出现的概率为,可以计算出的左信息熵,同理可求出右信息熵,取和的较小值作为最终信息熵。
测试效果
准备数据
测试数据用的是快看漫画APP社区的动态,因为数据量太大,第一次只取了前100w行。随便找了一段截图在下面👇,可以看到有很多的表情符号(这个后面会过滤掉),而且有很多空行,从右边👉的缩略图可以看出来。
第一次测试
第一次测试的时候,按照逐行导入数据的方式,可以看到每次导入1000行的时间越来越长。因为随着导入的数据越来越多,整个词典在变大,计算信息熵的时间变长。
并且,从下图可以发现,排在前面的词居然是一些表情。z这是因为我一开始只考虑了过滤一些符号:
[\s\d,.<>/?:;'"\[\]{}()\|~!@#$%^&*\-_=+a-zA-Z,。《》、?:;“”‘’{}【】()…¥!—┄-]
虽然知道会有,但是没想到出现的频率这么高😱(嗯,我忽略了这是一个二次元社区,而且活跃用户多是一些95后的青少年)。
第二次测试
然后我就加了一些过滤:
[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]|[\s\d,.<>/?:;'"\[\]{}()\|~!@#$%^&*\-_=+a-zA-Z\uFF0C\u3002\u300A\u300B\u3001\uFF1F\uFF1A\uFF1B\u201C\u201D\u2018\u2019\uFF5B\uFF5D\u3010\u3011\uFF08\uFF09\u2026\uFFE5\uFF01\u2014\u2504\uFF0D\u2022\u03C9\u0334\u0300\uD83E\uDD14\u203C\u0300\u03C9\u1D52\uFF5E\u200B\u3000\uD83E\uDD23\u0325\u2501\u2299\u25BD]
并且每次处理100万行数据(大概30M),第二次的测试结果如下
并且处理的时间也缩短了(100万行不到2分钟,第一个数字是数据的总长度,第二个是处理完成后词典中词的数量)
统计结果
统计了出现频率最高的前100个新词如下:
["朝花","作者大大","咬痕","锐思","啦啦","伊凯","马蓉","要要要","林早上","呵呵呵","啦啦啦","嗯嗯","点赞","污污","千玺","芙蕾","呵呵呵呵","蛤蛤","狗粮","夏天岛","呜呜呜","考神","搞事","粗长","蛤蛤蛤","污污污","什么鬼","小莘","爆照","福利图","啪啪啪","罗真","女主","斯里","莲莲","傲娇","林路","耽美","蓝斯","啦啦啦啦","蛤蛤蛤蛤","男主","宋喆","谨斯里","水默","微博","写作业","宝强","南烟","呜呜呜呜","壁咚","懵逼","易烊千玺","搞事情","萌萌","应怜","考神保佑","单身狗","朝花惜时","签售","高冉","洛逸","老司机","微信","炫童","高仿","加油加油","镜玄","小黄文","咳咳","江哥","学生党","同款","嗷嗷嗷","晴蓝","暖男","哇哇哇","腐女","龙之谷","开车开车","闺蜜","玛丽苏","南烟斋","清英","老宫","番外","保佑保佑","狂魔","没毛病","嘿嘿嘿嘿","小仙女","鹿晗","停更","必过","秀恩爱","注意身体","部漫画","威风堂堂","小贝","柯小"]
可以看到排名靠前的是一些快看漫画特有的词汇:朝花、咬痕、锐思等;还有一些关于学生的:写作业、考神、学生党等;关于恋爱的:壁咚、单身狗、啪啪啪等;另外,这份数据是按照时间排序的,所以这前100万行数据应该是快看刚开发出社区功能时候的,所以也体现了当时的热点,例如宝强、马蓉、宋喆都出现在了词表里面。