作者 | 兰红云
责编 | 何永灿
自然语言处理和大部分的机器学习或者人工智能领域的技术一样,是一个涉及到多个技能,技术和领域的综合体.
所以自然语言处理工程师会有各种各样的背景,大部分都是在工作中自学或者是跟着项目一起学习的,这其中也不乏很多有科班背景的专业人才,因为技术的发展实在是日新月异,所以时刻要保持着一种强烈的学习欲望,让自己跟上时代和技术发展的步伐.本文作者从个人学习经历出发,介绍相关经验.
一些研究者将自然语言处理(NLP,Natural Language Processing)和自然语言理解(NLU,Natural Language Understanding)区分开,在文章中我们说的 NLP 是包含两者的,并没有将两者严格分开.
图 1 自然语言处理工程师技能树
自然语言处理学习路线
数学基础
数学对于自然语言处理的重要性不言而喻.当然数学的各个分支在自然语言处理的不同阶段也会扮演不同的角色,这里介绍几个重要的分支.
代数
代数作为计算数学里面很重要的一个分支,在自然语言处理中也有举足轻重的作用.这一部分需要重点关注矩阵处理相关的一些知识,比如矩阵的 SVD,QR 分解,矩阵逆的求解,正定矩阵,稀疏矩阵等特殊矩阵的一些处理方法和性质等等.
对于这一部分的学习,既可以跟着大学的代数书一起学习,也可以跟着网上的各种公开课一起学习,这里既可以从国内的一些开放学习平台上学,也可以从国外的一些开放学习平台上学.这里放一个学习的链接,网易公开课的链接: https://c.open.163.com/search/search.htm?query= 线性代数 #/search/all.(其他的资料或者平台也都 OK).
概率论
在很多的自然语言处理场景中,我们都是算一个事件发生的概率.这其中既有特定场景的原因,比如要推断一个拼音可能的汉字,因为同音字的存在,我们能计算的只能是这个拼音到各个相同发音的汉字的条件概率.也有对问题的抽象处理,比如词性标注的问题,这个是因为我们没有很好的工具或者说能力去精准地判断各个词的词性,所以就构造了一个概率解决的办法.
对于概率论的学习,既要学习经典的概率统计理论,也要学习贝叶斯概率统计.相对来说,贝叶斯概率统计可能更重要一些,这个和贝叶斯统计的特性是相关的,因其提供了一种描述先验知识的方法.使得历史的经验使用成为了可能,而历史在现实生活中,也确实是很有用的.比如朴素贝叶斯模型,隐马尔卡模型,最大熵模型,这些我们在自然语言处理中耳熟能详的一些算法,都是贝叶斯模型的一种延伸和实例.
这一部分的学习资料,也非常丰富,这里也照例对两种概率学习各放一个链接,统计学导论 http://open.163.com/movie/2011/5/M/O/M807PLQMF_M80HQQGMO.html ,贝叶斯统计: https://www.springboard.com/blog/probability-bayes-theorem-data-science/ .
信息论
信息论作为一种衡量样本纯净度的有效方法.对于刻画两个元素之间的习惯搭配程度非常有效.这个对于我们预测一个语素可能的成分(词性标注),成分的可能组成(短语搭配)非常有价值,所以这一部分知识在自然语言处理中也有非常重要的作用.
同时这部分知识也是很多机器学习算法的核心,比如决策树,随机森林等以信息熵作为决策桩的一些算法.对于这部分知识的学习,更多的是要理解各个熵的计算方法和优缺点,比如信息增益和信息增益率的区别,以及各自在业务场景中的优缺点.照例放上一个链接: http://open.163.com/special/opencourse/information.html .
数据结构与算法
这部分内容的重要性就不做赘述了.学习了上面的基础知识,只是万里长征开始了第一步,要想用机器实现对自然语言的处理,还是需要实现对应的数据结构和算法.这一部分也算是自然语言处理工程师的一个看家本领.这一部分的内容也是比较多的,这里就做一个简单的介绍和说明.
首先数据结构部分,需要重点关注链表,树结构和图结构(邻接矩阵).包括各个结构的构建,操作,优化,以及各个结构在不同场景下的优缺点.当然大部分情况下,可能使用到的数据结构都不是单一的,而是有多种数据结构组合.比如在分词中有非常优秀表现的双数组有限状态机就使用树和链表的结构,但是实现上采用的是链表形式,提升了数据查询和匹配的速度.在熟练掌握各种数据结构之后,就是要设计良好的算法了.
伴随着大数据的不断扩张,单机的算法越来越难发挥价值,所以多数场景下都要研发并行的算法.这里面又涉及到一些工具的应用,也就是编程技术的使用.例如基于 Hadoop 的 MapReduce 开发和 Spark 开发都是很好的并行化算法开发工具,但是实现机制却有很大的差别,同时编程的便利程度也不一样.
当然这里面没有绝对的孰好孰坏,更多的是个人使用的习惯和业务场景的不同而不同.比如两个都有比较成熟的机器学习库,一些常用的机器学习算法都可以调用库函数实现,编程语言上也都可以采用 Java,不过 Spark 场景下使用 Scala 会更方便一些.因为这一部分是偏实操的,所以我的经验会建议实例学习的方法,也就是跟着具体的项目学习各种算法和数据结构.最好能对学习过的算法和数据结构进行总结回顾,这样可以更好的得到这种方法的精髓.因为基础的元素,包括数据结构和计算规则都是有限的,所以多样的算法更多的是在不同的场景下,对于不同元素的一个排列组合,如果能够融会贯通各个基础元素的原理和使用,不管是对于新知识的学习还是对于新解决方案的构建都是非常有帮助的.
对于工具的选择,建议精通一个,对于其他工具也需要知道,比如精通 Java 和 MapReduce,对于 Spark 和 Python 也需要熟悉,这样可以在不同的场景下使用不同的工具,提升开发效率.这一部分实在是太多,太广,这里不能全面地介绍,大家可以根据自己的需求,选择合适的学习资料进行学习.这里给出一个学习基础算法(包含排序,图,字符串处理等)的课程链接: https://algs4.cs.princeton.edu/home/ .
语言学
这一部分就更多是语文相关的知识,比如一个句子的组成成分包括:主,谓,宾,定,状,补等.对于各个成分的组织形式也是多种多样.比如对于主,谓,宾,常规的顺序就是:主语→谓语→宾语.当然也会有:宾语→主语→宾语(饭我吃了).这些知识的积累有助于我们在模型构建或者解决具体业务的时候,能够事半功倍,因为这些知识一般情况下,如果要被机器学习,都是非常困难的,或者会需要大量的学习素材,或许在现有的框架下,机器很难学习到.如果把这些知识作为先验知识融合到模型中,对于提升模型的准确度都是非常有价值的.
在先期的研究中,基于规则的模型,大部分都是基于语言模型的规则进行研究和处理的.所以这一部分的内容对于自然语言处理也是非常重要的.但是这部分知识的学习就比较杂一些,因为大部分的自然语言处理工程师都是语言学专业出身,所以对于这部分知识的学习,大部分情况都是靠碎片化的积累,当然也可以花一些精力,系统性学习.对于这部分知识的学习,个人建议可以根据具体的业务场景进行学习,比如在项目处理中要进行同义词挖掘,那么就可以跟着 "百科" 或者 "搜索引擎" 学习同义词的定义,同义词一般会有什么样的形式,怎么根据句子结构或者语法结构判断两个词是不是同义词等等.
深度学习
随着深度学习在视觉和自然语言处理领域大获成功,特别是随着 AlphaGo 的成功,深度学习在自然语言处理中的应用也越来越广泛,大家对于它的期望也越来越高.所以对于这部分知识的学习也几乎成为了一个必备的环节(实际上可能是大部分情况,不用深度学习的模型,也可以解决很多业务).
对于这部分知识,现在流行的几种神经网络都是需要学习和关注的,特别是循环神经网络,因为其在处理时序数据上的优势,在自然语言处理领域尤为收到追捧,这里包括单项 RNN,双向 RNN,LSTM 等形式.同时新的学习框架,比如对抗学习,增强学习,对偶学习,也是需要关注的.其中对抗学习和对偶学习都可以显著降低对样本的需求,这个对于自然语言处理的价值是非常大的,因为在自然语言处理中,很重要的一个环节就是样本的标注,很多模型都是严重依赖于样本的好坏,而随着人工成本的上升,数据标注的成本越来越高,所以如果能显著降低标注数据需求,同时提升效果,那将是非常有价值的.
现在还有一个事物正在如火如荼地进行着,就是知识图谱,知识图谱的强大这里就不再赘述,对于这部分的学习可能更多的是要关注信息的链接,整合和推理的技术.不过这里的每一项技术都是非常大的一个领域,所以还是建议从业务实际需求出发去学习相应的环节和知识,满足自己的需求,链接 http://www.chinahadoop.cn/course/918 .
自然语言处理现状
随着知识图谱在搜索领域的大获成功,以及知识图谱的推广如火如荼地进行中,现在的自然语言处理有明显和知识图谱结合的趋势.特别是在特定领域的客服系统构建中,这种趋势就更明显,因为这些系统往往要关联很多领域的知识,而这种知识的整合和表示,很适合用知识图谱来解决.随着知识图谱基础工程技术的完善和进步,对于图谱构建的容易程度也大大提高,所以自然语言处理和知识图谱的结合就越来越成为趋势.
语义理解仍然是自然语言处理中一个难过的坎.目前各项自然语言处理技术基本已经比较成熟,但是很多技术的效果还达不到商用的水平.特别是在语义理解方面,和商用还有比较大的差距.比如聊天机器人现在还很难做到正常的聊天水平.不过随着各个研究机构和企业的不断努力,进步也是飞速的,比如微软小冰一直在不断的进步.
对于新的深度学习框架,目前在自然语言处理中的应用还有待进一步加深和提高.比如对抗学习,对偶学习等虽然在图像处理领域得到了比较好的效果,但是在自然语言处理领域的效果就稍微差一些,这里面的原因是多样的,因为没有深入研究,就不敢妄言.
目前人机对话,问答系统,语言翻译是自然语言处理中的热门领域,各大公司都有了自己的语音助手,这一块也都在投入大量的精力在做.当然这些上层的应用,也都依赖于底层技术和模型的进步,所以对于底层技术的研究应该说一直是热门,在未来一段时间应该也都还是热门.之前听一个教授讲过一个故事,他是做 parser 的,开始的时候很火,后来一段时间因为整个自然语言处理的效果差强人意,所以作为其中一个基础工作的 parser 就随之受到冷落,曾经有段时间相关的期刊会议会员锐减,但是最近整个行业的升温,这部分工作也随之而受到重视.不过因为他一直坚持在这个领域,所以建树颇丰,最近也成为热门领域和人物.
所以在最后引用一位大牛曾经说过的话:"任何行业或者领域做到头部都是非常有前途的,即使是打球,玩游戏."(大意)
个人经验
笔者是跟着项目学习自然语言处理的,非科班出身,所以的经验难免会有偏颇,说出来仅供大家参考, 有不足和纰漏的地方敬请指正.
知识结构
要做算法研究,肯定需要一定的知识积累,对于知识积累这部分,我的经验是先学数学理论基础,学的顺序可以是代数→概率论→随机过程.当然这里面每一科都是很大的一个方向,学的时候不必面面俱到,所有都深入理解,但是相对基础的一些概念和这门学科主要讲的是什么问题一定要记住.
在学习了一些基础数学知识之后,就开始实现--编写算法.这里的算法模型,建议跟着具体的业务来学习和实践,比如可以先从识别垃圾邮件这样的 demo 进行学习实验,这样的例子在网上很容易找到,但是找到以后,一定不要看看就过去,要一步一步改写拿到的 demo,同时可以改进里面的参数或者实现方法,看看能不能达到更好的效果.个人觉得学习还是需要下苦功夫一步一步模仿,然后改进,才能深入的掌握相应的内容.对于学习的资料,上学时期的各个教程即可.
工具
工欲善其事必先利其器,所以好的工具往往能事半功倍.在工具的选择上,个人建议,最高优先级的是 Python,毕竟其的宣传口语是:人生苦短,请用 Python.第二优先级的是 Java,基于 Java 可以和现有的很多框架进行直接交互,比如 Hadoop,Spark 等等.对于工具的学习两者还是有很大的差别的,Python 是一个脚本语言,所以更多的是跟着 "命令" 学,也就是要掌握你要实现什么目的来找具体的执行语句或者命令,同时因为 Python 不同版本,不同包对于同一个功能的函数实现差别也比较大,所以在学习的时候,要多试验,求同存异.
对于 Java 就要学习一些基础的数据结构,然后一步一步的去编写自己的逻辑.对于 Python 当然也可以按照这个思路,Python 本身也是一个高级编程语言,所以掌握了基础的数据结构之后,也可以一步一步的实现具体的功能,但是那样好像就失去了 slogan 的意义.
紧跟时代
自然语言处理领域也算是一个知识密集型的行业,所以知识的更新迭代非常的快,要时刻关注行业,领域的最新进展.这个方面主要就是看一些论文和关注一些重要的会议,对于论文的获取,Google Scholar,arxiv 都是很好的工具和资源(请注意维护知识产权).会议就更多了 KDD,JIST,CCKS 等等.
来源: http://geek.csdn.net/news/detail/252082