赞
踩
NLP的全称是Natuarl Language Processing,中文意思是自然语言处理,是人工智能领域的一个重要方向
自然语言处理(NLP)的一个最伟大的方面是跨越多个领域的计算研究,从人工智能到计算语言学的多个计算研究领域都在研究计算机与人类语言之间的相互作用。它主要关注计算机如何准确并快速地处理大量的自然语言语料库。什么是自然语言语料库?它是用现实世界语言表达的语言学习,是从文本和语言与另一种语言的关系中理解一组抽象规则的综合方法。
人类语言是抽象的信息符号,其中蕴含着丰富的语义信息,人类可以很轻松地理解其中的含义。而计算机只能处理数值化的信息,无法直接理解人类语言,所以需要将人类语言进行数值化转换。不仅如此,人类间的沟通交流是有上下文信息的,这对于计算机也是巨大的挑战。
我们首先来看看NLP的任务类型,如下图所示:
主要划分为了四大类:
其中“类别”可以理解为是标签或者分类,而“序列”可以理解为是一段文本或者一个数组。简单概况NLP的任务就是从一种数据类型转换成另一种数据类型的过程,这与绝大多数的机器学习模型相同或者类似,所以掌握了NLP的技术栈就等于掌握了机器学习的技术栈。
传统方式和深度学习方式 NLP 对比
为了能够完成上述的NLP任务,我们需要一些预处理,是NLP任务的基本流程。预处理包括:收集语料库、文本清洗、分词、去掉停用词(可选)、标准化和特征提取等。
图中红色的部分就是NLP任务的预处理流程,有别于其它机器学习任务的流程
英文 NLP 语料预处理的 6 个步骤
中文 NLP 语料预处理的 4 个步骤
对于NLP任务来说,没有大量高质量的语料,就是巧妇难为无米之炊,是无法工作的。
而获取语料的途径有很多种,最常见的方式就是直接下载开源的语料库,如:维基百科的语料库。
但这样开源的语料库一般都无法满足业务的个性化需要,所以就需要自己动手开发爬虫去抓取特定的内容,这也是一种获取语料库的途径。当然,每家互联网公司根据自身的业务,也都会有大量的语料数据,如:用户评论、电子书、商品描述等等,都是很好的语料库。
示例数据源
每个机器学习问题都从数据开始,例如电子邮件,帖子或推文列表。常见的文字信息来源包括:
现在,数据对于互联网公司来说就是石油,其中蕴含着巨大的商业价值。所以,小伙伴们在日常工作中一定要养成收集数据的习惯,遇到好的语料库一定要记得备份(当然是在合理合法的条件下),它将会对你解决问题提供巨大的帮助。
我们遵循的首要规则是:“您的模型将永远与您的数据一样好。”
数据科学家的关键技能之一是了解下一步是应该对模型还是数据进行处理。一个好的经验法则是首先查看数据然后进行清理。一个干净的数据集将允许模型学习有意义的功能,而不是过度匹配无关的噪音。
我们通过不同的途径获取到了想要的语料库之后,接下来就需要对其进行清洗。因为很多的语料数据是无法直接使用的,其中包含了大量的无用符号、特殊的文本结构。
数据类型分为:
- 结构化数据:关系型数据、json等
- 半结构化数据:XML、HTML等
- 非结构化数据:Word、PDF、文本、日志等
需要将原始的语料数据转化成易于处理的格式,一般在处理HTML、XML时,会使用Python的lxml库,功能非常丰富且易于使用。对一些日志或者纯文本的数据,我们可以使用正则表达式进行处理。
正则表达式是使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。Python的示例代码如下:
- import re
-
- # 定义中文字符的正则表达式
- re_han_default = re.compile("([\u4E00-\u9FD5]+)", re.U)
-
- sentence = "我/爱/自/然/语/言/处/理"
-
- # 根据正则表达式进行切分
- blocks= re_han_default.split(sentence)
-
- for blk in blocks:
- # 校验单个字符是否符合正则表达式
- if blk and re_han_default.match(blk):
- print(blk)
输出:
- 我
- 爱
- 自
- 然
- 语
- 言
- 处
- 理
除了上述的内容之外,我们还需要注意中文的编码问题,在windows平台下中文的默认编码是GBK(gb2312),而在linux平台下中文的默认编码是UTF-8。在执行NLP任务之前,我们需要统一不同来源语料的编码,避免各种莫名其妙的问题。
如果大家事前无法判断语料的编码,那么我推荐大家可以使用Python的chardet库来检测编码,简单易用。既支持命令行:chardetect somefile
,也支持代码开发。
以下是用于清理数据的清单:
按照这些步骤并检查其他错误后,我们可以开始使用干净的标记数据来训练模型!
中英文分词的3个典型区别
区别1:分词方式不同,中文更难
英文有天然的空格作为分隔符,但是中文没有。所以如何切分是一个难点,再加上中文里一词多意的情况非常多,导致很容易出现歧义。下文中难点部分会详细说明。
区别2:英文单词有多种形态
英文单词存在丰富的变形变换。为了应对这些复杂的变换,英文NLP相比中文存在一些独特的处理步骤,我们称为词形还原(Lemmatization)和词干提取(Stemming)。中文则不需要
词性还原:does,done,doing,did 需要通过词性还原恢复成 do。
词干提取:cities,children,teeth 这些词,需要转换为 city,child,tooth”这些基本形态
区别3:中文分词需要考虑粒度问题
例如「中国科学技术大学」就有很多种分法:
粒度越大,表达的意思就越准确,但是也会导致召回比较少。所以中文需要不同的场景和要求选择不同的粒度。这个在英文中是没有的。
中文分词是一个比较大的课题,相关的知识点和技术栈非常丰富,可以说搞懂了中文分词就等于搞懂了大半个NLP。
中文分词的3大难点
难点 1:没有统一的标准
目前中文分词没有统一的标准,也没有公认的规范。不同的公司和组织各有各的方法和规则。
难点 2:歧义词如何切分
例如「兵乓球拍卖完了」就有2种分词方式表达了2种不同的含义:
难点 3:新词的识别
信息爆炸的时代,三天两头就会冒出来一堆新词,如何快速的识别出这些新词是一大难点。比如当年「蓝瘦香菇」大火,就需要快速识别。
中文分词经历了20多年的发展,克服了重重困难,取得了巨大的进步,大体可以划分成两个阶段,如下图所示:
词典匹配与规则
优点:速度快、成本低
缺点:适应性不强,不同领域效果差异大
基本思想是基于词典匹配,将待分词的中文文本根据一定规则切分和调整,然后跟词典中的词语进行匹配,匹配成功则按照词典的词分词,匹配失败通过调整或者重新选择,如此反复循环即可。代表方法有基于正向最大匹配和基于逆向最大匹配及双向匹配法。
基于统计与机器学习
优点:适应性较强
缺点:成本较高,速度较慢
这类目前常用的是算法是HMM、CRF等算法,比如stanford、Hanlp分词工具是基于CRF算法。以CRF为例,基本思路是对汉字进行标注训练,不仅考虑了词语出现的频率,还考虑上下文,具备较好的学习能力,因此其对歧义词和未登录词的识别都具有良好的效果。
常见的分词器都是使用机器学习算法和词典相结合,一方面能够提高分词准确率,另一方面能够改善领域适应性。
目前,主流的中文分词技术采用的都是基于词典最大概率路径+未登录词识别(HMM)的方案,其中典型的代表就是jieba
分词,一个热门的多语言中文分词包。
中文分词工具
下面排名根据 GitHub 上的 star 数排名:
英文分词工具
标准化是为了给后续的处理提供一些必要的基础数据,包括:去掉停用词、词汇表、训练数据等等。
当我们完成了分词之后,可以去掉停用词,如:“其中”、“况且”、“什么”等等,但这一步不是必须的,要根据实际业务进行选择,像关键词挖掘就需要去掉停用词,而像训练词向量就不需要。
词汇表是为语料库建立一个所有不重复词的列表,每个词对应一个索引值,并索引值不可以改变。词汇表的最大作用就是可以将词转化成一个向量,即One-Hot编码。
假设我们有这样一个词汇表:
- 我
- 爱
- 自然
- 语言
- 处理
那么,我们就可以得到如下的One-Hot编码:
- 我: [1, 0, 0, 0, 0]
- 爱: [0, 1, 0, 0, 0]
- 自然:[0, 0, 1, 0, 0]
- 语言:[0, 0, 0, 1, 0]
- 处理:[0, 0, 0, 0, 1]
这样我们就可以简单的将词转化成了计算机可以直接处理的数值化数据了。虽然One-Hot编码可以较好的完成部分NLP任务,但它的问题还是不少的。
当词汇表的维度特别大的时候,就会导致经过One-Hot编码后的词向量非常稀疏,同时One-Hot编码也缺少词的语义信息。由于这些问题,才有了后面大名鼎鼎的Word2vec,以及Word2vec的升级版BERT。
除了词汇表之外,我们在训练模型时,还需要提供训练数据。模型的学习可以大体分为两类:
根据不同的学习任务,我们需要提供不同的标准化数据。一般情况下,标注数据的获取成本非常昂贵,非监督学习虽然不需要花费这样的成本,但在实际问题的解决上,主流的方式还选择监督学习,因为效果更好。
带标注的训练数据大概如下所示(情感分析的训练数据):
- 距离 川沙 公路 较近 公交 指示 蔡陆线 麻烦 建议 路线 房间 较为简单 __label__1
- 商务 大床 房 房间 很大 床有 2M 宽 整体 感觉 经济 实惠 不错 ! __label__1
- 半夜 没 暖气 住 ! __label__0
其中每一行就是一条训练样本,__label__0
和__label__1
是分类信息,其余的部分就是分词后的文本数据。
为了能够更好的训练模型,我们需要将文本的原始特征转化成具体特征,转化的方式主要有两种:统计和Embedding。
原始特征:需要人类或者机器进行转化,如:文本、图像。
具体特征:已经被人类进行整理和分析,可以直接使用,如:物体的重要、大小。
目前常用的文本表示方式分为:
One-Hot 编码又称为“独热编码”或“哑编码”,是最传统、最基础的词(或字)特征表示方法。这种编码将词(或字)表示成一个向量,该向量的维度是词典(或字典)的长度(该词典是通过语料库生成的),该向量中,当前词的位置的值为1,其余的位置为0。
文本使用one-hot 编码步骤:
One-Hot 编码的特点如下:
缺点:
例句:
在词袋模型中不考虑语序和词法的信息,每个单词都是相互独立的,将词语放入一个“袋子”里,统计每个单词出现的频率。
词袋模型编码特点:
缺点
为了解决词袋模型无法区分常用词(如:“是”、“的”等)和专有名词(如:“自然语言处理”、“NLP ”等)对文本的重要性的问题,TF-IDF 算法应运而生。
TF-IDF 全称是:term frequency–inverse document frequency 又称 词频-逆文本频率。其中:
统计的方式主要是计算词的词频(TF)和逆向文件频率(IDF):
那么,每个词都会得到一个TF-IDF值,用来衡量它的重要程度,计算公式如下:
优点
缺点
理论基础:
n-gram 是一种 语言模型(Language Model, LM)。语言模型是一种基于概率的判别式模型,该模型的输入是一句话(单词的序列),输出的是这句话的概率,也就是这些单词的联合概率(joint probability)。(备注:语言模型就是判断一句话是不是正常人说的。)
首先指定窗口大小,然后统计窗口(和对称窗口)内词语共同出现的次数作为词的向量(vector)。
语料库:
备注: 指定窗口大小为1(即:左右的 window_length=1,相当于 bi-gram)统计数据如下:(I, like),(Iike, deep),(deep, learning),(learning, .),(I, like),(like, NLP),(NLP, .),(I, enjoy),(enjoy, flying), (flying, .)。则语料库的共现矩阵如下表所示:
从以上的共现矩阵可以看出,单词 like 和 enjoy 都在单词 I 附件出现且统计数目大概相等,则它们在 语义 和 语法 上的含义大概相同。
优点
缺点
word2vec 模型是Google团队在2013年发布的 word representation 方法。该方法一出让 预训练词向量 的使用在NLP 领域遍地开花。
word2vec模型
word2vec有两种模型:CBOW 和 SKIP-GRAM;
优点
缺点
GloVe 是斯坦福大学Jeffrey、Richard 等提供的一种词向量表示算法,GloVe 的全称是Global Vectors for Word Representation,是一个基于全局词频统计(count-based & overall staticstics)的词表征(word representation)算法。该算法综合了global matrix factorization(全局矩阵分解) 和 local context window(局部上下文窗口) 两种方法的优点。
备注:Glove模型的推导公式比较复杂,在这里不做详细推导,具体可以查看官网(https://nlp.stanford.edu/projects/glove/)。
效果
优点
缺点
word2vec 和 glove 算法得到的词向量都是静态词向量(静态词向量会把多义词的语义进行融合,训练结束之后不会根据上下文进行改变),静态词向量无法解决多义词的问题(如:“我今天买了7斤苹果” 和 “我今天买了苹果7” 中的 苹果 就是一个多义词)。而ELMO模型进行训练的词向量可以解决多义词的问题。
ELMO 的全称是“ Embedding from Language Models ”,这个名字不能很好的反映出该模型的特点,提出ELMO 的论文题目可以更准确的表达出该算法的特点“ Deep contextualized word representation ”。
该算法的精髓是:用语言模型训练神经网络,在使用word embedding 时,单词已经具备上下文信息,这个时候神经网络可以根据上下文信息对word embedding 进行调整,这样经过调整之后的word embedding 更能表达在这个上下文中的具体含义,这就解决了静态词向量无法表示多义词的问题。
网络模型
过程
效果
如上图所示:
NLP 的4个典型应用
大家不要被这些眼花缭乱的业务场景给搞晕了,其实上面的这些业务都是基于我们之前讲的NLP预处理的输出,只是应用了不同的机器学习模型,比如:SVM、LSTM、LDA等等。
这些机器学习模型大部分是分类模型(序列标注也是一种分类模型),只有少部分是聚类模型。这些模型就是泛化的了,并不只是针对于NLP任务的。要想讲清楚这部分内容,就需要另开一个关于“机器学习入门”的主题,这里就不过多的展开了。
小结:只要大家掌握了NLP的预处理,就算入门NLP了,因为后续的处理都是一些常见的机器学习模型和方法。
NLP是一个非常有挑战性的工作,同时也是一个非常有发展空间的工作,所以大家只要克服了前期的入门门槛,那么迎接你的将是一片广阔的天地。道阻且长,行则将至。
安利一下掘金小册《深入理解NLP的中文分词:从原理到实践》,它将系统的帮助你学习NLP的中文分词的相关知识,而中文分词对于NLP的重要意义,通过本文大家也应该十分清楚了。掌握中文分词的技术,不仅对于提高NLP任务的结果质量有很大的帮助,同时对于理解机器学习也有很大的促进作用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。