自然语言处理入门实践

自然语言处理入门实践

人工智能领域中有两个主流方向即机器视觉(CV)和自然语言处理(NLP)。其中自然语言处理(英语:Natural Language Processing,缩写作 NLP)是人工智能和语言学领域的分支学科。自然语言处理领域主要探讨如何处理及运用自然语言。自然语言处理包括多方面和步骤,基本有认知、理解、生成等部分。下面介绍一些NLP的基础知识。

分词

  提到自然语言处理当然不得不提大名鼎鼎的自然语言处理工具包NLTK了。NLTK在国外很流行,它提供包括英文分词、词性标注、命名实体的识别等等自然语言处理中的基本操作。如果各位想体验NLTK你可以通过pip install nltk来安装nltk。
​  但是nltk只支持英文分词,如果想对中文进行切词还得另谋他法。英文分词很方便,直接按照空格分割字符串就可以切出token字串,但是汉语是没有使用空格来分割词语。所以我给大家提供了一下几种汉语分词解决方案。

  1. 使用斯坦福大学分词器+nltk包,完美解决nltk对汉语的兼容。
  2. 使用jieba分词。
  3. 使用哈工大语言技术平台的python封装包pyltp

  本人经常用的是jieba分词工具和哈工大的分词器pyltp。首先jieba分词工具分词的速度非常快,这一点可谓是完胜pyltp,而且jieba分词的准确率也和pyltp非常接近。但是jieba分词工具终究只是一个分词工具。它不支持一些高级的功能比如命名实体识别,语义角色标注等。所以如果只需要分词而不需要命名实体识别那就尽量使用jieba分词,有其它需求再使用pyltp。

  你可以通过pip安装jieba和pyltp,jieba的安装非常简单,使用一个pip安装就可以了。但是pyltp的安装就没那么容易了,你除了需要安装pyltp还需要下载一个数据包,这个数据包提供了分词需要的一些词典。为了下载这个数据包你需要去Pyltp在Github主页下载整个项目,然后把项目中的ltp_data文件夹存放到一个固定位置方便以后调用。另外pyltp的具体调用方法可以前往Pyltp的官网学习。jieba分词的调用方法可以直接前往它在Github主页查看。

下面我简单介绍一下jieba分词工具的使用:

代码:

# coding:utf-8
import jieba

text = "青年一代有理想、有本领、有担当,国家就有前途,民族就有希望。"
tokens = jieba.lcut(text)
print(tokens) 

运行结果:

Building prefix dict from the default dictionary ...
Loading model from cache C:\temp\jieba.cache
Loading model cost 1.020 seconds.
Prefix dict has been built succesfully.
['青年一代', '有', '理想', '、', '有', '本领', '、', '有', '担当', ',', '国家', '就', '有', '前途', ',', '民族', '就', '有', '希望', '。']

停用词

  什么是停用词呢?停用词就是在信息检索中,为节省存储空间和提高搜索效率,在处理自然语言数据(或文本)之前或之后会自动过滤掉某些字或词,这些字或词即被称为停用词(Stop Words)。 这些停用词都是人工输入、非自动化生成的,生成后的停用词会形成一个停用词表。但是,并没有一个明确的停用词表能够适用于所有的工具。甚至有一些工具是明确地避免使用停用词来支持短语搜索的。

  简单来说就是对我们处理自然语言过程中没有帮助的词汇,例如“哈哈”、“不仅”、“如果”等。这些词蕴含的信息很少,所以在NLP中我们通常会将它们从分词结果中去掉。

  那么怎么获取停用词表呢?首先你可以谷歌一下,网上有很多停用词表。不过如果你想为了方便的话可以使用我提供给你的停用词表。https://pan.baidu.com/s/1o8VFnTK
说明:

停用词表每一行就是一个停用词且该停用词表即包括标点符号也包括普通停用词。

那么有怎么去除停用词呢?

你可以通过下面代码加载停用词,其中stopwords.txt就是停用词文件。

1
stopwords = [line.strip() for line in open('stopwords.txt', 'r', encoding='utf-8').readlines()]

