监督学习的方法需要大量的标注数据,对于层出不穷的网路新词,显得力不从心。这是就需要无监督的演算法去发现新词、行业词等。本文根据这篇新词发现演算法做一个梳理和自我的总结。

上面文章做新词发现的主要思想就是通过字之间的组合,正向匹配,从相关性最低处切开,保证词内部的相关性最高,或者称之为凝固度最高。

以三个字的词为例,相关性(凝固度)的公式:

min left{ frac{P(ABC)}{P(A)P(BC)},frac{P(ABC)}{P(AB)P(C)} 
ight}

上面公式可以这样理解,以第一个式子为例,假设A、BC为相互独立的事件,则ABC发生的概率为 P(ABC) = P(A)P(BC),而P(ABC)表示ABC统计而得发生的真实的概率。上式可以理解为 P(ABC)/P(ABC),比值越大代表ABC越不独立,相关性很高越有可能同时出现,也就是词的内部凝固度很高。按照互信息的概念来讲,就是 A 和 BC 联合分布相对于假定 A和 BC独立情况下的联合分布之间的内在依赖性。

演算法分为以下步骤:

  1. 统计1,2,3...ngrams的词频并根据词频设定的阈值过滤小于阈值的部分

2.根据凝固度公式计算2grams以上词语的凝固度,并过滤小于凝固度阈值的词语,针对不同长度的词语,凝固度的阈值设置不一样。按文中作者给出的经验阈值,以字典的形式给出,长度为2的为5,长度为3的为25,长度为4的为125。min_proba={2:5,3:25,4:125}。其中,凝固度的计算按照每种切分可能都进行计算,取最小的最为其凝固度

根据凝固度过滤掉第一步统计出来的ngrams中小于凝固度的词语。

3.根据前两步筛选出来的词语对句子进行分词。

其中,对句子分词时设置了一个掩码,用于标记句子中出现在ngrams中的词语,例如「中华人民」除去句首外各个位置设置掩码为[0,0,0],从句首开始扫描,如果"中华"在ngrams里面,则掩码变成[1,0,0],再向前扫描,中华人不在ngrams里面,掩码依然为[1,0,0],中华人民在ngrams里面,掩码全部加一,变成[2,1,1],从掩码等于0的地方断开,这样就可以进行粗略的分词。

4.上面的分词结果可能会存在一个问题,比如说"各项目",是由于"各项","项目"都存在于ngrams,所以"各项目"才会保留下来,这时可以扫描"各项目"是否在3grams里面,如果在其中,将其保留,不在就删除。其实,不进行这一步的筛选,我认为也是可以的,主要看你的需求,例如"大字型大小印表机",可以切成{大字型大小,印表机},也可以保留成一个。

演算法实践

利用新闻语料测试一下新词发现的结果:

处理结果:

每句对应的分词结果
发现的新词

可以看出很多词都是和金融股票有关的,"分红派息","现金红利"也都能从文中识别出来。此演算法还是具有一定的效果。

整体的代码和数据上传在github上:HaishuoFang/Find_New_token


推荐阅读:
相关文章