ZMonster's Blog 巧者劳而智者忧,无能者无所求,饱食而遨游,泛若不系之舟

NLP哪里跑: 什么是自然语言处理

本文是《NLP 哪里跑》系列的第二篇文章,系列文章如下:

  1. NLP哪里跑: 开篇及一些碎碎念 · ZMonster's Blog
  2. NLP哪里跑: 什么是自然语言处理 · ZMonster's Blog
  3. NLP哪里跑: Unicode相关的一些小知识和工具 · ZMonster's Blog
  4. NLP哪里跑: 文本分类工具一览 · ZMonster's Blog

什么是自然语言处理

  • 教授:“你笑什么?”
  • Z:“老师,学自然语言处理是我从小的梦想,能在这里我很开心!”
  • 教授:“用不着开心,给自然语言处理下个定义。”
  • Z:“能帮助我们理解自然语言的技术就是自然语言处理。”
  • 教授:“能说详细点吗?”
  • Z:“自然语言处理能帮我们理解人类的语言。你写了一篇文章,编辑器告诉你有些字写错了,这是自然语言处理;来了一封邮件,分个类告诉你这是垃圾邮件,这是自然语言处理;在输入框里输入‘香农’两个字,搜索引擎把香农的百科、学术成果展示在你面前,这是自然语言处理;你发了一条微博,说‘我想连任你的男朋友’,被微博自动删掉了,这是自然语言处理;你写论文从英文文献里抄了一段,用谷歌翻译转成中文放到自己论文里,这是自然语言处理;你对着 iPhone 说「hey siri 定 7 点钟的闹钟」,7 点钟 siri 提醒你该起床了,这是自然语言处理……”
  • 教授(生气):“净说废话!定义是什么!?”
  • Z:“我刚说了呀,老师。”
  • 教授:“考试你也这样?自然语言处理是,连任你的男朋友?白痴!换个人回答!”
  • M:“老师,自然语言处理可以定义为研究在人与人交际中以及在人与计算机交际中的语言问题的一门学科。自然语言处理要研制表示语言能力和语言应用的模型,建立计算框架来实现这样的语言模型,提出相应的方法来不断完善这样的语言模型,根据这样的语言模型设计各种实用系统,并探讨这些实用系统的评测技术。”
  • 教授:“太棒了!好极了!”

以上是一则瞎编的小品,套用了《三傻》中 Rancho 被教授问及“什么是机械装置”的场景。电影里通过这个场景里教授和“优等生”的死板与 Rancho 的灵活风趣之间的对比,来抨击僵硬死板的教育体制。不过电影总归是电影,它批评的问题我们要承认是客观存在的,但 Rancho 的行为是作为与一个极端对立的另一个极端来呈现并强化冲突和矛盾的,在我们认识事物、学习知识时,机械式地死板记忆固然不可取,毫无章法纯凭个人感性认识也不是什么值得鼓励的行为。

那么什么是自然语言处理呢?

自然语言处理,即 Natural Language Processing,简称 NLP ,是一门旨在利用计算机技术来理解并运用自然语言的学科。在不同的场景下,有时候也称之为计算语言学(Computational Linguistics, CL)或者自然语言理解(Natural Language Understanding, NLU)。

