AIQ | NLP 算法工程师的学习、成长和实战经验



转载请注明 AIQ - 最专业的机器学习大数据社区  http://www.6aiq.com

AIQ 机器学习大数据 知乎专栏 点击关注

我们本次分享主要分为六个小节,分别为:

1.NLP 解决什么问题;
2.NLP 算法发展简史;
3. 检索式问答系统的语义匹配模型;
4. 任务型对话系统背后的算法实例;
5. 创业公司 NLP 工程师的工作职责;
6.NLP 算法工程师面试注意事项;

其中前两个小节主要大概讲述一下 NLP 这个学科它解决了什么问题,以及它算法发展的简要的历史,这样可以让大家对它先有一个整体上的认识;中间两节介绍一下在问答系统和对话系统中 NLP 的作用和典型的模型;最后两节说一下现在创业公司 NLP 算法工程师的工作职责和一些面试的注意事项。

一:NLP 解决什么问题?

NLP 是一个交叉性的学科,它和计算机科学,人工智能,计算语言学这三门都有交叉,是一门对综合要求比较高的学科。它的主要目标是解决计算机和人类(自然)语言的交互问题,随着近年来 UCG 内容的越来越多,NLP 在很大程度上需要解决无结构化的语料怎么让机器更好的理解。因此 NLP 学习起来也有些难度,主要难点为:

●语言本身复杂:大家想象一下语言本身有多复杂,比如我们在学习外语的时候都有各种各样的语法规则,就可以知道让计算机去理解人类的自然语言是多么复杂的一件事情。
●语境相关:在不同的语境里面同样的一句话可以有不同的理解。
●抽象概念联系:我们在提到一个概念的时候,需要我们对概念的相关抽象概念有一些历史上的认识,比如说以前见过或者以前看过相关的东西才能把它联想起来。

所以人跟人之间的正常交流都需要很多语言本身之外的东西,可以想像让计算机来完成这件事情难度是非常大的。

NLP 解决的五个基本问题,这五个是李航老师在北大的 AI 公开课上提出来的,分别为:

  1. 分类问题:分类问题大家平时表容易见到,比如文本分类,情感分析目的是把一段文本打上一个或多个标签。
    2. 匹配问题:比较常见的是检索,检索与某句话类似的话或者是与它相关的回答,这个就是匹配。
    3. 翻译问题:类似于两种语言之间的翻译,把一种语言翻译成跟它语义相似的另外一种。
    4. 结构化预测:把一段文本结构化,所谓的结构化类比于一段文本中的词对应的是动词还是名词,语法角色是主语还是谓语,将其转化为结构化的输出序列。
    5. 马氏(马尔可夫)决策过程:当前要采取的动作和上一个状态和动作相关,这是一个典型的马氏链的过程。代表性的系统是对话,如何回复当前用户的话,是和最近的上下文相关的,这就是马氏决策过程。

综述上面所讲的五个基本问题,结合这张图来看一下它的应用实例。

这张图从上到下总共有四个任务,是用 Stanford CoreNLP 来标识的。

●第一个任务是词性标注,所谓的词性标注,它是一个典型的序列任务,把一段文本中的每一个词的词性标注上,如名词,动词,副词。
●第二个任务是结构性预测任务,把一段文本中跟实体有关的词,打上实体的标签,如人名,机构名,地点,日期。
●第三个任务是指代消歧,将句中的 3 个代词反推回去,和人名一一对应。
●第四个任务是句法依赖,把某些词和其他的词是修饰关系还是组合关系,统称为依赖关系,建成一棵依赖树。

生活中 NLP 都能够应用在哪些方面?以搜索引擎为例,在使用搜索引擎的过程中肯定有遇到出错词这样的纠错算法,这就是 NLP 的一个应用,还有文本分词以及搜索词改写,所谓的搜索词改写就是我们输入的词,系统会给我们做泛化,把同义词也进行检索,扩大了搜索结果。还有意图识别,比如在电商中搜索一件商品,比如苹果,是指你想要买手机还是水果,意图的识别率会影响到它的一个转化率。结果排序是更重要的,所有的网页质量都有一套排序算法,排序算法中很多都会涉及到 NLP 算法,尤其是文本分析相关的技术。最后还有搜索推荐,比如你在网站上搜索一个词的时候,下面有一块会提示出大家还在搜的词,你可能还想搜索的词语,这都是根据文本相似度的理解去做的。

