前  言

为什么要写这本书

自然语言处理是一门交叉学科,属于人工智能的一个分支,涉及计算机科学、语言学、数学等多个领域的专业知识。外行人很难入门这个小众的圈子,非科班出身的我对此深有体会。经典教材虽然高屋建瓴,但自学的话很难读懂,缺乏代码也无法落地;工程类书籍则往往侧重对开源项目的接口介绍,缺乏深度与宏观系统性。我曾经跟天书般的术语与公式顽强斗争,也在迷宫般的教学代码中苦苦挣扎。现在回顾自学历程,我才认识到:当时缺少一本面向普通人的入门书,走了许多弯路。

在我的开源自然语言处理项目 HanLP 流行起来后,我接触了大量 NLP 初学者,我看到不 少人碰到了我当初苦苦思索的问题。许多用户不理解“统计自然语言处理”的设计理念,对 “语料”“训练”“模型”等概念十分陌生。同时,如果你缺乏自然语言处理基础的话,也无法掌握 HanLP 中的高级功能。还有部分学习热情高涨的用户尝试阅读 HanLP 的代码,却反应即便代码有注释,也看不懂为什么要这么写……用户的问题和困惑越积越多,有些朋友建议我写一本 HanLP 的书。然而我认为一本书不应当局限于代码,而应当让读者知其所以然,而彼时我觉得自己才疏学浅,写不出满意之作。后来经过几年的完善,HanLP 成为 GitHub 上最受欢迎的自然语言处理项目,我对自然语言处理的理解也系统化了一些。正巧图灵的王军花老师跟我约稿,我想是时候将这些年的收获总结一下了。

这本书跟其他图书有什么不同

避免大而全式地泛泛而谈,又不拘泥于工程实践,这是我写作这本书秉持的原则。我希望这本务实的入门书,能够帮助零起点的你上手这门新学科,并且真正将自然语言处理应用在生产环境中。

书中不是枯燥无味的公式罗列,而是用白话阐述的通俗易懂的算法模型;书中不是对他人开源代码的堆砌,而是工业级开发经验的分享。

我以 HanLP 作者的身份,从基本概念出发,逐步介绍中文分词、词性标注、命名实体识别、信息抽取、文本聚类、文本分类、句法分析这几个热门问题的算法原理与工程实现。通过对多种算法的讲解和实现,比较各自的优缺点和适用场景。这些实现并非教学专用,而是生产级别的成熟代码,可以直接用于实际项目。

理解这些热门问题的算法之后,本书会引导你根据自己的项目需求拓展新功能,最终达到理论和实践上的同步入门。

书中还会穿插一些你在网络资料中难得一见的实现技巧,巧妙运用的话会成为你高效开发的秘诀。读完本书后,你不光会理解理论、掌握接口,还能成长为自然语言处理类库的设计者。

无论是书还是代码,我都坚持“递归深入”“延迟加载”(lazy loading)的思想,即只在使用的时候才去加载必要的资料。也就是说,全书是自顶而下循序渐进的:

● 你首先看到的是一个摸得着的实际问题,为了解决该问题才去接触一个具体方案;

● 为了理解这个方案,才会介绍必要的背景知识;

● 为了实现这个方案,才会介绍相关细节;

● 为了克服这个方案的问题,才会过渡到新的方案。

主要内容

本书是自包含的,编排上尊重一般人的认知规律而不是学术上的纲目顺序。本书面向普通程序员,将内容粗略划分为下图所示的三大部分。

图像说明文字

第一部分介绍一些字符串算法,让普通程序员从算法的角度思考中文信息处理。

第二部分由易到难地讲解一些常用的机器学习模型,让算法工程师晋级为机器学习工程师。这部分并非空谈理论,而是由中文分词这一应用问题贯穿始终,构成一种探索式的递进学习。这些模型也并非局限于中文分词,会在第三部分应用到更多的自然语言处理问题上去。

第三部分新增了许多与文本处理紧密相关的算法,让机器学习工程师进化到自然语言处理工程师。特别地,最后一章介绍了当前流行的深度学习方法,起到扩展视野、承上启下的作用。你也可根据自身情况,灵活跳过部分章节。

翻阅本书,你会得到观影一般的流式体验。我曾经也是一无所知的外行,自学时走过不少弯路,深知数学语言的艰深晦涩,并且痛恨罗列公式故作高深的文章,也不喜欢大而全的综述书籍。因此,我写了这本不太一样的入门书,将阅读体验排在学术规范之前。尽量用自然的语调讲几个具体算法,把每个算法讲清楚,力争做到让你在地铁上也能把书读完读懂。