要理解 NLP 这个领域,只要紧紧抓住这几个要点就好

  1. NLP 主要通过计算机技术来进行

    在底层理论层面,NLP 会涉及数学、语言学、认知科学等多个学科,但在最后一般是通过计算机技术来承载这些理论知识并发挥效果的。

    看起来好像是废话,但仍然要在此进行强调,计算机和人脑不同,它有其优点也有其缺点,而 NLP 技术也会受到现在计算机技术优缺点的影响。因此不要用我们人脑处理自然语言的过程和效果来要求 NLP 技术 —— 对我们中的绝大部分人来说,使用语言是很自然、很简单的,但不要因此就觉得用计算机来处理也会很简单。

  2. NLP 要理解和运用的,是自然语言

    所谓「自然语言」是指在我们的世界中自然地演变出来的语言,比如说英语、汉语、法语……之所以称之为「自然语言」,是为了和程序设计语言(如 C 语言、Java 语言、Python 语言等)等人造的语言进行区分。

    程序设计语言是有非常明确的、固定的语法的,用程序设计语言写出来的每一个句子,都会有唯一确定的含义,因此计算机只需要按照语法规则对其进行解析并执行就好了。

    自然语言则不同,它有相对稳定的语法规则,但这些语法规则都会存在例外而且一直在演变,加上其他一些特性,经常会出现歧义。处理歧义是 NLP 中非常核心的一部分内容。

  3. NLP 试图理解自然语言,但何谓「理解」其实并没有一个确定的标准

    理想意义上的「理解」自然语言,是要求 NLP 可以像人脑一样理解自然语言,然而现在脑科学研究上对于我们在使用语言时大脑是如何运作的,并没有一个系统的、全面的认识。因此这也就不能称之为一个标准,实际上在现有的技术框架下,用计算机做到完全理解自然语言,是不可能的。

    退而求其次的,我们一般认为只要在特定的场景中,机器能对我们用自然语言表达的要求进行正确的响应,就是理解了自然语言。

    注意这里有几个前提

    • 「在特定的场景中」:一般我们认为,在限制了场景后,人们的目的以及语言的表达也会受到限制,因此能把语言表达的多样性降低,这样理解才具备可能性
    • 「进行了正确的响应」:我们认为机器的行为符合预期就是理解了,并不关心这中间的过程是否和人脑的运作机制是否一致、是否真正意义上的理解了语言的内涵

    当然,这只是现在实际的 NLP 系统所遵循的标准,事实上还是有人从语言学、脑科学等不同角度尝试确定「理解」的过程和标准,让我们保持关注、期待未来吧。

  4. NLP 在理解自然语言之后还有加以运用,因此凡是有用计算机来处理、分析自然语言的应用,我们都可以说它是一个 NLP 过程 —— 当然有可能不止是 NLP。

接下来我将根据这几点来讨论一下

  1. NLP 有哪些困难和限制
  2. NLP 有哪些主要的应用
  3. NLP 有哪些主要的技术

自然语言处理的困难和限制

我们每天都在使用自然语言,并不会对「理解自然语言」这件事情的困难之处有太多认识,但实际上,自然语言自身的一些特性,给计算机理解自然语言这件事情带来了非常多的困难。