二:NLP 算法发展简史

NLP 算法对于语言的理解分为三个层次,分别为:

●语法,是指我怎样说是符合语法规则的,类比程序上没有编译错误。
●语义,是指我这句话表达的是什么意思,是否是正确的意思。
●语用,是指我把这句话放在一个上下文的环境中这样说是不是合理,以及它是不是当前最合适的说法,类比于在程序中我们在一个约束条件下,是否实现了正确的算法。

从上面的图片中我们可以看出来目前 NLP 处在语义的阶段中,至于语用属于刚刚起步的状态。

从图片上可以看到 NLP 从被提出到现在基本上经历了三个阶段,

●第一个阶段是基于规则的 NLP
●第二个阶段是基于统计学习方法的 NLP
●第三个阶段是涉足深度学习的 NLP,这个阶段从 2012 年开始的。

从上面这张图中可以很明显的看出深度学习在 NLP 领域的发展趋势。

三:问答系统和对话系统

先来解释一下三个概念:
1. 问答系统,它主要是针对那些有明确答案的用户问题,而且通常面向特定的领域,比如金融,医疗,这一类的机器人。它的技术实现方案分为基于检索和基于知识库两大类。
2. 第二个任务型对话系统,大家看论文的时候看的大多数的对话系统都是任务型的,它也是面向特定的领域,而且是非常明确的领域。它是以尽快地正确的完成明确的任务为目标的,而且对话的轮数越短越好,它的应用实例就是各种在线的私人助理比如助理来也。
3. 第三个是偏闲聊的对话机器人,它没有特定的领域和明确的对话目标,评价标准之一就是看人和他聊天的时间长短。

从图上大家可以看到,检索式问答系统的系统架构主要分为离线和在线两大块。离线把问答索引,序列匹配模型和排序模型建好,在线服务收到用户的问题,把问题中的关键词从索引库中把相关的索引拿出来,然后根据生产好的 Matching 和 Ranking 模型去做 Rerank ,挑选最好的答案给用户展示。这样就是检索式问答系统的典型是实现方式。

从图中大家可以看到检索式问答系统的实现方案,主要分为四种方案:

1. 很经典,很传统的实现方式,根据需要统计 TF-IDF,应用一些比较简单的向量空间模型或 BM25 来计算匹配度。
2. 构造一些特征向量,特征向量的维度需要根据业务来确定,特征向量构造完成后,用统计学习方法或 L2R 的模型进行排序。
3. 从 2013 年开始的词向量算法,它需要先训练词向量,通过词向量构造他们之间的相似度,最简单的一种方法是通过 IDF 对每个词向量加权,然后把加权和做一个句向量的表示去计算相似度。还有一些比较复杂的方法,比如 WMD,用词向量计算等文本相似度,大家如果有兴趣可以用谷歌搜索它们的论文和实现方案,它们在短文本上的效果还是非常好的。
4. 基于神经网络尤其是深度学习来做语义匹配。基于深度学习的匹配方案有两种:
(1)先得到句向量表示,再用句向量表示来计算它的匹配度。这种方法一般采用孪生网络或者双塔模型网络,它的特点是处理 Q 和 A 的文本的网络是完全一样的。
(2)构造 QA 的交互网络,让他们尽早的相遇。尽早相遇可以利用更多的匹配信号,而不是像方案一中的孪生网络,在得到句向量之后才去计算它的相似度,这样可能会损失一些匹配信息。多轮问答和单轮问答还是有区别的,多轮问答需要考虑上下文对当前问答的影响。这里我也举出了一个实例,如果大家有兴趣可以去看一下。

