本文整理自知乎上的一个问答,分享给正在学习自然然语言处理的朋友们!

一、自然语言处理是什么?

自然语言处理说白了,就是让机器去帮助我们完成一些语言层面的事情,典型的比如:情感分析、文本摘要、自动问答等等。我们日常场景中比较常见到的类似Siri、微软小冰之类的,这些的基础都是自然语言处理,另外还有一些语音处理,这就暂且不表了。总之,你看到的机器与人利用语言交互,用机器模拟人脑阅读,对话,评论等等这些的基础都是自然语言处理的范畴之内。

二、自然语言处理怎么学?

自然语言处理的实际入门步骤来说,假如单单从应用来说,我觉得还是直接先从简单的应用搞起更好一点,上来就是理论的话可能对一些人还是比较枯燥,我认为一个好的过程是:实践-理论-实践,先由实践搞起,加深兴趣,然后理论研究,深化理解,最后继续实践,知行合一。闲言少叙,下面说下自己的入门步骤:

1、分词

针对中文而言(当然假如你处理英文,可直接跳过这一步),首先就是分词的问题,因为中文相对于英文,并不是空格分隔的,另外进行自然语言处理的相关实践,也不大可能直接一长段文本进行操作,所以分词还是首当其中的。分词的原理暂且不说(比如CRF、霍夫曼等等,有兴趣可自己去了解),这里主要推荐一下常用到(Java)的几个分词工具:

1)、HanLP 是一个中文自然语言处理的基础包,它囊括了包含分词在内的几乎所有的自然语言处理涉及的基础操作,同时工具包来说,分为data版和ptotable版,对于一般的分词而言,protable完全就可以满足要求。另外还有一些其他的操作,例如词性识别,也是实际应用中比较多的。当然其他的类似关键词提取,情感识别做个参考也就好了,实际还是要自己优化;

2)、LTP 是哈工大的一个分词组件,相较于HanLP而言,其包含的依存句法分析以及语义依存分析的方法,对于我们基于文本进行更高级一点的操作(比如提取句子的主语、谓语;行动关系等,另外基于此进行分词优化实践也有一定的提升),可以说是比较方便的;但是与此同时,LTP提供分词的方式是利用http接口的方式,这就让它在实际的应用中有那么一点落后,虽然它也提供了自搭服务的方式,但也逃不出请求接口。最后的最后,貌似现在已经和讯飞合作了,开放接口都需要申请,而且还不一定能用。。允悲。

3)、jieba 说起分词,就不得不提jieba,包括最基础的python版本,然后还有衍生出来的java版、C#版等等,实际使用起来也是比较方便,当然对于java版而言,它没有词性的功能,这也是我在实际应用中使用表少的一个原因吧。

另外,分词工具还有ansjStanfordNLP中工具等等,用的不多也就不瞎说了。

2、关键词提取

对于中文文本而言,分词完毕,接下来我们要做的事情,大致逃不出那么几件:关键词提取、句子相似性、文本摘要等,这其中一个比较典型的应用就是关键词提取。相应的实践方式主要有以下几种:

1)、TF-IDF 是关键词提取一个可以说是首先想到的解决方案,它说自己第二,没人敢说第一。当然它的理论也是比较好理解的,归结起来一句话:在一篇文本中那些不常出现(此处指的文本集)的词在当前文本中大量出现,那它就是关键词;TFIDF也相应的就是两个概念,想看理论,查查便知;具体到应用层级来说,对于大量文本,语料比较丰富的场景下,这种方式提取关键词来说,确实也是比较方便和准确的,但在语料不足的情况下,可能也就just soso了。但是思想是最重要的,这也是我们入门的基础。

2)、TextRank 是基于GooglePageRank的一个应用于文本的一个关键词提取算法,基于词语窗口的思想,利用相互投票的方式,提取文本关键词。TextRank有一个最大的好处就是不依赖额外文本,针对单篇文本,处理得当也就可以提取出看的过去的关键词,简单实用。关于其优化方式,比如改变词语网络窗口的大小,分词的预过滤,词性权重投票等等,都是一个不错的方向,效果也还算显著。其对应的实现都有开源的版本,GitHub上动动手就有了。

