《NLP基础任务之新词发现探索之路》

 NLP
 

step1:寻找综述

没找到太好的综述。

step2:寻找技术博客文章

如寻找技术博客(如CSDN与个人博客站点)与文章(如知乎、简书),具体到新词发现任务,如:

  1. 基于互信息和左右信息熵的短语提取识别-码农场
  2. 互联网时代的社会语言学:基于SNS的文本数据挖掘 | Matrix67: The Aha Moments
  3. python3实现互信息和左右熵的新词发现 - 简书

step3:寻找已有实现

如从Github上搜索与筛选相关开源项目,如:

  1. xylander23/New-Word-Detection: 新词发现算法(NewWordDetection)
  2. zhanzecheng/Chinese_segment_augment: python3实现互信息和左右熵的新词发现

step4:结合知识点研读开源项目

算法初始思路

经过研究以上代码与相关文章,发现主要有2种思路:

  1. 不依赖分词,直接进行新词发现,如上面开源项目1
  2. 在原有分词基础上进行,如上面开源项目2

相比而言(更多的是感性认识,并没有对比观察多少数据从而建立起有依据的推论),不依赖分词能够避免原有分词错误而引起的后面的错误,而在原有分词基础上进行则更加准确,因为可以依赖于分词结果作为输入特征,个人认为可能方案2(即在原有分词基础上进行)可能会更好些,当然这又受限于分词的准确率。

相关特征

识别新词即确定两个词(或多个)是否能够组合成为一个词,主要看词内部的凝固度以及词外部的自由度,其中内部的凝固度可以用点间互信息来衡量,而自由度则可以用左右邻的信息熵来衡量。

大致流程

对于所有的候选新词分别计算以上两个特征,通过某种方式组合在一起,或线性加和或幂次乘积来给候选新词打分,同时设定一些阈值过滤掉不符合条件的候选词,并将所有过滤后的候选词按分数高低降序排序,从而得到最终的结果。

step5:改进与整合原有项目

自己主要参考项目2,但发现存在一些不足,如:

  1. 没有实现开箱即用的接口
  2. 数据结构设计不合理,比如遍历自定义的类所组成的列表进行匹配查找,耗时较多
  3. 虽然将引入外部词典数据进行初始化构建的模型进行了pickle持久化操作,但是其实没必要
  4. 不能很好地多次调用,每次调用都需要初始化或读取持久化的对象,耗时较长。

经过不断实践与探索,基本上比较好地解决了以上问题,同时在过程中也考虑了很多问题,如:

  1. 基于分词还是不基于分词
  2. 是否引入外部词典作为结果排序矫正
  3. 是否提供用户自定义词典以及自定义停用词接口
  4. 采用何种数据结构,是否照搬项目中数据结构,还是进行优化改进
  5. 在每次调用时都需要进行对外部词典数据初始化的过程,使用pickle文件写入读取持久化还是使用deepcopy进行对象拷贝,怎样更快
  6. 如何对如互信息与信息熵等统计特征进行加权组合,参数如何选取调整
  7. 如何引入其他信息增强发现能力以及矫正能力,比如词性信息(然而结巴的那个词典里面许多词性信息都不准确,比如说将知识的词性标注为动词)
  8. 设计一个什么样的接口才能使用户很方便的使用
  9. 如何将该新词发现模块与分词系统等较好地整合在一起
  10. 如何更好地融入人工校验机制
  11. 是否加入机器学习、深度学习等算法,包括有监督、无监督、强化学习、在线学习等

实现

smilelight/lightText: 文本处理相关库,目前包括新词发现等功能。

后记

当今nlp各任务的各种实现从传统规则到机器学习再到深度学习比比皆是,层出不穷,然而根本就没有完美的算法,没有完美的系统,有的只是不断地改进和优化。

个人心得

在进行系统设计时,前期一定要对项目有一个比较清晰的规划,比如它的定位是什么、有哪些可以参考借鉴的已有实现,重要的搭一个能够跑起来的架子,不论啥效果;在中期优化过程中,则需要综合考虑时间空间硬件精度等多种因素,在一方面有所得有时必须建立在在其它某些方面有所失,比如各种时间空间互换、精度与时间空间互换等,在不同的时期不同的场景下主要矛盾不同,因此所对应的最佳策略也不唯一;在整个项目的生命周期中都需要不断考虑项目的拓展性,许多时候多写几个函数,多整几个文件来将不确定的、复杂的实现解耦,便于后续的排查调整。

参考