TF-IDF

  tf-idf(英语:term frequency–inverse document frequency)是一种用于信息检索与文本挖掘的常用加权技术。tf-idf是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。tf-idf加权的各种形式常被搜索引擎应用,作为文件与用户查询之间相关程度的度量或评级。除了tf-idf以外,互联网上的搜索引擎还会使用基于链接分析的评级方法,以确定文件在搜索结果中出现的顺序。

  tf是term frequency的缩写,也就是词频的意思;而idf是inverse document frequency的缩写,也就是逆词频的意思。 我大概解释一下,通常一个句子中不同的词蕴含着不同的信息,且他们的重要性是不相同的。通常一个词语在一个文本中出现的次数越高说明它就越重要,反之越不重要。这是有些细心的读者就发现了,我们前面介绍的那些停用词怎么解释,例如“不仅”,它在一个句子中出现的顺序其实也不低呀,如果我们认为它很重要的话,那么就大错特错了,因为它是不包含任何信息的。所以我们此时就引入下面一个概念,也就是逆词频。通常在多个文本中,我们认为当一个词在同一篇文本中出现的次数越高那么它就越重要,可是如果它即出现在本篇文档中又在其他文档中的频次很高,那么我们就认为它不那么重要了。我们需要降低它的重要程度。

对于在某一特定文件里的词语来说,它的重要性可表示为:

逆向文件频率(inverse document frequency,idf)是一个词语普遍重要性的度量。某一特定词语的idf,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到:

最后计算综合词频和逆词频得到最终的tfidf值

Word2vec

One-hot

  自然语言在计算机中是以字符或者字符串形式存在的,但是作为一个基于统计的机器学习系统,我们的运算对象是数值型的数据,所以我们需要对字符型数据进行处理。

  表征单词的方式是首先建立一个较大的词汇表(例如10000),然后使用one-hot的方式对每个单词进行编码。例如单词Man,Woman,King,Queen,Apple,Orange分别出现在词汇表的第5391,9853,4914,7157,456,6257的位置,则它们分别用O5391,O9853,O4914,O7157,O456,O6257表示。其中O5391表示一个维度为10000,第5391维度的值为1其余位置值全为0的向量。

  one-hot表征单词的方法最大的缺点就是每个单词都是独立的、正交的,无法知道不同单词之间的相似程度。例如Apple和Orange都是水果,词性相近,但是单从one-hot编码上来看,内积为零,无法知道二者的相似性。在NLP中,我们更希望能掌握不同单词之间的相似程度。

词嵌入

  为了解决One-hot向量的缺点我们可以使用特征表征(Featurized representation)的方法对每个单词进行编码。也就是使用一个特征向量表征单词,特征向量的每个元素都是对该单词某一特征的量化描述,量化范围可以是[-1,1]之间。特征表征的例子如下图所示:

Man(5391) Woman(9853) King(4914) Queen(7157) Apple(456) Orange(6257)
Gender -1 1 -0.95 0.97 0.00 0.01
Royal 0.01 0.02 0.93 0.95 -0.01 0.00
Age 0.03 0.02 0.7 0.65 0.03 -0.02
Food 0.09 0.01 0.02 0.01 0.95 0.97

  特征向量的长度依情况而定,特征元素越多则对单词表征得越全面。这里的特征向量长度设定为300。使用特征表征之后,词汇表中的每个单词都可以使用对应的300 x 1的向量来表示,该向量的每个元素表示该单词对应的某个特征值。每个单词用e+词汇表索引的方式标记,例如e5391, e9853, e4914, e7157, e456, e6257。

  特征表征的优点是根据特征向量能清晰知道不同单词之间的相似程度,例如Apple和Orange之间的相似度较高,很可能属于同一类别。这种单词“类别”化的方式,大大提高了有限词汇量的泛化能力。这种特征化单词的操作被称为Word Embeddings,即单词嵌入。

  这里特征向量的每个特征元素含义是具体的,对应到实际特征,例如性别、年龄等。而在实际应用中,特征向量很多特征元素并不一定对应到有物理意义的特征,是比较抽象的。但是,这并不影响对每个单词的有效表征,同样能比较不同单词之间的相似性。

学习词嵌入

我们可以通过构建自然语言模型(神经网络),运用梯度下降算法得到embedding。举个简单的例子,输入样本是下面这句话:
I want a glass of orange ——.
通过这句话的前6个单词,预测最后的单词“juice”。

为了让神经网络输入层数目固定,可以选择只取预测单词的前4个单词作为输入,例如该句中只选择“a glass of orange”四个单词作为输入。当然,这里的4是超参数,可调。

一般地,我们把输入叫做context,输出叫做target。对应到上面这句话里:

context: a glass of orange
target: juice

关于context的选择有多种方法:

  • target前n个单词或后n个单词,n可调
  • target前1个单词
  • target附近某1个单词(Skip-Gram)

关于context和target的选择,比较流行的模型有Skip-Gram和Cbow。

情感分析

pass

机器翻译

pass

Attention机制

pass

显示 Gitment 评论