菜鸟学NLP(一)

文本预处理方法总结

文本预处理的三个主要组成部分:

  • 标记化(tokenization)
  • 归一化(normalization)
  • 替换(substitution)

标记化(tokenization)

标记化是将文本中的长字符串分割成小的片段或tokens的过程.大段文字可以被分割成句子,句子又可以分割成单词等等.有时,分割(segmentation)用来表示大段文字编程小片段的过程(例如段落或句子).而tokenization指的是将文本变为只用单词表示的过程.
这里的tokenization其实就是分词操作,在python里我们可以使用split()函数,

1
2
3
4
5
sentence_example = """I love deep learning, I love natural language processing."""
token_seq1 = str.split(sentence_example)
token_seq2 = sentence_example.split(' ')
print("token_seq1: ", token_seq1)
print("token_seq2: ", token_seq2)

其中token_seq1和token_seq2的效果是一样的.
而用nltk.word_tokenize也可以实现

1
text_list = nltk.word_tokenize(sentence_example)

如果要进行句子切分操作,sentence tokenize,也是可以用nltk来实现的.

1
2
from nltk.tokenize import sent_tokenize
sent_tokenize_list=sent_tokenize(text)

其中Sentence Tokenize是PunktSentenceTokenizer的实例.
nltk.tokenize.punkt中包含了很多预训练好的tokenize模型.

1
2
3
import nltk.data
tokenizer=nltk.data.load('tokenizers/punkt/english.pickle')
tokenizer.tokenize(text)

归一化(Normalization)

归一化指的是一系列相关的任务,能够将所有文本放在同一水平区域上:将所有文本转化成同样的实例,删除标点,将数字转换成相应的文字等.对文本进行归一化可以执行多种任务.一般的归一化有3种特殊的步骤:

  1. 词干提取(stemming):删除词缀(包括前缀、后缀、中缀、环缀),从而得到单词的词干,比如running$\rightarrow$ run
  2. 词形还原(lemmatization):词形还原与词干提取相关性,不同的是,词形还原能够捕捉基于词根的规范单词形式$better\rightarrow good$
  3. 其他:词性还原和词干提取是文本预处理的主要部分,所以这两项要认真对待.它们不是简单地文本操作,而要依赖语法规则和对规则细致地理解
    其他重要地方法包括:
    3.1. 将所有字母变成小写
    3.2. 删除数字
    3.3. 删除标点
    3.4. 删除空白格
    3.5. 删除默认停用词
    3.6. 删除特定的停止词

替换

自然语言数据预处理中经常会涉及到同义词替换,比如计算两个句子的相似度中,把一个词的两个同义词利用同义词替换技术转换为同一个词,那么就提高了相似度计算的可靠性。

文本表示

上面预处理完了以后,我们得到的还是一系列文本字符串,要想要用机器学习方法处理,还需要将字符串向量化,称为文本表示.
文本表示基于类型分为以下几种:

  • 长文本表示
  • 短文本表示
  • 词表示

文本表示分类(基于表示方法)

  • 离散表示:One-hot表示,Multi-hot表示
  • 分布式表示:基于矩阵、基于降维表示、基于聚类表示
  • 基于神经网络的表示:CBOW,Skip-gram,NNLM,C&W

文本离散表示:词袋模型与TF-IDF

词袋模型

词袋子模型是一种非常经典的文本表示。顾名思义,它就是将字符串视为一个 “装满字符(词)的袋子” ,袋子里的 词语是随便摆放的。而两个词袋子的相似程度就以它们重合的词及其相关分布进行判断。
举个例子,对于句子:“我们这些傻傻的路痴走啊走,好不容易找到了饭店的西门”。
我们先进行分词,将所有出现的词储存为一个词表。然后依据 “词语是否出现在词表中” 可以将这句话变为这样的向量:
[1,0,1,1,1,0,0,1,…]
词表:[我们,你们,走,西门,的,吃饭,旅游,找到了,…]
其中向量的每个维度唯一对应着词表中的一个词。可见这个向量的大部分位置是0值,这种情况叫作“稀疏”。为了减少存储空间,我们也可以只储存非零值的位置。

词袋模型的优缺点:

  1. 优点:
  • 简单、方便、快速
  • 预料充足前提下,对于简单的自然语言处理任务效果不错,如文本分类
  1. 缺点:
  • 其准确率往往比较低。凡是出现在文本中的词一视同仁,不能体现不同词在一句话中的不同的重要性。
  • 无法关注词语之间的顺序关系,这是词袋子模型最大的缺点。如“武松打老虎”跟“老虎打武松”在词袋子模型中是认为一样的。

词袋模型的改进——TF-IDF

第一步,计算词频。
TF=某词在文章中出现的次数,考虑到文章有长短之分,为了便于不同文章的比较,进行”词频”标准化。
TF = 某词在文章中出现的次数/文章的总次数
第二步,计算逆文档频率。
这时,需要一个语料库(corpus),用来模拟语言的使用环境。
逆文档频率(IDF)=log(语料库的文档总数/包含该词的文档数+1)
如果一个词越常见,那么分母就越大,逆文档频率就越小越接近0。分母之所以要加1,是为了避免分母为0(即所有文档都不包含该词)。log表示对得到的值取对数。
第三步,计算TF-IDF。
TF-IDF=TF*IDF
可以看到,TF-IDF与一个词在文档中的出现次数成正比,与该词在整个语言中的出现次数成反比。所以,自动提取关键词的算法就很清楚了,就是计算出文档的每个词的TF-IDF值,然后按降序排列,取排在最前面的几个词。

基于SVD降维的表示方法

这是一种构造词嵌入(即词向量)的方法,步骤如下:
1.遍历所有的文本数据集,统计词出现的次数
2.用一个矩阵X来表示所有的次数情况
3.对X进行奇异值分解得到一个的分解
4.用U的行(rows)作为所有词表中词的词向量
有两种方法来构造矩阵X
方法一:词-文档矩阵
方法二:基于窗口的共现矩阵X

这两种方法都能产生词向量,它们能够充分地编码语义和句法的信息,但同时也带来了其他的问题:

  • 矩阵维度会经常变化(新的词语经常会增加,语料库大小也会随时变化)
  • 矩阵非常稀疏,因为大多数词并不同时出现
  • 矩阵维度通常非常搞,训练需要$O(n^2)$的复杂度
  • 需要专门对矩阵X进行特殊处理,以应对词组频率的极度不平衡状况

基于神经网络的表示方法(当前流形方法)

基于神经网络的方法是创建一个模型,他能够一步步迭代地进行学习,最终得出每个单词基于其上下文的条件概率。
我们想建立一个概率模型,它包含已知和未知参数。每增加一个训练样本,它就能从模型的输入、输出和期望输出(标签),多学到一点点未知参数的信息。在每次迭代过程中,这个模型都能够评估其误差,并按照一定的更新规则,惩罚那些导致误差的参数。
两种应用场景

  1. CBOW——基于上下文预测词语
  2. skip-gram—基于词语预测上下文
-------------本文结束感谢您的阅读-------------

本文标题:菜鸟学NLP(一)

文章作者:Yif Du

发布时间:2019年04月02日 - 12:04

最后更新:2019年04月05日 - 01:04

原始链接:http://yifdu.github.io/2019/04/02/菜鸟学NLP(一)/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。