第一个特性是自然语言中普遍地存在歧义现象,这种歧义体现在多个层面:

  1. 在语言的最小单元也就是词语的级别,存在多义词、同义词等现象

    比较经典的是 20 世纪 60 年代一位早期的机器翻译研究者给出的经典例子

    The box is in the pen.
    

    我们虽然可能不太清楚 pen 的另外一个含义是「围栏」,但肯定能意识到这句话中 pen 的含义不是「笔」。这个 badcase 从提出到现在已经有 50 多年了,但我们可以看到,仍然没有翻译系统能够在不加特殊处理的情况下解决这个问题(换言之这个 badcase 是可以通过特殊而丑陋的手段来解决的)。

    Google 翻译 google-translate.png

    百度翻译 baidu-translate.png

    搜狗翻译 sogou-translate.png

    与之相对的,中文里有一个例子是「意思」这个词的多义性

       他说:“她这个人真有意思(funny)。”她说:“他这个人怪有意思(funny)的。”于是人们认为他们有了意思(wish),并让他向她意思意思(express)。他火了:“我根本没有那个意思(thought)!”她也生气了:“你们这么说是什么意思(intention)?”事后有人说:“真有意思(funny)。”也有人说:“真没意思(nosense)”。(原文见《生活报》1994.11.13 第六版)
    

    当然,上述两个例子都是经过人为设计的精巧例子,大部分人们日常活动中使用的语言,并不会这么复杂。

    多义词之外,同义词也是非常普遍的语言现象,如:词语的缩写(如「人影办」之于「人工影响天气办公室」)、专有名词的别名(如「感冒」之于「上呼吸道感染」)、网络用语(如「蓝瘦」之于「难受」)、方言(如「包谷」之于「玉米」)、口语和书面语(如「脑袋」之于「头部」)……在 NLP 应用中,对同义词的辨别和处理工作也是非常多的,如:搜索引擎会通过查询改写(Query Rewrite)来将用户的搜索改写为同样含义但表述更为精准的语句;知识图谱里的实体链接技术本质上就是将实体名称(如人名、地名)的不同形式的表达和标准的表达对应起来;智能对话里可以通过同义词来更好地理解用户的问题……

    而在多义词、同义词理解上,目前 NLP 领域并没有一劳永逸的解决办法,有靠人工构建的小规模高质量知识库如 WordNet、HowNet、同义词词林,也有靠机器学习方法从大量语料中学习到词语的向量表示来隐式地反映词义 —— 量大但并不足够精确。前者往往质量很好但只能覆盖人们实际语言中很小的一部分,后者依赖于语料的数量、质量和领域,对于语料中较少出现的一些词往往就会得到莫名其妙的结果。

  2. 在句子乃至更高层的语言单元如段落、篇章里,又存在结构性歧义的现象

    以句子为例,它是由词组成的,词和词之间有些是有关联的、有些是没有关联的,因此整体会形成一个结构,也就是我们在学习语言时了解到的「语法」。

    理想的情况下,任意给定一个句子,如果它的语法结构是唯一、确定的,那么我们只需要把它这个语法结构计算出来,然后再把前面提到的同义词、多义词的问题也解决了,那么这个句子的含义就能确定了。但实际情况是,自然语言的语法规则并不是一个非常严格的规则,在句子比较复杂的时候,往往会造成句子可以有多种不同但都合理的解释。

    举一些例子

    • “喜欢乡下的孩子” 可以有下面两种解释
      • [喜欢/乡下]的/孩子: “喜欢乡下的”作为定语修饰“孩子”
      • 喜欢[乡下/的/孩子]: “乡下的孩子”作为“喜欢”的宾语
    • “他背着总经理和副总经理偷偷地把钱存进了银行” 可以有下面 2 种解释
      • 他[背着/总经理/和/副总经理]偷偷地/把/钱/存进/了/银行: “他”独自存钱
      • 他[背着/总经理]和/副总经理/偷偷地/把/钱/存进/了/银行: “他”和“副总经理”一起存钱
    • “放弃美丽的女人让人心碎” 可以有下面 2 种解释
      • [放弃/美丽/的]女人/让/人/心碎: “女人”让人心碎
      • [放弃/美丽/的/女人]让/人/心碎: “放弃”让人心碎

    再看英文的一个经典例句: "Put the block in the box on the table"。它可以有两种解释:

    • Put the block [in the box on the table]: "on the table" 修饰 "box"
    • Put [the block in the box] on the table: "on the table" 限定 "block"

    如果再加上一个介词短语 "in the kitchen",那么它可以有 5 种不同的解释;再增加一个的话,将会得到 14 种不同的解释。就这个介词短语导致歧义的情况来说,可能的歧义结构数量基本上是随着介词短语数量的增加而呈指数级上升。「指数级上升」是什么概念?那意味着想要靠枚举所有的可能性来解决歧义是非常低效甚至不可能的。

上述两种情况互相组合,又会造成更多、更复杂的歧义情况。

正如前文所说,如何处理歧义并排除歧义,是 NLP 中非常主要的一部分内容,而且是非常困难的一部分,这是因为造成语言歧义的原因多种多样。

造成词语歧义的原因,前面已经说过了一部分,也就是缩写、别名、网络用语、方言、口头语和书面语这几个;除此以外,比喻、拟人、谐音等手法也会使已有的词产生新的含义或和原来不相关的词产生同义;还有省略、指代等依赖上下文的情况也容易造成歧义……总之造成词语歧义的情况是非常多的。

