Giter VIP home page Giter VIP logo

nlp_tutorial's Introduction

nlp_tutorial

前言

NLP自然语言处理,到底是怎么处理的,有哪些常用的方法和思路,恰逢项目需要,借由本篇教程梳理NLP解决实际问题的一般思路。

这篇教程期待你本身对于NLP的知识有一定的了解,知晓NLP包括哪些部分(词,句,段,篇章等),知晓NLP有哪些应用(相似度,分类,生成等),反正,你从这个项目里是看不到这些基础知识的。

相反,这里会给你描述一般情况下,项目中NLP需要面对的业务场景和需要解决的问题,以及可以采取的思路和方案,当然,还有亲自实践,有code。

NLP面临的常见业务场景

巨量的文本信息,可能是短文本,几句话;也可能是长文本,文章或新闻报道。而且通常样本没有标注,不读其文,难知其义,更难知其类别。而真实的需求,往往和业务紧密结合,需要从这些文本信息中获取某些有价值的业务数据,获取某种隐藏的规律等等。

具体场景中NLP的通用思路

没有标注的巨量文本数据,首先需要解决的就是文本的结构化。长文本由段落组成,段落其实相当于短文本,段落或者短文本由句子组成,句子则有词组成,词是NLP中的最小处理单元,所以NLP的关键,往往是分词。(这里只给解决思路,实际在分词前,还需要完成分段,断句等准备工作)

分词

分词的方法有多种,有基于词典的,有基于统计概率的,理论算法的描述网上不胜枚举,也可以看看吴军先生的《数学之美》。这里只告诉你,项目中应该怎么分词,有哪些开源项目可以帮助你。

实际项目中分词的过程可能是最最重要的。分词,是在为后续的处理准备最初级的原材料,这一步如果贴近业务,准确度高,就决定了后续的每一步都有一个可靠的基础,相反NLP的每一步都或多或少带有误差累积的顽疾,如果分词的准确度不高,后续的NLP处理也极难有较好的结果。

原始分词,工具可以使用jieba分词,当然,也可以使用HanLP,其中jieba是python实现的,HanLP是Java实现的,本身没有绝对的鸿沟,使用那个,随意就好。

选取开源工具的一个关键条件是:支持自定义词库!理由很明显,实际的业务场景总是有很多的专业名词,这些词不太可能在通用词库里有包含。比如:会议控制,业务场景里其实是一个词,但是通用的词库一般都会分成“会议”和“控制”两个词。

去除停用词

分词之后就要去除停用词,当然,这里停用词涵盖代词,副词等等。这里的去除停用词,更像是去除和语义关系不大的词,例如下面这段文本:

“我的电脑不能开机了,怎么办呢?请帮帮忙,谢谢~”

其实,关键信息就两个词:电脑(对象)不能开机(状态),当然,你也可以分成三个词,电脑+不能+开机,根据业务场景来定,如果不能开机在当下的场景里出现的可能性更高,最好就划为一个词。那么其他的文字信息呢,例如:我的,了,怎么办呢,请帮帮忙,谢谢,这些和当下场景的语义无关,必须要去除掉。

通过这个过程,可以发现,分词,以及去除停用词的标准和实际的业务场景有紧密的关系,所以,基于NLP来解决业务问题的前提就是要足够了解当前的业务场景。

去除停用词,也有开源工具可以使用,包括jieba等,不过这个逻辑比较简单,自己实现也未尝不可。

处理同义词或同类词

同义词,并不是传统意义上的同义词,正确的解释应该是基于具体的业务场景下可以彼此替换的词,比如在求助邮件的场景下,“**打不开”和“**打开失败”其实是一个意思,所以需要总结出业务场景下的一个同义词词典,然后对于分词的结果进行同义词替换,替换是比较粗暴的做法,但是对于后续生成词向量,计算相似度非常有效。

对于同义词的处理,也有比较细腻的方法,就是标注,对分词的结果进行同义词,同类词和相关词标注,标注的结果类似于这样:

去年底/t/ 国家/n/Di02A01= 深度/ns/Dn01A10= 贫困地区/n/

其中第一个标注的字段是词性,名称,动词,形容词等,第二个标注则是基于哈工大词义语料标注进行的同义,同类或相关词标注,哈工大的语料对应了5个层级的分类,标注的含义即是当前这个词属于5级分类的详细信息,细节可以参看:哈工大词林。后续在计算相似度上如果可以合理的应用词的标注信息,会对计算结果有较好的改进。

但是,必须强调一点,词标注并不是必须的,他是锦上添花,不是救命稻草。

最后,一定记得把词的处理结果保存下来。

这部分内容的练习代码在:TextPreparer.py


生成词向量

基于分词的结果就可以生成每一个词的词向量,这里列举目前比较流行的两种方式:TF-IDF和Word2Vec。

TF_TDF

TF-IDF的计算相对简单:(之所以要插个图片这么丑,因为github不支持LaTex,codecogs不支持中文导致的)

TF-IDF

也有不少开源工具支撑,常用的是scikit-learn,这里就不介绍用法了,scikit-learn的用户体验很友好,看看官方文档就能即可上手。

