⽤python实现新词发现程序——基于凝固度和⾃由度python学习笔记整理于猿⼈学⽹站的和
互联⽹时代,信息产⽣的数量和传递的速度⾮常快,语⾔⽂字也不断变化更新,新词层出不穷。⼀个好的新词发现程序对做NLP(⾃然预⾔处理)来说是⾮常重要的。
N-Gram加词频
最原始的新词算法莫过于n-gram加词频了。简单来说就是,从⼤量语料中抽取连续的字的组合⽚段,这些字组合⽚段最多包含n个字,同时统计每个字组合的频率,按照词频并设置⼀个阈值来判断⼀个字组合⽚段是否为词汇。
该⽅法简单处理速度快,它的缺点也很明显,就是会把⼀些不是词汇但出现频率很⾼的字组合也当成词了。
凝固度和⾃由度
这个算法在⽂章《互联⽹时代的社会语⾔学:基于SNS的⽂本数据挖掘》 ⾥有详细的阐述。
凝固度就是⼀个字组合⽚段⾥⾯字与字之间的紧密程度。⽐如“琉璃”、“榴莲”这样的词的凝固度就⾮常⾼,⽽“华为”、“组合”这样的词的凝固度就⽐较低。
leveldb使用⾃由度就是⼀个字组合⽚段能独⽴⾃由运⽤的程度。⽐如“巧克⼒”⾥⾯的“巧克”的凝固度就很⾼,和“巧克⼒”⼀样⾼,但是它⾃由运⽤的程度⼏乎为零,所以“巧克”不能单独成词。
Python实现
根据以上阐述,算法实现的步骤如下:
1. n-gram统计字组合的频率
如果⽂本量很⼩,可以直接⽤Python的dict来统计n-gram及其频率。⼀段⽂本n-gram出来的字组合的⼤⼩⼤约是原始⽂本的(1+n)*n/2倍,字组合的数量也⾮常惊⼈。⽐如,“中华⼈民共和国”的⾸字n-gram是(n=5):
中
中华
中华⼈
中华⼈民
中华⼈民共
n-gram统计字组合频率的同时还要统计字组合的左右邻居,这个⽤来计算⾃由度。
如果⽂本量再⼤⼀些,Python的dict经常会碰到最好使⽤trie tree这样的数据结构。双数组Trie Tree有很多⾮常好的开源实现,⽐
如,cedar、darts等等。Trie Tree使⽤的好处是,它天然包含了字组合的右邻居信息,因为这个数据结构⼀般是前缀树。要统计左邻居信息时,只需要把字组合倒序放⼊另外⼀个Trie Tree即可。
使⽤cedar Trie Tree的时候,5-gram统计30M的⽂本⼤约使⽤6GB左右的内存。
如果⽂本量更⼤,这就要借助硬盘了,可以使⽤leveldb这样的key-value数据库来实现。实验下来,trie tree统计30M的⽂本⽤⼏⼗秒,⽽同样的⽤leveldb统计却要6个多⼩时应该还有⽐leveldb更合适的数据库来做这件事情,有时间再说。
当然,为了发现新词,⼏⼗MB的⽂本⽂本⾜够了。
2. 计算字组合的凝固度;
有了上述的统计结果,计算每个字组合的凝固度就⽐较简单了。
⾸先,把字组合切分成不同的组合对,⽐如’abcd’可以拆成(‘a’, ‘bcd’), (‘ab’, ‘cd’), (‘abc’, ‘d’),
然后,计算每个组合对的凝固度:D(s1, s2) = P(s1s2) / (P(s1) * P(s2))
最后,取这些组合对凝固度中最⼩的那个为整个字组合的凝固度。
3. 计算字组合的⾃由度;
分别计算它的左邻居信息熵和右邻居信息熵,取其中较⼩的为该组合的⾃由度。
4. 阈值的选择
整个过程涉及到三个阈值的选择:
组合的词频:频率很低的组合成词的可能性很⼩
组合的凝固度:凝固度越⼤成词的可能性越⼤
组合的⾃由度:⾃由度越⼤成词的可能性越⼤
经验值:30M⽂本,词频>200, 凝固度>10**(n-1), ⾃由度>1.5
⼩窍门:词频>30, 凝固度>20**(n-1)也能发现很多低频的词汇。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论