在词义消歧这个问题上,除了造成歧义的情况多种多样外,还有一个困难是消歧经常依赖于文本之外的、海量的「常识」,比如说前面那个机器翻译的例子「The box is in the pen」,我们为什么能判断「pen」的含义不是「笔」,是因为我们具备这些知识

  1. 盒子是有体积的
  2. 笔不是一个容器
  3. 相对盒子,笔一般都更小

并由此推理出:盒子在笔中是不合理的。但是抱歉,这种我们认为是常识的知识,计算机并不具备,它是无法作出这种推理的。我们说的机器学习、深度学习,本质上还是依赖于数据,也就是说,要见过相同的或者相近的数据,它才能理解,对于知识本身则基本没有学习到。

在 NLP 发展历程中,也有人耗费巨大精力和金钱来将我们说的知识和规则整理成计算机可操作的数据,如 CycDBpediaFreebase,并演变成我们现在所说的知识图谱(其实以前就叫「知识库(Knowledge Base)」的,「Knowledge Graph」最早是 Google 的一个知识库的名字),但在 NLP 任务比如说词义消歧中,如何使用这些知识,仍然是一个很大的问题。

至于结构歧义或者说语法歧义,其原因也可能有几方面

  1. 当其中的词语有歧义时,这个词的不同词义可能具有不同的语法功能,而造成最终的语法结构不同,如前文的例句「放弃美丽的女人让人心碎」的两个不同解释中,「美丽」一词分别作为名词和形容词,而造成了不同的语法解析结果
  2. 自然语言语法本身并不是确定性的,即存在一些情况,哪怕其中每个词的词性、词义都是确定无疑的,可以得到的合理的语法解析结果也会有多个,前面那个「他背着总经理和副总经理偷偷地把钱存进了银行」的例句和那个英文例句就是这种情况

再加上语言一直在演变,新的语法规则不断出现,比如原来认为是错误的语法因为被普遍使用而被接受为新的语法规则,比如原有的语法规则被简化称为更简单的语法规则。这就导致很多语法规则都会有例外,而很多例外逐渐又成为了新的语法规则,就造成了「所有规则都有例外,所有例外都是规则」的现象。这就导致如果我们如果想靠语法规则来完成任务的话,最终就会陷入不停补充新的语法规则(或说例外)的境地里。

前面说了歧义这个自然语言的特性,而自然语言还有一个很重要的特性,就是前面提到的语言的动态演变。除了它给带来的歧义现象,更重要的是,由于语言的动态演变,新的知识、语言现象一直在出现,如何捕获、学习到这些新的知识和语言规则,对 NLP 来说,同样是非常大的一个挑战,因为如果不能学习到新的语言知识,那么建立在旧数据上的 NLP 模型,往往连基本的分析都做不到,更别谈去解决歧义并理解了。

此外,对中文、日文等一些语言来说,还有特殊的一点,就是在文字中,词和词不是天然就分隔开的。出于效果和效率等多方面的考虑,现有的 NLP 方法基本都建立在词的基础上,所以对中文这些语言来说,还需要对文字进行额外的、确定词和词之间边界的处理,也就是我们常说的「分词(Word Segmentaion)」。而分词这个过程本身,又存在不确定性,即同一个句子,可能的分词结果不一定是唯一的。

先看看这些例子

  1. “梁启超生前住在这里” 可能有两种分词结果
    • 梁启超/生前/住/在/这里
    • 梁启/超生/前/住/在/这里
  2. “武汉市长江大桥” 可能有两种分词结果
    • 武汉/市长/江大桥
    • 武汉市/长江/大桥
  3. “阿拉斯加遭强暴风雪袭击致多人死亡” 可能有两种分词结果
    • 阿拉斯加/遭/强/暴风雪/袭击/致/多人/死亡
    • 阿拉斯加/遭/强暴/风雪/袭击/致/多人/死亡
  4. “已取得文凭的和尚未取得文凭的干部” 可能有两种分词结果
    • 已/取得/文凭/的/和/尚未/取得/文凭/的/干部
    • 已/取得/文凭/的/和尚/未/取得/文凭/的/干部
  5. “今后三年中将翻两番” 可能有两种分词结果
    • 今后/三年/中将/翻/两番
    • 今后/三年/中/将/翻/两番

