自然语言处理实战
上QQ阅读APP看书,第一时间看更新

1.2 神奇的魔法

能够读写自然语言的机器有什么神奇之处呢?自从发明计算机以来,机器一直在处理语言。然而,这些“形式”语言(如早期语言Ada、COBOL和Fortran)被设计成只有一种正确的解释(或编译)方式。目前,维基百科列出了700多种编程语言。相比之下,Ethnologue[2]已经确认的自然语言总数是当前世界各地人们所用的自然语言的10倍。谷歌的自然语言文档索引远超过1亿吉字节[3],而且这只是索引而已,当前在线的实际自然语言内容大小肯定超过1000亿吉字节[4],同时这些文档并没有完全覆盖整个互联网。但是自然语言文本数量之庞大并不是使自然语言文本处理软件开发十分重要的唯一原因。

自然语言处理真的很难,能够处理某些自然事物的机器本身却不是自然的。这有儿点像使用建筑图来建造一个有用的建筑。当软件能够处理不是为了机器理解而设计的语言时,这看上去相当神奇,我们通常认为这是人类独有的一种能力。

“自然语言”与“自然世界”中“自然”一词的意义相同。世界上自然的、进化的事物不同于人类设计和制造的机械的、人工的东西。能够设计和构建软件来阅读和处理大家现在正在阅读的语言,该语言正是关于如何构建软件来处理自然语言的,这非常高级,也十分神奇。

为了让后续处理更加容易,我们只关注一种自然语言——英语。当然,大家也可以使用从本书中学到的技术来处理任何语言,甚至对于这种语言大家完全不懂,或者它还没有被考古学家和语言学家破译。本书也将展示如何仅仅使用一种编程语言Python,来编写程序以处理和生成自然语言文本。

Python从一开始就被设计成一种可读的语言,也公开了很多其内部语言处理机制。上述两个特点使Python成为学习自然语言处理的一个很自然的选择。在企业级环境下为NLP算法构建可维护的生产流水线时,Python也是一种很棒的语言,在单个代码库上有很多贡献者。甚至在某些可能的地方,Python是代替数学和数学符号的“通用语言”。毕竟,Python可以无歧义地描述数学算法[5],设计它的目标就是针对你我这样的程序员,使其尽可能地具备可读性。

1.2.1 会交谈的机器

自然语言不能直接被翻译成一组精确的数学运算集合,但是它们确实包含可供提取的信息和指令。这些信息和指令可以被存储、索引、搜索或立即使用。使用方式之一可能是生成一段词语序列对某条语句进行回复。这属于后面将要构建的“对话引擎”或聊天机器人的功能。

下面我们只关注英文书面文本文档和消息,而非口语。这里绕过了从口语到文本的转换——语音识别,或语音转文本(即STT)过程。同样,我们也略过语音生成或称文本转语音,即将文本转换回语音的过程。当然,由于存在很多语音转文本及文本转语音的免费库,大家仍然可以使用本书学到的内容来构建像Siri或Alexa一样的语音交互界面或虚拟助手。Android和iOS移动操作系统也提供了高质量的语音识别和生成API,并且有很多Python包也能在笔记本电脑或服务器上实现类似的功能。



语音识别系统

如果你想自己构建一个定制化的语音识别或生成系统,那么这项任务本身就需要一整本书来介绍。我们可以把这个作为练习留给读者。要完成这样的系统,需要大量高质量的标注数据,包括带有音标拼写注释的语音记录以及与音频文件对齐的自然语言转写文本。从本书中学到的一些算法可能会对建立这样的系统有所帮助,但大部分语音识别和生成算法和本书中的有很大区别。



1.2.2 NLP中的数学

从自然语言中提取有用的信息可能会很困难,这需要乏味的统计记录,但这正是机器的作用所在。和许多其他技术问题一样,一旦知道答案,解决起来就容易多了。机器仍然无法像人类一样精确可靠地执行很多实际的NLP任务,如对话和阅读理解。因此,大家需要对从本书中学到的算法进行调整来更好地完成一些NLP任务。

然而,在执行一些令人惊讶的精细任务上,本书介绍的技术已经足够强大,根据它们构建的机器在精度和速度上都超过了人类。举例来说,大家可能猜不到的是,在对单条Twitter消息进行讽刺识别上,机器比人类更精确[6]。大家不要担心,由于人类有能力保留对话的上下文信息,因此仍然更善于识别连续对话中的幽默和讽刺。当然,机器也越来越善于保留上下文。如果大家想尝试超过当前最高水平的话,本书将帮助大家把上下文(元数据)融入NLP流水线中。

一旦从自然语言中提取出结构化的数值型数据——向量之后,就可以利用各种数学工具和机器学习工具。我们可以使用类似于将三维物体投影到二维计算机屏幕的线性代数方法,这些方法早在NLP自成体系之前就被计算机和绘图员所使用了。这些突破性的想法开启了一个“语义”分析的世界,即让计算机能够解释和存储语句的“含义”,而不仅仅是对其中的词或字符计数。语义分析和统计学一起可以有助于解决自然语言的歧义性,这里的歧义性是指词或短语通常具有多重含义或者解释。

因此,从自然语言文本中提取信息和构建编程语言的编译器完全不同(这一点对大家来说很幸运)。目前最有前景的技术绕过了正则语法(模式)或形式语言的严格规则。我们可以依赖词语之间的统计关系,而不是逻辑规则表述的深层系统[7]。想象一下,如果必须通过嵌套的 if…then语句树来定义英语语法和拼写规则,大家能撰写足够多的规则来处理词、字母和标点符号一起组成句子的每一种可能方式吗?大家能捕捉语义,即英语语句的意义吗?虽然规则对某些类型的语句有用,但可以想象一下该软件是多么的有局限性和脆弱,一些事先不曾意料到的拼写或标点符号会破坏或扰乱基于规则的算法。

此外,自然语言还有一个更难解决的所谓“解码”挑战。用自然语言说话和写作的人都假定信息处理(听或者读)的对象是人而非机器。所以当人们说“早上好”时,肯定假想对方已经对“早上”的含义有所了解,即早上不仅包括中午、下午和晚上之前的那个时段,也包括午夜之后的那个时段。同时,大家需要知道,这些词既可以代表一天中的不同时间,根据一般经验,也可以代表一天中的一段时间。可以假定解码器知道“早上好”只是一个普通的问候语,而没有包含关于“早上”的任何信息,相反,它反映了说话者的精神状态以及与他人交谈的意愿。

这种关于人类如何处理语言的思维理论后来被证实是一个强有力的假设。如果我们假设人类的语言“处理器”拥有人类一生关于世界的常识,我们就能用很少的话表达很多信息。这种信息压缩率仍非机器的能力可及。在NLP流水线中也没有明确的“思维理论”可以参照。不过,我们将在后面的章节中介绍一些技术,这些技术可以帮助机器构建常识的本体与知识库,它们可以用于理解依赖这些知识的自然语言语句。