这部分的练习代码在:TF_IDF.py

Word2Vec

Word2Vec从原理上讲就要复杂一些,这东西是Google团队搞的一种算法,官网和源码在这里Word2Vec,内部算法有两种:CBOW(Continuous Bag of Words),Skip-gram。简单理解就是:

  • CBOW:根据上下文来预测词的概率,上下文所有词对于当前词出现概率的影响权重是一致的。
  • Skip-gram:正好相反,根据当前词预测上下文出现的概率。

到这里不要被算法迷糊了双眼,Word2Vec最终的输出依然是词向量,只不过这里的词向量是算法中概率最大的模型参数而已。

同样,Word2Vec也有很多开源工具的支持,除了Google开放的源码,还有gensimDeepLearning4J,其中gensim对于python友好,DL4J对于java友好。

最后还是要记住一点,把文档词向量矩阵合理的保存下来。

这部分的练习代码在:Word2Vec.py

文本聚类

面对浩如烟海的文本数据,文本聚类可以帮助你打开一扇模糊的小窗户,额,一般情况也只能是一扇小窗户。妄想通过文本聚类来解决业务问题直达彼岸往往是不现实的。

文本聚类可以给样本标注最最原始的标签,尽管这个标签不甚准确,业务上也没有太好的解释性,但是,这是一个开始,对于原始文本的一个初级加工,这一步输出的东西有两个:标签集合和被标签标注的样本。记住,这两个输出的准确性都有待商榷。

有了这两个东西,业务专家们才有了参与的理由,以前,面对堆积如山的文本数据,业务专家需要识别类别,标注标签,直白讲,没人愿意做这个事情,即乏味又无聊;现在,业务专家只需要修正标签集合,修正样本标注即可,不需要投入大量的人力,几个业务专家短期内就会有可观的产出。

扯了这么多,明确两点:

  • 文本聚类一定要做;
  • 不要浪费更多精力去提升文本聚类的精度。

那文本聚类怎么做呢?常用的算法:K-Means聚类和层次聚类算法。适用的场景略有不同,其中K-Means算法适用于样本的标签比较独立,也就是多数样本只有一个标签,标签多数属于同一个级别;层次聚类则适用于样本的标签有交叠,有层次结构,样本多数都包含多个标签。之所以有这种区别,主要是算法的思路决定的。

K-Means必须指定cluster的个数,然后基于初始样本根据欧式距离进行聚类计算;层次聚类没有初始指定Cluster个数的概念,只是基于某一个样本根据欧式距离的远和近进行合并和分裂,所以cluster具有层级结构。

实际情况,这两种算法的实验都是要做的,目的就是去探索样本本身的特点,这里的欧式距离其实不一定是范式距离,只要是评估相似度的指标都可以使用,例如cos等。

对于聚类,往往很难获取较好的结果,当然优化的点自然是模型使用的相似度的计算方法,不过,可以多尝试,不要偏执就好。实际工作中,还是建议尽快产出,尽快让业务专家参与进来。

对于K-Means和层次聚类的算法,在scikit-learn中都有现成的实现,调用即可。

这部分的练习代码在:K_Means_Cluster.pyHierarchical_Cluster.py

共性特征提取

当聚类的结果出来以后,我们依然没有获取cluster的文本描述,一般情况cluster的算法输出只有一个int型的标签。这个东西对于业务专家而言依然非常困扰,人工浏览几万甚至几十万的样本然后总结一个标签任谁都极难做到,即使可以做到也是耗时耗力的苦差事,所以,有必要通过机器学习的手段来降低这件事情的难度。

提取cluster中各个样本的共性特征,思路有多种,这里只介绍实践中相对靠谱的。还是那句话,没有万般皆准的方法,必须针对具体的业务场景进行定制化研究,这里依然以求助邮件为例子:

case1:我的邮箱最近只能找到一个月内的邮件,以前的邮件找不到了。

case2:我的邮箱不能搜索历史邮件。

case3:我这里原来有发件人什么的选项可以搜索,不见了,怎么添加?

通过文本聚类的方法,以上三个case被聚到一个cluster,暂且称这个cluster为1。从业务的角度描述这个cluster想表述的主题是:搜索问题或邮件丢失(允许多主题)。

我们的目标则是尽可能抽取到和业务总结的主题相接近的主题。方法有两个:LDA主题模型,基于句子依存关系和语义实体标注的主题抽取模型。

LDA主题模型

LDA模型的提出基于人类写作的思维规律:给定几个主题,然后学习主题对应的词,然后以一定概率选择某几个主题,再以一定概率选择主题对应的词,不断的重复这个过程,最后就可以生成一篇文档。那么对于LDA要做的事情,就是反其道而行之,给定一篇文章,推测其主题的分布。LDA模型是基于统计概率的模型,内部原理涉及到各种不同的概率分布函数,这里直接介绍实现方法:

文本分类

//todo:

多标签分类算法:magpie

###未完待续

nlp_tutorial's People

Contributors

fei090620 avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.