上图展示了四种模型:
●图一是很典型的一个双塔模型(孪生网络),它就是把 Q 和 A 先做了 invading ,经过一个双向的 LSTM 拿到它的 hiddenfate,常用的是取最后一个作为句向量,但是这里是沿着时间维度去做 MaxPooling ,这样可以保留更多的信息,最后把两个网络的 pooling 值进行相似度计算。这个被称为 BasicModel,是一个非常经典的实现方法。
●图二是把 CN 和 LSTM 结合起来的一种方法,下面一部分同样是把 Q 和 A 先过 invading ,然后过 TSLM 的网络,上面一部分图一是用 pooling 把 LSTM 的每一个 time step 值用 pooling 提取,图二是用 CN 网络去提取计算计算相似度。
●图三和图二的区别是把 CN 和双向 LSTM 的顺序做了调换,文本过了 invading ,先用 CN 去提取,再用双向 LSTM 做向量编码,沿着 time step 做 MAX Pooling,最后匹配两个句向量的相似度。
●图四相对复杂一些,对比图一和图四,它们在处理 Q 的逻辑是一样的,都是通过 invading,双向 LSTM,沿着 time step 做 MAX Pooling;处理 answer 这一块的时候要稍微复杂一些,它把 question 的 pooling 结果当作注意力信号,这样生成的 answer 句向量中包含跟 question 的匹配信息,如果是匹配的,大大提升了他们之间的匹配效果。
这篇文章中还包含对四种模型的分析,虽然模型一个比一个复杂,但是效果是跟具体的场景相关的。比如图一在短文本上面的效果最好,随着文本长度的增加,图二和图四的效果要比图一要好一些,其中随着文本长度的增加,图四的效果是最好的。图三和图二的 CN 和 LSTM 的顺序调换了,图三的所有效果都会比图二要差一些,出现这种情况的原因可能是一开始就用 LSTM 提取特征会比用 CN 提取获得更多的信息。通过以上四个模型的分析,大家可以看出,并不是越复杂的模型,效果越好。所以在实战中,大家有很多细节需要注意,对此我也做了一下总结,因为都是比较常见的,所以我这里就不过多的介绍了,大家可以自己看图理解一下。

四:任务型对话系统背后的算法

这里有两张图是有两个实例,一个是单轮对话,一个是多轮对话。左边的单轮对话是创建日程,右边的多轮对话是订咖啡,大家可以感受一下两者的不同。

图中列出了任务型对话系统的典型系统架构。从左往右,收到用户消息后,依次处理为:
●第一个模块是自然语言理解,也就是 NLU 这个模块,这个模块主要负责的是意图识别和实体抽取。意图识别就是分析用户想要做什么,是想要打车,订咖啡还是叫外卖。实体抽取就是比如我要打车,要抽取出用户的出发点和目的地两个槽位。
●第二个模块 State Tracker 收到意图和抽取到的实体,对它们进行填槽更新对话状态。更新完对话状态后,我们就会知道当前用户提供了哪些消息,我们还需要什么信息,如果信息不足,我们需要发出消息询问,如果够了就可以继续下一步。
●State Tracker 把用户的对话状态传递给策略模块,策略模块根据用户当前的对话状态,来判读采取什么样的动作来回复用户。
●动作确定后传递给 NLG,NLG 把选定的动作生成对应的文本发送给用户。对话状态反映了在一次完整的对话的任一时刻,用户的后续预期是什么,主要负责解决如下问题:用户的最近一条消息,时候有可以填充槽位的实体,有的话就要填充。还需要判断业务需要的槽位是否都填充满了,如果满了需要提交给策略网络做 API 调用。判断用户最近一次交互的对话动作是在询问信息还是提供信息。DM 对话管理模块有两个方案:
(1)方案一是基于任务型对话状态是有限的前提来设计的,例如订机票的场景,会先把必填的槽位定义出来,根据槽位设计具体的问题,按照预设的顺序依次发给用户收集槽位信息。方案一的短板是不会根据用户的回答去灵活变通,而是按照设定的流程去走,如果用户回答的不是它想要的,它也会把错误的信息当成正确的信息,这样出错的可能性就非常大了,所以方案一只能用于非常标准化简单的场景。
(2)方案二是基于 Frame,Frame 是由一组槽位构成,某一时刻的 Frame 相当于槽位状态当时的快照。实现方式和方案一一样,每一个槽位关联一个问题,但是若用户一次提供多个槽位值,系统会抽取所有的槽位值填充,而且不会重复提问。方案二需要做状态迁移和管理的工作,这也是整个对话系统核心的部分。实现基于 Frame 的技术方法也有两种,第一种是基于规则,因为状态是有限的,预设一些规则,在状态中间做跳转。第二种是基于数据驱动的统计学习方法,把所有的槽位值,转化为向量,再把系统发出和收到的消息也转化为向量,这样就把回话当前转化为特征向量,这样就可以引入马氏链过程或 LSTM 去建模,捕捉上下文的依赖关系。当数据越多,第二种的效果会越好,而且当第一种的规则越多的时候,发生冲突的概率会越高,在不同的领域迁移也存在很大的问题。