3)、LDA 从严谨的角度而言,它并不是一个提取关键词的方式,但是对于我们预先有一定分类的文本而言,利用LDA提取文本的中心词,或者说针对类别的关键词,某些情况下效果也是不错的。具体到实现上,Java开源的有JGIbbLDA、当然pythonscikit-learn,以及Spark Mllib中都包含了对应的LDA版本,可以一试。

具体到实际的使用场景,对于有大量语料,首推TF-IDF;对于单篇文本,当然还是TextRank;对于类别文本,LDA也不失为一种选择。总之,看你实际应用需求。

3、词向量

从关键词提取直接跳转到词向量,感觉是一个比较大的跳跃,但实际而言,词向量是我们后续进行机器学习或者深度学习的处理,因为机器处理的始终还是二进制,你不可能改变计算机底层的实现(当然说的是现在,没准后来有人就真成了呢,我们当那是一个美好的愿景吧)。词向量说白了,就是用向量的形式表示词,这就牵涉到一个问题了,我们怎么把一个中文词语转化成一个向量呢。这里主要有以下几种方式:

1)、词袋模型,顾名思义就是把所有的词都放进一个袋子里,然后指定每个词的位置。所以这样生成的向量,就是长度等同于单词总数,尽在词对应的位置置1,其他位置均为0。这样你也应该能想到,实际应用而言,不太现实。

2)、HashTF,对应词袋模型的困境,人们首先想到的就是怎么缩小向量的维度,同时表示相同的单词呢,HashTF的基本思想也就是为了解决这个问题,利用Hash的思想,将大量的单词映射到一个小维度向量中,来解读维度爆炸的问题,当然有利有弊,仍然不能很好的解决词语映射的问题。

3)、Word2Vec是工业上比较常用的一个词向量模型工具,也是实际应用中采用的。其思想包括CBOWSkip-Gram,基本思想都是词语和词语周围单词间的一个共现关系,它在一定程度上考虑了语境和语义的影响,是一个可以实际使用的工具。

概括来说,在我们后期利用机器学习或者深度学习处理问题的时候,词向量是我们必不可少的一步,word2vec也是我们可以考虑的一个比较不错的选择。

4、文本分类

文本分类是一个比较大的概念,具体到应用,其中包括了情感识别、敏感识别等,具体到实现方式,包括二类分类、多类别分类、多标签分类等。就是为了把一组文本按照指定要求利用机器进行区分。具体到实现算法而言,不胜枚举。。Spark Mllib中包含了大量的分类算法,可以进行实践,这也是入门的一种比较快速的方式,先会后懂然后深入。

5、自动问答

自动问答是一个比较热的概念,也是一个应用比较广泛的自然语言处理案例,当前业界最高水平R-Net已经可以达到80%多的准确率,已经是一个比较了不起的成就了,但是实际操作起来,也还是有一定难度,我也在不断摸索,暂时不瞎说了。

三、自然语言处理的深入

谈到自然语言处理的深入,这个可以做的就比较多了,上面列举的各个方面都与比较大的优化空间。但总体而言,最大的几个问题在于分词、词向量的转化以及文本特征的提取,这也是一定程序上困扰我们继续提高的几大阻碍。拿分词来说,无论是基于词典和算法的分词还是目前基于深度学习的分词方式,都只能说一定程度上进行分词实现,想要达到人脑的分词效果,实际上还是前路漫漫;词向量的转化在一定程序上也依赖于大量的语料,而我们也不可能在训练模型时囊括所有的词语,所有的语境,所有的文本,这些也都是不现实的,只能说时优化算法或者选择一种更好的方式;文本特征的提取也是一个我们在后期进行学习过程中一个绕不过去的坎。总而言之,自然语言处理说简单也简单,说难也难,就看你想要达到什么样的高度。

作者:郑海伦