可以看到,仅仅是分错一两个词,整个句子的含义就完全不一样了。中文分词的困难在于,如果要正确地进行分词,就要对句子的语义有正确的理解;另一方面,要正确理解句子的语义,又需要正确的分词结果。于是就出现了一个先有鸡还是现有蛋的问题。

虽然有上述诸多困难,但 NLP 领域也形成了相应的应对方法,不过也只能说是「应对」而非「解决」,因为这些方法的目的都是追求解决上述问题在实际应用中常见的一部分,使对应的 NLP 系统能在受限场景中正确处理绝大部分比如 80% 或者 90% 的自然语言;而剩下未能处理的部分,则可以通过系统、产品上的一些设计,根据用户行为把它们找出来,加以研究并更新技术,如此逐渐迭代,来让 NLP 系统逐渐达到令人满意的效果。

自然语言处理的主要应用和关键技术

我们比较熟知的一些比较成体系的 NLP 应用,有

  • 机器翻译: 将一种自然语言的文字转换成另外一种自然语言的文字
  • 信息检索: 从海量的文档里检索出我们需要的信息,搜索引擎如 Google/Bing/Baidu 就是非常典型的信息检索系统
  • 文本摘要: 从较长的文档或文章中生成篇幅更小但内容完整的摘要
  • 智能对话: 通过对话的形式直接自动回答用户的问题或者执行特定的行为
  • 垃圾邮件过滤: 将垃圾邮件筛选出来并进行标记
  • 與情分析: 检测民众对公共事件的意见、态度、情感等倾向

当然实际上 NLP 的应用是非常多的,限于篇幅这里只讨论一下上述比较主要的应用。

上面六个 NLP 应用,其实可以划分成两类,一类是需要理解文本的完整语义并作出响应,如机器翻译、文本摘要和智能对话;另一类只需要理解文本中特定的信息就可以,对于文本的完整语义并不太关心,比如信息检索、垃圾邮件过滤和與情分析。当然我这样划分并不太严格,比如说搜索引擎里也会有人用自然语言去描述自己的问题并期望得到正确的结果,而垃圾邮件过滤和與情分析有时候也需要在理解完整语义的基础上再去提炼「特定信息」,但大部分情况下我认为这样划分是没有问题的。

在第一类即机器翻译、文本摘要和智能对话中,前两者都有明确的目标和评估标准,比如机器翻译有 BLEU 指标,文本摘要有 ROUGE 指标,而智能对话至今仍没有一个通用的评估标准,要么是借用一下机器翻译的 BLEU,要么是在特定的对话形式和对话任务里制定特殊的标准 —— 比如任务型对话里的槽填充率、检索型问答里的命中率和召回率。一个真正可用的智能对话系统,必然是一个融合系统,既有任务型问答也有检索型问答,说不定还会有开放域闲聊,那么在这样一个融合的系统里,各扫自家门前雪肯定是不行的,所以就现在来说,智能对话会比机器翻译和文本摘要要难一点 —— 倒不是说技术上难,而是难在确定目标和评估标准上。

在第二类即信息检索、垃圾邮件过滤、與情分析这三者中,與情分析除了要分析出情感、态度倾向,还要确定这种倾向针对的是什么对象,所以相比信息检索和垃圾邮件过滤,又会更难一点。

总的来说,在大部分情况下,对于 NLP 的应用,可以按照下面的原则来判断其难易程度

  • 需要理解完整语义的任务,要比只需理解部分信息的任务更难
  • 有确定目标和评估标准的任务,要比没有的更容易
  • 要做复杂分析的任务,要比只做简单分析的任务更难