图片、公式与配套代码

本书为双色印刷,我们根据图书的特点对大部分图片进行了双色处理,其中有些跟作者使用代码输出的原始图片样式略有区别,但是在表达上的效果一致。

本书只保留了必不可少的公式和推导,以确保你充分理解为选择标准。书中的数学符号约定在“目录”之前的“主要数学符号表”中单独给出了,建议开始阅读之前了解一下。书中公式与代码相互印证,配套代码由 Java 和 Python 双语言写成,与 GitHub 上的最新代码同步更新,分别位于 https://github.com/hankcs/HanLP/tree/v1.7.5/src/test/java/com/hankcs/book和https://github.com/hankcs/pyhanlp/tree/master/tests/book①。为保证兼容,读者也可以使用命令 git checkout v1.7.5切换到本书写作时的版本。对于 Java 代码,使用“类路径 # 方法名”来索引,比如 com.hankcs.book.ch01.HelloWord#main 表示源代码 HanLP/src/test/java/com/hankcs/book/ch01/HelloWord.java 中的 main函数。对于 Python 代码,使用“模块路径 . 方法名”来索引,比如 tests.book.ch01.hello_word.main 表示源代码 pyhanlp/tests/book/ch01/hello_word.py 中的main函数。引用整个源码文件时,则直接使用文件的相对路径。另外,区别于正文,配套代码在书中印刷的背景色为淡蓝色。

思维导图

为了让读者纵览 NLP 领域的宏观图景,也为了帮助读者梳理 NLP 知识点,我精心打磨了一份 NLP + ML “双生树”思维导图。这可能是目前你所见到的最为详尽的思维导图,印刷尺寸大约宽 60 厘米,高 74 厘米,它是随书附赠给你参考学习的。

你不仅可以从中了解 NLP 领域的详尽知识脉络,还可以彻底弄清楚 NLP 与 ML 知识点之间的关联。这些关联知识点不仅涵盖本书中的核心知识,甚至涉及许多前沿研究与应用。不论你处于入门还是进阶阶段,这份思维导图都可以帮你厘清学科脉络。放在手边,时常拿出来参考一下,会相当便利。

① 你也可以到图灵社区(ituring.cn)本书主页“随书下载”下载源代码文件。

教学讲义 PPT

本书为教师提供教学讲义 PPT。教师可凭借教师信息申请教学讲义,发送邮件至 liumy@ turingbook.com 即可。

关于封面

本书封面上的图案是一只蝴蝶形状的词云,由全书 60 个关键术语构成。蝴蝶同时也是码农场与 HanLP 的标志,为业内人士熟知。蝴蝶象征着蝴蝶效应、非线性与混沌理论——虽然微小,但足以改变世界。本书虽属入门读物,但希望能成为读者漫漫修行路上那只扇动翅膀的蝴蝶。

致谢

本书的撰写得到了许多亲友和老师的帮助。 感谢我的父母,为我创造舒适的写作环境。 感谢我的导师 Choi 教授,你严谨的教研态度深深地感染着我。 感谢图灵编辑王军花和英子,在书稿的审核过程中提出了许多细致入微的高标准建议。感谢夏志宏教授、周明副院长、李航博士、宗成庆教授、刘群教授、王斌教授、刘知远副教授、张华平副教授、@52nlp 为后辈小生作推荐。

感谢大快搜索创始人孙燕群、首席科学家汤连杰,为 HanLP 的研发提供诸多资源。

感谢开源社区的每一位用户与参与开发的黑客,是你们推动了中文信息处理在工业界的落地。

感谢每一位为本书做出贡献的朋友,我谨以此书作为回礼。

互动与勘误

虽然水平有限,但我对改进内容的热情是无限的。本书配套代码承诺与 HanLP 同步更新维护,欢迎大家积极参与开源项目。此外,也欢迎读者朋友们将对本书的评价和问题发在留言板https://forum.hankcs.com/ 或者图灵社区本书主页上,大家一起探讨,谢谢。

何晗

2019 年 7 月

目录

  • 推荐序
  • 推 荐 语
  • 前  言
  • 主要数学符号表
  • 第1章 新手上路
  • 第2章 词典分词
  • 第3章 二元语法与中文分词
  • 第4章 隐马尔可夫模型与序列标注
  • 第5章 感知机分类与序列标注 
  • 第6章 条件随机场与序列标注
  • 第7章 词性标注
  • 第8章 命名实体识别
  • 第9章 信息抽取 
  • 第10章 文本聚类
  • 第11章 文本分类
  • 第12章 依存句法分析
  • 第13章 深度学习与自然语言处理