数学极客来自中文系

时间:2022-09-18 08:27:09

数学极客来自中文系

汉语是一种独特而神奇的语言,我非常热衷于用计算的方法去分析汉语资料。2012年,我在人人网实习了一段时间,期间在对汉语资料进行自然语言处理时,我遇到了很多其他语言不会有的困难,比如分词——汉语的词与词之间没有空格,计算机怎么才知道,“已结婚的和尚未结婚的青年都要实行计划生育”究竟说的是“已/结婚/的/和/尚未/结婚/的/青年”,还是“已/结婚/的/和尚/未/结婚/的/青年”呢?这就是所谓的分词歧义难题。虽然现在很多语言模型已经能比较漂亮地解决这一问题了。但在中文分词领域里,还有一个比分词歧义更令人头疼的东西——中文没有首字母大写,专名号也被取消了,这叫计算机如何辨认人名地名之类的东西?更惨的是机构名、品牌名、专业名词、缩略语、网络新词等等,它们的产生机制似乎完全无规律可寻。最近十年来,中文分词领域都在集中攻克这一难关,自动发现新词则是其中关键的环节。

挖掘新词的传统方法是,先对文本进行分词,然后猜测未能成功匹配的剩余片段就是新词。但这似乎又陷入了一个怪圈:分词的准确性本身就依赖于词库的完整性,如果词库中根本没有新词,我们又怎么能信任分词结果呢?此时,一个大胆的想法浮现了出来:能不能不依赖任何已有的词库,仅仅根据词的共同特征,将一段大规模语料中可能成词的文本片段全部提取出来,然后,再把所有抽出来的词和已有词库进行比较,不就能找出新词了吗?于是,我随机找来人人网2011年12月部分用户的状态和相关语料,准备自己做一次挖掘实验。

文本、词语有算法

要想从一段文本中抽出词来,我遇到的第一个问题就是,怎样的文本片段才算一个词?大家想到的第一个标准或许是,看这个文本片段出现的次数是否足够多。不过,光是出现频数高还不够,一个经常出现的文本片段有可能还是多个词构成的词组。在各种用户状态中,“的电影”出现了389次,“电影院”只出现了175次,然而我们却更倾向于把“电影院”当作一个词,因为从直觉上看,“电影”和“院”衔接得更紧密一些。

为了证明“电影院”一词的内部凝固程度确实很高,我决定计算一下,如果“电影”和“院”真的是各自独立地在文本中随机出现,它俩正好拼到一起的概率会有多少。在2400万字的语料数据中,“电影”一共出现了2774次,出现的概率约为0.000113,“院”字则出现了4797次,出现的概率约为0.0001969。如果两者之间真的毫无关系,它们恰好拼在一起的概率就是0.000113 × 0.0001969,约为2.223×10??次方。但事实上,“电影院”在语料中一共出现了175次,出现概率约为7.183×10??次方,是预测值的300多倍。而“的”和 “电影”随机组合到了一起的理论概率值为0.0166×0.000113,约为1.875×10??,这与“的电影”出现的真实概率很接近——真实概率约为1.6×10??次方,是预测值的8.5倍。这个计算结果表明,“电影院”更可能是一个有意义的搭配,而“的电影”则更像是“的”和“电影”这两个成分偶然拼到一起的。

光看文本片段内部的凝合程度还不够,文本片段的自由运用程度也是判断它是否成词的重要标准。如果一个文本片段能够算作一个词的话,它应该能够灵活地出现在各种不同的环境中,具有丰富的左邻字集合和右邻字集合。我决定用信息熵来衡量一个文本片段的左邻字集合和右邻字集合有多随机。“信息熵”是一个非常神奇的概念,它能够反映知道一个事件的结果后平均会给你带来多大的信息量。如果某个结果的发生概率为p,当知道它确实发生了,得到的信息量就被定义为-log(p) 。p越小,得到的信息量就越大。在人人网用户状态中,出现了956次的“被子”的左邻字用例非常丰富:用得最多的是“晒被子”,所有左邻字的信息熵为3.67453,而2330个同样发音的“辈子”中所有左邻字的信息熵仅为1.25963。当然,也有一些文本片段的左邻字没啥问题,右邻字用例却非常贫乏,例如“交响”、“后遗”、“鹅卵”等,把它们看作单独的词似乎也不太合适,于是我就把一个文本片段的自由运用程度定义为它的左邻字信息熵和右邻字信息熵中的较小值。

最后,我把文本中出现过的所有长度不超过d(即候选词的长度上限,我设定的值为5)的子串都当作潜在的词,再为出现频数、凝固程度和自由程度各设定一个阈值,只需要提取出所有满足阈值要求的候选词即可。为了提高效率,我又把语料全文视作一整个字符串,并对该字符串的所有后缀按字典序排序。这样便得到了一个无需任何知识库的抽词算法,也就能以大致O(n·logn) 的效率提取出可能的词来。