在技术方面,各个应用会涉及的更底层的关键 NLP 技术如下:

  • 早期基于规则的翻译系统: 句法分析
  • 统计机器翻译: 语言模型,隐马尔可夫模型(HMM,早期被广泛用于序列标注)
  • 神经网络机器翻译: seq2seq,注意力模型
  • 信息检索: 大量的文本预处理,实体抽取,主题模型,文本相似度量,知识图谱
  • 检索型的问答系统: 同信息检索,但还需要进行指代消解、省略消解
  • 任务型的问答系统: 意图识别,实体抽取,指代消解,省略消解,对话状态管理,自然语言生成
  • 垃圾邮件过滤: 文本分类
  • 與情分析: 观点词抽取,情感分析,关系抽取,意见挖掘
  • 文本摘要: (这个不太清楚,略过)

上面的东西就是罗列一下以便形成整体印象,实际上像机器翻译和文本摘要我都没有做过,所以里面的关键技术我说不了太多,而信息检索、智能对话方面我相对有经验一些因此就写得比较多。

虽然各个应用的目标都不一样,但最后我们会发现它们用到的很多方法都是共通或者干脆是一样的。

最基础的,各个应用在开始前都需要对文本做预处理,不过预处理是一个很宽泛的概念,并没有一个或一套特定的方法,就我个人经验来说,因为处理的都是汉语,所以基本上都会做简繁统一转换,会把全角字符转成半角字符,会做标点的归一化处理(我才不会告诉你希腊字母里的问号在外形上和英文的分号一个样子呢),会去除一些无效的字符(比如说不可见的零宽度的空白符);英文里则会做词干提取、词形还原。很多讲 NLP 的文章说到预处理都会说停用词(stopwords)去除 —— 所谓停用词是指在特定领域里使用频率很高且往往不表达语义的词,如「了」、「的」,但实际上不是所有的应用上都需要去停用词、都可以去停用词的,比如说在作者身份鉴别这个应用上,是重度依赖虚词、介词等所谓功能词的,而在 NLP 里,虚词、介词这种词一般都会被视作停用词。

预处理的目的是让文本变得更「干净」,少一些「脏东西」,同时尽量更加地规范,所以有时候也会把预处理形象地称为「清洗」。好的预处理能减少干扰信息,并且保留重要信息,同时一些规范化处理(如繁简统一转换、标点归一化处理、英语的词干提取和词形还原)还能够减少后续步骤需要处理的信息量。

在做完预处理后,一般就是变着花样从文本里提取信息出来,以机器学习的角度来讲就是特征提取。根据不同的应用,这一步可能会非常简单,也可能会非常复杂。

最初始的一个处理,就是从文本里,把词都提取出来,这一步对英文等语言来说很自然,按空格和标点分一下就好了,而对中文来说则需要专门做中文分词,这个是前面提到过的。从计算语言学的角度来讲,分词是「词法分析」的一部分,所谓「词法分析」除了确定词和词之间的边界,还需要确定词性(一个词是动词、名词还是别的什么)、词义(「苹果」是一种水果还是一种电子产品),通俗一点来说,就是要解决: 哪些是词,有哪些词,各个词都是什么意思。

分词的方法有多种,简单的如准备好一个超大的词表,然后在这个词表里找可能拼成当前这句话的词,然后在多种可能的组合里确定一个最有可能的,看着很粗暴但其实也还可以。不过现在主流上都是将分词当作序列标注问题来处理。所谓序列标注是说,给一个序列,模型能给这个序列上每一个元素都标注成为一个特殊的记号,对分词而言,要标注的记号可以有三种: 是不是词的第一个字,是不是词的最后一个字,是不是词中间的字。

序列标注问题并不是 NLP 中特有的,但有不少 NLP 任务或技术都和序列标注有关,刚才说到的分词和词性标注(确定词性),基本上都是当作序列标注问题来处理。除此以外,实体抽取或者更复杂的信息抽取,也被视为序列标注问题。所以如果是作为一个 NLP 从业人员,序列标注问题的相关方法,是必须要掌握的,建议 HMM、CRF、RNN 的原理摸熟吃透,掌握一两个好用的序列标注工具,囤点序列标注问题的数据集打磨一下自己的感觉。