现在总结一下任务型对话系统的算法,分别为:
1. 意图识别,是一个文本分类任务,难点是多轮的意图切换,采用双向的 LSTM+attention 机制做文本分类任务,对意图识别的效果是非常好的。
2. 第二是实体抽取,是一个典型的序列标注任务,与命名实体的模型类似。
3. 第三是多任务学习,将意图识别和实体抽取再一次训练过程中全部完成。
4. 第四是对话管理,它是对话管理系统的核心,虽然有很多的建模方法,但是各有利弊。其中 POMDP 模型是一个非常经典的方法,但是它的工程实用性不高,不容易实现。现在有很多论文在探索强化学习机制(在线学习机制)对管理系统的帮助,但是强化学习方法目前只处于实验阶段,要是想应用于现实系统还有一段的距离。
5. 第五是回复生成,它有基于模板和完全自动生成两个方式。基于模板可控性比较高,在现实系统中应用的也比较多。完全自动生成通过语料来训练是比较简单的,但是因为控制权比较低,不确定因素比较多,所以是一个趋势,想要在现实系统中应用还有一段的距离。

五:创业公司 NLP 工程师的工作职责

在助理来也的算法团队中,NLP 工程师需要工程和算法都涉及,例如数据预处理这是最基本的要求;根据业务需求调研并做算法选型;复现论文模型,评估效果,持续优化;开发模型的在线 serving 模块,满足性能高要求;处理流程及通用工具 SAAS 化,保证经验的复用。
如果 NLP 工程师具备以下素质会相对成长的比较快。
●计算机基础扎实(编程语言 + 数据结构 + 操作系统);
●对数据敏感,数据处理功底扎实;
●无障碍阅读论文,能讲清楚论文出发点及主要思路;
●跟进业务相关的领域研究成果(论文或开源方案);
●关注算法原理和实现细节,质重于量;
●学习能力强,能快速上手实战;
●自主性强,责任心强,用数据来支撑你的观点。

六:NLP 算法工程师面试注意事项

图中的第一点在于积累,平时工作中需要多多实战。第二点和第三点可以结合来看,因为我遇到很多面试者,自己简历中的项目一知半解,疑问道细节就回答的磕磕绊绊,这样肯定是很难达到面试要求的。对于第四点,文本分类是比较经典的,大部分求职者简历里面都会提到,但是它的原理和细节处你是否真的掌握了,我上图也列出了一些针对文本分类可能会问到的问题,大家可以自检一下。针对这些问题我们也可以做些准备,原理方面的需要自己实践印象会比较深刻;细节方面要自己梳理清楚,每做完一个项目要清楚自己的实验效果在该领域处于什么等级。对于一个任务,如果你不仅知道自己是怎么做的,还了解其他的实现方法,更了解方法之间的区别,懂得做横向比较,在面试过程中肯定可以给面试官留下深刻的印象。

因为看到有很多大学在校生和初学者都希望能多了解一些 NLP,所以下图是我做的资源推荐和成长建议总结。其中资源推荐的教材中第二本是关于神经网络和 NLP 方向的,很不错的一本书,非常建议大家去阅读一下。
最后这张图是我准备此次 Live 所使用到的一些资源,大家有兴趣也可以去了解一下,里面有对应的文章和视频。

Q&A:

Q1: NLP 工程师如何考虑在场景中要不要使用机器学习模型?

要不要使用机器学习模型,是由业务需求决定的。当业务刚启动的时候,没有标注数据,是没有办法使用模型的。这个时候用一些规则的方法把系统搭建起来,不断地积累语料,当积累到一定程度,也有人帮你做标注,那些规则不太能满足需求的时候,就可以考虑使用了。

Q2: 句向量现在一般怎么实现?

现在还没有一个非常好的模型或者方法可以保证句向量在所有的场景下都可以保持一个很好的表示效果。第一种可以根据句子中的每一个词的向量去做一些平均、加权运算,从而等到它的句向量,但是这种方法的效果一般都不是很理想。第二种方法是使用其他模型,把句子中的关键词的权重加重,非关键词的权重降低,从而得到句向量。第三种方法是根据语料和实现的任务设计一个神经网络抽取句向量,这也是目前效果最好的一种方法。第四种方法是将一个领域语料中得到的句向量迁移到其他领域使用,这种方法目前在实践中,但是具体的效果是和场景相关的。

