作者|mczhao,携程高级研发经理,专注于自然语言处理技术领域。概述随着消费热点和新网红的不断涌现,在电商平台的NLP任务中,经常会出现一些以前没见过的词。这些词不在系统现有的词库中,称为“未注册词”。一方面,词库缺词会影响一些基于词库的分词器的分词质量,并间接影响文本召回和突出显示的质量,即用户文本搜索的准确性和搜索结果的可解释性.另一方面,在主流的NLP深度学习算法BERT/Transformer等中,在处理中文时往往会使用词向量来代替词向量。理论上使用词向量的效果应该更好,但是由于未注册词,实际使用词向量的效果更好。如果词库比较全,使用词向量的效果会比使用词向量的效果更好。综上所述,新词发现是我们现在需要解决的问题。1.传统的无监督发现中文新词的方法这个问题在业界已经有了比较成熟的解决方案。输入是一些语料库。这些文本被NGram分割后,生成候选片段。计算这些片段的一些统计特征,然后根据这些特征判断片段是否是一个词。业界的主流做法是统计观察这三个方面的指标:流行度、内聚度、左右相邻词的丰富度。网上也有很多文章描述这三个指标。这里简单介绍一下。具体可以参考HelloNLP和SmoothNLP的两篇新词发现文章。1.1流行度词频用来表示流行度。统计所有语料的所有片段出现的次数,那些高频片段往往是一个词。1.2内聚度是通过点互信息来衡量的:比如我们判断汉庭是不是一个词,log(P("汉庭")/P("汉")P("亭"))。汉庭成词概率与“汉庭”热度成正比,与“汉”“亭”词热度成反比。这个很好理解,像汉字中出现频率最高的“得”字,任何一个汉字与“得”匹配的概率都很高,但并不代表“x”或“dex”就是一句话,这里对“德”字的流行起到了抑制作用。1.3左右相邻字符的丰富度左右相邻字符表示左右字符的丰富度。左右邻接熵是词出现在候选词段左侧或右侧的分布随机性。您可以将左侧的熵和右侧的熵分开,或者将两个熵合并为一个指标。比如“香格里拉”这个片段有非常高的人气和凝聚力,对应的子片段“香格里拉”也有很高的人气和凝聚力,但是因为“香格里拉”后面的大部分情况都出现了“香格里拉”这个词右邻接熵很低,抑制了它的构词,可以判断“Shangri”这个词不能单独成词2.ClassicalMethodsLimitationsofClassicalMethods经典方法的问题是阈值参数需要NLP专家在了解了当前语料中片段的概率分布后,将这些指标通过公式组合或独立使用,然后设定一个阈值作为判断标准,使用这个标准的判断结果也能达到很高的准确率。但是,概率分布或词频不是一成不变的。随着语料库越来越丰富,或者语料库的加权流行度(通常是对应的产品popularity)波动,专家设定的公式中的参数和阈值需要不断调整。这浪费了大量的人力,也让人工智能工程师沦为调整者。3.基于深度学习的新词发现3.1词频概率分布图上述业界现有算法的三个指标只有一个基本的来源特征,即词频。在统计方法中,一些简单的、关键的统计数据通常以图片的形式展示,比如直方图、箱线图等,即使不涉及模型,也能一眼就做出正确的统计。法官。可以从语料库中切出所有限长的片段,将片段的词频归一化为0-255,映射成二维矩阵。行代表起始字符,列代表结束字符。一个像素就是一个片段,一个像素点的明暗就是候选词片段的热度。上图是短句“浦东机场华美达酒店”的词频概率分布图。我们惊喜地发现,仅凭肉眼,我们就能大致分辨出一些比较亮的、等腰直角三角形的方块,比如:“浦东”、“浦东机场”、“机场”、“华美达酒店”等等.这些块可以确定对应的段正是我们需要的单词。3.2经典图像分割算法通过观察词频概率分布图,我们可以将短句分词问题转化为图像分割问题。早期的图像分割算法与上述新词发现算法类似。它也是一种基于阈值检测边缘灰度变化的算法。随着技术的发展,现在普遍采用深度学习算法,其中最著名的是U-Net图像分割算法。.U-Net前半部分使用卷积下采样提取不同粒度的多层特征,后半部分上采样将这些特征以相同的分辨率concat,最后通过全连接层+Softmax得到像素级的分类结果。3.3基于卷积网络的新词发现算法。词频概率分布图的切分与图的切分类似。将位置相邻、灰度级相近的部分剪掉。所以对于短句的分割,也可以参考图像分割算法,使用全卷积网络来做。使用卷积的原因是当我们切割短句或图像时,我们更关注局部信息,即靠近切割边缘的那些像素。之所以使用多层网络,multi-layerpooling可以表现出不同层特征的阈值判断,比如我们切割地图地形时,需要同时考虑斜率(一阶导数/差分)和斜率的变化(二阶导数/差分),两者分别取阈值,组合的方法不仅仅是简单的线性加权,而是一个串行网络。针对新词发现场景,我们设计了如下算法:首先将短句的词频分布图填充为0~24x24;首先有两个3x3的卷积层,输出4个通道;concat两个卷积层,然后做一个3x3的卷积,输出一个单通道;损失函数使用logistic=T,所以最后一层可以不用softmax输出来做分类;与U-Net相比,有以下区别:1)放弃下采样和上采样的原因是一般用于分词的短句比较短,词频分布图分辨率不高,所以模型相应简化。2)U-Net是三类(block1,block2,ontheedge),这个算法只需要两个类别(不管像素是不是词)。所以最后输出的结果也是不一样的。U-Net输出一些连续的块和分割线,我们只需要某个点为正。下图是模型训练后预测的结果。我们可以看到,在输出结果中,“上海”(上行海列)、“虹桥”、“商务区”这三个词对应的像素已经被识别。使用训练好的模型,在携程的地标库中输入地标名称,可以自动切分找到一些生词,如下图所示。虽然有一些不好的情况,但是总体准确率还不错。将这些词导入词库后,搜索分词准确率提高,分词结果词库覆盖率提高。由于搜索分词一般容易出现over-recall和剔除missedrecall的情况,所以业界有比较激进的做法是通过分词来recall,准确率一般通过后续的排序来解决。因此,分词的准确率提高了,但搜索结果的准确率在用户眼中并没有明显提高。但是可以解决部分分词错误导致高亮不正确的问题。4.模型内部分析如果想探究模型是如何工作的,可以查看中间层的卷积核。我们先将模型卷积层的卷积核数从4个简化为1个,训练完成后通过TensorFlowAPI查看中间层:model.get_layer('Conv2').__dict__。我们发现Conv2层的卷积核如下:可以看出第一行和第二行对模型的影响是相反的,对应上一行的像素减去差值(有权重)当前行的,如果灰度差异越大,则该像素表示的字符串越有可能是单词。也可以看出第一行第二列0.04505884的绝对值比较小,可能是因为第一行的正参数减去第二行和第三列的负参数减去第二列各自抵消了其他出来。五、优化空间本文描述了一个结构非常简单的全卷积网络模型,还有很大的改进空间。一是扩大特征选择范围。比如这篇文章的输入特征只是词频。如果输入特征中也包含左右邻接熵,分割效果会更准确。二是增加网络的深度。通过模型分析发现,第一层卷积主要是处理填充0的像素点产生的情况,而真正关注真实热度的卷积只有一层。如果是3x3的卷积核,只能看到一阶差分。因此,不考虑当前像素前后的第二行和第二列。可以适当放大卷积核的大小或者加深网络,使模型的视野更大。但是加深网络也会带来过拟合的问题。最后,该模型不仅可以用来补充词库提高分词效果,还可以直接作为分词的参考。该模型的预测结果可以应用于分词过程中的候选词召回和分词路径评分两个步骤。