虽然说主流的方法都是将分词当作序列标注问题来做,但在实践中,囤点词典还是有益无害的,比如说做做新词挖掘、同义词挖掘、领域实体词的积累等等。至于怎么做这些挖掘、积累,各个应用有各个应用的做法,比如说搜索引擎靠 query 点击日志能把同义词或近义词找出来,原理就是类似两个人用了不同的词去搜索,但最后都点击了同一个链接这种思路;没有搜索引擎这样比较方便的用户反馈的,可以通过一些无监督或半监督的方法来做,会更难一些但总之是有方法的。

做完词法分析后,一般会有一些不同的后续处理

  1. 区分哪些词是重要的,哪些词是不重要的,可能涉及到关键词提取、实体抽取、停用词去除等
  2. 分析哪些词之间是有关联的,哪些词之间是没有关联的,可能涉及到短语抽取、关系抽取、句法分析等
  3. 基于词对整个文本进行分类得到一个高度抽象的结果,可能涉及情感分析、意图识别、主题分类等

实体抽取前面说了,可以当作序列标注问题来做。停用词去除没什么好说的,一般就是在通用的一个停用词表的基础上,统计一下数据中高频的词加进去而已。关键词提取我觉得是很重要的一件事情,不过大部分情况下用 TFIDF 就能提取出不错的关键词来了,在此基础上辅以之前词法分析的一些结果如词性基本上就能把关键词捋得差不多,基本上名词、动词、形容词、实体词拿出来做关键词就差不多了。

这里说到了 TFIDF,这个也是 NLP 里非常经典非常重要的一个技术,思路是很简单的,就是说对一个词,用两个数值来反映其在某篇文档或者某个句子里的重要程度,第一个是所谓词频(Term Frequency, TF),即这个词在当前文档/句子中出现的次数;第二个是所谓逆文档频率(Inverse Document Frequency, IDF),指出现过这个词的文档/句子的数量的倒数。通俗来说,就是,一个词在其他文档/句子里越少出现(IDF 值比较大),在当前文档/句子中越多出现,那么它在当前文档/句子中就越重要。很朴素的思想,实际上这个思路最终是可以用信息熵来解释的,总之很实用。

短语抽取、关系抽取和句法分析都是为了得到文本中的层次结构以更好地理解语义。其中短语抽取较简单,因为只需要看前后两个词是否有关系就好了,而关系抽取和句法分析都需要分析不相邻的词之间是否存在关联。这块不太熟,只是用过相关工具。不过我的观点是,句法分析是理解语义非常核心非常重要的一件事情,一个好的句法分析系统或工具,能够大大提高整个系统的效果。

然后是情感分析、意图识别、主题分类这些技术,其实大部分情况下都是文本分类在不同应用场景里的别名而已。文本分类是一个相对简单但应用非常广泛的技术,也是一块值得花精力去好好掌握的内容,逻辑回归、支持向量机、GBDT,然后是深度学习常见的分类模型结构,把这些都好好掌握一下,并且在实际数据中熟练掌握好预处理、特征提取、特征选择的流程和技巧,受用无穷。至于说深度学习不用特征的都是傻蛋,我分类的时候用深度学习一样能把特征加上去,就是比你不加好,爱调不调。

上述技术,基本上就能把任务相关的「理解」做得差不多了。在理解之后,一般还会有涉及应用的更具体的响应处理,如机器翻译、文本摘要、智能对话中会有自然语言生成,信息检索及检索型问答系统会有文本相似度量。

其中自然语言生成(Natural Language Generation, NLG)至今仍然是一个很困难的问题,在技术上,有基于统计语言模型的生成方法,也有基于神经网络语言模型的生成方法,近几年的变分自编码器(Variational Auto-Encoder, VAE)和基于强化学习的生成方法使用得也越来越多了。但这里说的 NLG 多是在特定任务中,基于前面已经有的分析结果来生成较短的文本,至于生成小说什么的,看看都没有媒体和公司去吹就知道是多么难的一件事情了。

这里提到了语言模型,也是一块可以好好掌握一下的内容。