Q3: NLP 工程师面试常见的题目是什么?

这个问题很难有一个明确的答案,一般还是根据简历来提问的。所以要非常熟悉自己简历上的项目。

Q4: NLP 在文本自动生成方面的研究进展?

今年上半年在有一篇 100 多页的综述文章,专门盘点了 NLP 方向以前和当前比较好的技术方法,大家可以自己搜索阅读一下。

Q5: 请问命名实体识别中,除了 NLTK 中的工具包,还有别的工具包或者方法么?

NLTK 中的工具对中文的支持不是很好,斯坦福的 CALL NLP 是支持中文的,但是它是在新闻语料上训练出来的,不一定合适你的。你可以自己用自己的语料训练一份,或者在 Github 上找用双向 LSTM+CRF 结构训练出来的 NER 模型。

Q6:请问 NLP 工程师需要对深度学习,机器学习的算法有深入的了解吗?能够调用这些方法吗?

其实调用这些包的话,是解决不了问题的,因为有时你会遇到模型效果很差,但是别人用这个模型效果比较好,那为什么你用就不行了呢,这个时候就要求你对模型的原理有一定了解,你要分析出可能存在的问题,可能是因为你数据域处理的不够回,可能是你参数调的不够合适,如果你不了解,只是当作黑盒来用,你是很难分析到具体的 case 的。

Q7:自然语言处理任务在应用深度学习模型时,在线 serving 是怎么做的?

因为我们用到的是 TensorFlow 框架,所以我们的 serving 也是 Tensor serving 那一套框架去做的,有时候我们离线训练完模型以后,要把模式文件导出来,然后用 Tensor serving 和 TF serving 去加载这个模型,然后用基于 C++ 和 PC 这套框架去扛线上的流量。

Q8:请问现在做意图识别,除了人工标注,有什么深度学习的方法可以实现自动标注么?

自动实现标注的方法一直都有,但是准确标注一直是一个疑问,现在我们意图识别模型,表示用双向 LSTM+Tensor 这样的结构,模型本身学习能力已经很强,所以很多时候决定意图识别准确率就是你虚拟豫章标注的准确性,所以如果你用自动标准,会使质量得不到保证,从而模型效果大打折扣,所以你需求去权衡。

Q9:LSTM 严格上说应该不是马尔可夫过程,马氏决策严格依赖前一部分过程,而 LSTM 过程是对所有前面的状态进行编码,进而预测输出。

LSTM 和马尔科夫过程确实不是同一回事,就我刚才说的 NLP 要解决的五个基本问题大部分都可以归类到这五个问题上,但并不是所有的问题都能归类上去,而且 LSTM 和马尔科夫过程也不是同一个层次上的概念,而 LSTM 是 LIN 的一个变种,而 LIN 是对任一层次上的序列进行建模的,它是一个技术上的实现,而马尔科夫过程是比较抽象的一个概念,一个是技术上的,一个是数学上比较抽象的概念,并没有划等号的必要性。

Q10:请问生成式的问答系统,怎么避免对同一个问题的回答千篇一律的情况?

这说的是应该是 sequence to sequence 框架的问题,sequence to sequence 的框架本身就存在这样的问题,因为那些通用的回复在豫章出现的频率会比较高,针对这个问题,有好几篇论文是专门来解决这个问题的,比如说其中一个思路就是重新定义损失函数,把那些预测会出现高频率的回复做乘法,这样它会倾向于增加回复的多样性。然后另外一个思路就是增加一些鲜艳的知识进去,所谓鲜艳的知识就是根据我对话的语料,把用户上一句话的主题词抽取出来,然后在用 decoding 的时候,用一些方法把主题词融入到我的解码过程当中,这样相当于把鲜艳的知识加进去以后,就会在主题词附近做解码,这样就一定程度上会避免回复出现千篇一律的情况,或者跟我想要表达的意思差别很大。


更多高质资源 尽在AIQ 机器学习大数据 知乎专栏 点击关注

转载请注明 AIQ - 最专业的机器学习大数据社区  http://www.6aiq.com