不怕狂想,只要有合适的算法

得到了基本算法,我开始对不同的语料进行抽词,发现2011年12月人人网用户状态中最常出现的词是:

哈哈、什么、今天、怎么、现在、可以、知道、喜欢、终于、这样、觉得、因为、如果、感觉、开始、回家、考试、老师、幸福、朋友、睡觉、生活、已经、希望……

程序一共从人人网的状态数据中抽出了大约1200个词,里面大多数词也确实都是标准的现代汉语词汇。不过别忘了,我这次的目标是新词抽取。所以我又将这些抽出来的词与已有词库作对比,于是得到了人人网特有的新词:

伤不起、给力、有木有、挂科、坑爹、神马、淡定、老爸、无语、微博、六级、高数、选课、悲催、很久、人人网、情何以堪、童鞋、哇咔咔、吐槽……

这时候,我想到了一个更有意思的玩法。为什么不拿每一天状态里的词去和前一天的状态作对比,从而提取出这一天里特有的词呢?这样一来,我就能提取出每日热点了!于是我选了10个比较具有代表性的词,列出了它们在2011年12月13日的用户状态中出现的频数(左列的数),以及2011年12月14日的用户状态中出现的频数(右列的数):

从上图我们可以从直觉上迅速判断出,14日除了“下雪”以外,“看见”、“北半球”和“脖子”也应该是热词。你或许坚信后三个词异峰突起的背后一定有什么原因,事实上,你的直觉是对的——2011年12月14日发生了极其壮观的双子座流星雨,此乃北半球三大流星雨之一。白天网友们不断转发新闻,因而“北半球”一词热了起来;晚上网友们不断发消息说“看见了”、“又看见了”,“看见”一词的出现频数猛增;最后呢,仰望天空一晚上,脖子终于出毛病了,于是回家路上一个劲儿地发“脖子难受”。

更有趣的是,我在比较不同文本的用词特点时,发现人人网上大多数者都填写了性别和年龄的个人信息,那为何不把状态重新分成不同组别,挖掘出不同属性的人都爱说什么?要知道,在过去,这样的问题需要进行大规模语言统计调查才能回答,然而,在互联网海量用户生成内容的支持下,我能轻而易举地找出答案。

我真的做了这个工作(基于另一段日期内的数据)。男说的词有:

兄弟、篮球、男篮、米兰、曼联、足球、皇马、比赛、国足、超级杯、球迷、中国、老婆、政府、航母、踢球、赛季、股市……

下面则是女说的词:

一起玩、蛋糕、加好友、老公、呜呜、姐姐、嘻嘻、老虎、讨厌、妈妈、呜呜呜、啦啦啦、便宜、减肥、男朋友、逛街、无限、帅哥、礼物……

还有90后用户爱用的词:

加好友、作业、各种、乖乖、蛋糕、来访、聚会、补课、欢乐、刷屏、录取、无限、互相、速度、一起玩、啦啦啦、晚安、求陪同、查分、上课、果断、肿么办……

80后用户爱用的词:

加班、培训、周末、工作、公司、各位、值班、砸蛋、上班、任务、公务员、工资、领导、包包、办公室、校内、时尚、企业、招聘、顺利、朋友……

不仅如此,不少状态还带有地理位置信息,因而我可以站在空间的维度对信息进行观察。借助这些包含地理位置的签到信息,我又挖掘出很多有意思的结果来。对北京用户的抽词结果非常有趣:“考试”一词集中分布在海淀众高校区,“天津”一词集中出现在北京南站,“逛街”一词则全都在西单附近扎堆。北京首都国际机场也是一个非常特别的地点,“北京”、“登机”、“终于”、“再见”等词在这里出现的密度极高。

从全国范围来看,不同区域的人也有明显的用词区别。例如在节假日的时候,“滑雪”一词主要在北方出现,“登山”一词则主要在南方出现。地方特色也是造成词语分布差异的一大原因,例如“三里屯”一词几乎只在北京出现,“热干面”一词集中出现在武汉地区。另外,方言也会导致用词分布差异,例如“咋这么”主要分布在北方地区,“搞不懂”主要分布在南方城市,“伐”则集中地出现在上海地区。当数据规模足够大时,或许我们能通过计算的方法,自动对中国的方言区进行划分。

其实,不仅仅是时间、用户年龄、用户性别、地理位置这四个维度,按照上述方法,还可以对浏览器、用户职业、用户活跃度、用户行为偏好等各种各样的维度进行分析,在某个特定范围内挖掘热点事件,或者根据语言习惯去寻找出某个特定的人群。或许这听上去太过理想化,不过我坚信,有了合适的算法,这些想法终究会被一一实现。

上一篇:扛住!哪怕肩膀再嫩 下一篇:让个性在阅读中生根