然后就是文本相似度量,也是非常重要的一项 NLP 技能。某种意义上来说,它和 NLP 的终极目标是等价的。如果任意给定两个句子,一个 NLP 系统能够准确地判断这两个句子是相似还是不相似,那么它就已经是一个完全理解自然语言的系统了。以机器翻译为例,其 BLEU 指标,就是判断翻译出来的句子,和给定的标准翻译是否相似,但实际上其计算方法很简单只是计算了表面相似,所以 BLEU 指标也并不是非常准确,在实际应用中还是要靠人来评估实际效果,但是这么多年了学术界和业界也并没有找到比 BLEU 更好多少的指标,所以将就用着,倒是也有 AMBER 和 METEOR 这种不光看表面相似的评估标准,但是计算太复杂了,所以并没有成为公认的标准。假如有一天有更好的评估标准能和人为评估效果更加接近,那才是机器翻译的大突破。

文本相似的困难对很多非技术人员或者非 NLP 领域人员来说也经常难以理解,“这两个句子就是一个意思为什么就不理解呢”这样的话也是经常能听到的。理解一下,它真的很难。

简单的、传统的相似度量有 LCS 相似度、Jaccard 系数、余弦相似度等,都是久经考验非常实用的方法,应对一些简单的任务措措有余,当然这些方法基本上都是看表面相似,所以泛化性会差一些,需要不断补充特征才能提高效果。如果有足够数据的话,一些基于深度学习的匹配模型会有非常不错的效果,这个不错不光是指其在固定的测试集上的效果,在集外数据的泛化性上都会很不错,当然前提是要有米。

文本相似度量的应用也是很多的,在机器翻译和文本摘要里可以用来评估系统效果,在信息检索和智能对话里可以用来匹配正确的文档或问题,甚至有些时候一些分类任务也可以用文本相似度量来解决(有 A 类数据 1000 条 B 类数据 1000 条,判断下和 A 类数据更像还是和 B 类数据更像)。

另外一方面,除了给定两个句子判断其相似程度外,相似句子的挖掘和生成,也是很有意思的一件事情。生成相似问题这件事情,专业的说法叫做「复述(Paraphrase)」,它和相似度量是互相促进的,相似度量做的好,那么就可以挖掘出更多的相似句子来做训练复述生成模型;复述生成做的话,反过来又可以给相似度量模型提供训练数据。

对于深度学习在 NLP 中的应用,比较核心的技术有

  1. word embedding,也就是我们俗称的词向量,通过大量数据无监督(不需要标注)训练,可以用一个向量来表示一个词的词义,理想情况下如词性、词义、情感、主题等各种信息都可以在这个向量中得到表达 —— 当然这只是一个感性认识,目前对于这个向量实际的含义和解释,我们并不太关心,好用就对了。此外 word embedding 因为能比较好地反映词义,还可以用来做关键词、同义词挖掘,在各项深度学习相关的 NLP 任务中,基本也是标配了
  2. 序列标注方面,BiLSTM+CRF 已经是很主流的做法
  3. seq2seq 和 attention,这两个技术都是在神经网络机器翻译的研究中被提出来的,然后也被广泛用到如智能问答、文本摘要等重要 NLP 应用上。这两者一般是一起出现的,现在已经演变成了一种计算框架,具体的方法和细节则已经有了很多的变化
  4. 自然语言生成方面前面提到过 VAE 和强化学习,近一年内生成对抗网络(Generative Adversarial Nets, GAN)也开始有在这方面的应用

深度学习相关的技术一般都会需要比较多的数据,但我们会发现在实际的任务中,可能并没有那么多数据来让我们上深度学习,或者数据太多但却包含了太多噪音数据。土豪的办法是用金钱来为所欲为顺便创造点特殊岗位造福社会,对这件事情我是举双脚支持的。比较经济的做法是先使用前面提到的传统的、经典的方法,同时在产品、系统的上设计好良好的反馈渠道,在冷启动后不断进行迭代优化,同时有意识地从日志、用户反馈中积累数据,到达一定的量后开始上深度学习来解决传统模型泛化性不够好的问题。