NLP

自然语言处理基础

Posted by Fu Xiaohang on February 5, 2022

1 Segment(分词)

  分词主要是对中文的,因为英文词单词之间有空格。

1.1 最大匹配法

1.1.1 FMM(正向最大匹配)

  Forward Maximum Matching,从左往右取词,取词初始长度为词典中最长单词的长度,每次右边减一个字,直到在词典中匹配或剩下1个单字,如rollingstoneapps,设词典中最长单词的长度为8,则匹配顺序如下,

rollings x
rolling  √
stoneapp x
stoneap  x
stonea   x
stone    √
apps     √

则分词结果为,

rolling stone apps

1.1.2 BMM(反向最大匹配法)

  Backward Maximum Matching,与正向最大匹配类似,不同之处是从右向左取词。

1.1.3 双向最大匹配法

  综合正向和反向的结果,因为有的句子只能正向匹配到,有的只能反向匹配到。选择正向和反向中分词数少的作为结果,若分词数相同,则选择词长为1的单词少的作为结果。

1.1.4 最小匹配法

  与最大匹配相反,取词长度从2加到词典中的最大单词长度,每次右边加一个字,取词长度不能为1,要不然分词结果就都是长度为1的词了。

1.1.5 评价

  • 优点
    • 理论上可以匹配任意类型的串,包括英文、拼音、数字以及这些的混排,只要把相应的类型放入词典即可
    • 速度相对较快,因为不需要列出所有的分词可能
  • 缺点
    • 分词结果是上下文无关的,不包含语义信息
    • 一些词匹配不到,例如drivereallyfast会先找到driver,然后无法识别eallyfast,可以结合Trie树进行一些回溯,或者综合双向匹配和最小匹配的结果
    • 不能将长度为1的词放入词典中,因为这可能使得所有分词都是长度为1的词
    • 词典如果不全可能就匹配不到
  • 优化
    • 按单词长度切分成多个词典,查找指定长度的词时无需搜索全部字典(如果词典底层用的是哈希表,性能提升不大)
    • 词典使用布隆过滤器、Trie树或自动机

1.2 基于N-Gram的分词

  一个句子可能有很多的分词结果,本算法利用已有的语料库,使用N-Gram,找出概率最大的分词结果。首先将一句话中的所有词匹配出来,构成词图(是一个有向无环图DAG),然后从起点到终点找一条概率最大的路径。构建DAG用的是词典,计算概率用的是文章这种有上下文的语料库。

image-20220127211102196

可能的分词结果有,

南京//长江/大桥
南京//长江大桥
南京市/长江/大桥
南京市/长江大桥
南京/市长//大桥
南京/市长/江大桥
南京市长//大桥
南京市长/江大桥

第一种分词结果的概率为, \(P(南京市长江大桥)=P(南京)·P(南京|市)·P(南京市|长江)·P(南京市长江|大桥)\) 而概率可以近似为,其中w是词典中的词, \(P(Sentence)=\prod_{i=1}^l P(w_{1}...w_{i-1}|w_{i})≈\prod_{i=1}^l P(w_{i-1}|w_{i})\) 即, \(P(南京市长江大桥)=P(南京)·P(南京|市)·P(市|长江)·P(长江|大桥)\) 这些概率都能在语料库中计算。

  这个算法的语料库是句子,概率是词;Android Package Readable的语料库是词,概率是字母。

评价

  • 优点
    • 能够识别出所有的可能
    • 分词结果结合上下文语义
  • 缺点
    • 对于拼音、数字这种,没有语料库或者语料库很少的就无法计算概率
    • 速度相对较慢
  • 优化
    • 拼音的语料库可以用汉语的语料库,然后将汉字转为拼音

1.3 HMM(隐马尔可夫模型)

Hidden Markov Model

Viterbi算法

1.4 常用库

  • jieba
  • wordsegment
  • wordninja

2 StopWords(停用词)

  一些出现频率很高但没有实际意义的词在处理时需要去掉,如”的”,”了”,”the”,”to”等。一般是先分词,然后过滤停用词。

3 词干化和词形化

  • stemming(词干化):采用直接缩减的方法,去掉复数,过去式,进行时等,只保留词根 \(cats=>cat,cycling=>cycl,drove=>drove\)

  • lemmatization(词形化):采用词性转变的方法 \(cats=>cat,cycling=>cycle,drove=>drive\)

4 关键词提取

4.1 TF-IDF(词频-逆文档频率)

  一种用于信息检索与数据挖掘的常用加权技术,常用于挖掘文章中的关键词。对于一篇文章,出现频率最高的词很可能是关键词,这就是词频TF, \(TF=该词在文章中出现的次数/该文章的总词数\) 而一些出现频率很高的词,比如”xxx系统”,在其他文章中也是常出现的,这种在关键词中靠后,赋予比较小的权重,这就是逆文档频率IDF,衡量了一个词能够在多大程度上代表他所处的这个句子, \(IDF=log(语料库的文档数/包含该词的文档数)\) 对其进行平滑,得到, \(IDF=log((语料库的文档数+1)/(包含该词的文档数+1)+1)\) 加1是为了防止没有文档包含这个词,分母变0。最终的TF-IDF如下, \(TF-IDF=TF*IDF\) 该值越大说明词频越高并且在其他文章中出现的少,因此权重越高,越可能是关键词。

4.2 TextRank

  TextRank是根据PageRank改进而来的,可以完成关键词提取和文本摘要任务(关键句提取)。

  • 关键词提取

  首先进行分词,TextRank中的节点是分词后的词语,例如,原始文本内容为“淡黄的长裙,蓬松的头发,牵着我的手看最新展出的油画”,分词后得到[淡黄 长裙 蓬松 头发 牵 我 手 看 最新 展出 油画],是滑动窗口中同时出现的词语,若给定窗口为3,依次滑动,得到[淡黄 长裙 蓬松]、[长裙 蓬松 头发]等等,得到边淡黄-长裙、长裙-蓬松、蓬松-头发等等,最终得到的图是无向的,然后就可以利用PageRank的公式,计算各个词语的TextRank值,选出值最高的作为关键词。 \(TR(A)=(1-d)+d*(∑TR(Ti)/Out(Ti))\)

  • 文本摘要任务

  文本摘要任务,也可以理解为关键句提取,图中的节点变为了句子,首先计算各个句子之间的相似度,相似度可以通过两种方式计算,一是将句子分词,对词向量化并加和平均,然后计算余弦相似度;二是通过如下公式, \(Similarity(Si,Sj)=|\{wk|wk∈Si\&wk∈Sj\}|/log(|Si|)+log(|Sj|)\) 其中,Si、Sj分别表示两个句子,wk表示句子中的词,分子的意思是同时出现在两个句子中的词的个数,分母是两个句子中词的个数和,分母这样的设计可以抑制较长的句子在相似度计算上的优势。

对相似度设定一个阈值,相似度大于阈值的两个句子之间有边相连,相似度作为边的权值,在PageRank公式的基础上,利用以下公式计算TextRank值,选出最高的作为文本摘要, \(TR(A)=(1-d)+d*(∑(TR(Ti)*w1/∑w2)\) Ti代表在图中与A相连的句子,w1代表A和Ti的相似度,w2代表与Ti相连的句子的相似度,分母就是对这些相似度进行了求和。

  TF-IDF和TextRank都严重依赖于分词结果,TextRank相对于TF-IDF,可以更充分地利用文本元素之间的关系,但要构造词图并进行迭代计算,因此速度更慢。两者都倾向于将高频词作为关键词。

5 文本特征表示

  文本表示可以分为离散表示和分布式表示,离散表示的代表是词袋模型,分布式表示的代表是词嵌入模型。

5.1 Bag Of Words(词袋模型)

  词袋模型忽略掉文本的语法和语序等要素,将其仅仅看作是若干个词汇的集合,文档中每个单词的出现都是独立的,就像一个词袋一样。

5.1.1 VSM(向量空间模型)

  Vector Space Model,用一个向量表示一个文本,向量的每一个元素对应一个单词,其数值是该单词的词频或者TF-IDF等。语料库有多少类别,向量就有多少位,比如性别有[‘male’,’female’],地区有[‘CN’,’USA’,’JP’],就可以用一个五维向量[‘is_male’,’is_female’,’is_CN’,’is_USA’,’is_JP’]表示。这种方式的缺点是数据会非常稀疏。

5.1.1.1 One-Hot(独热编码)

  向量的每一位用1/0表示是否有或者没有,如一个中国男性就可以表示为[1,0,1,0,0],。

5.1.1.2 TF-IDF

  TF-IDF不仅可以用作关键词提取,还可以用于文本表示,向量的值为TF-IDF。例如,给定四个文本,

['Chinese Beijing Chinese',
 'Chinese Chinese Shanghai',
 'Chinese Macao',
 'Tokyo Japan Chinese']

那么构造的VSM向量为,

['Beijing', 'Chinese', 'Japan', 'Macao', 'Shanghai', 'Tokyo']

元素的值为其TF-IDF值,以第一条文本’Chinese Beijing Chinese’为例,

TF-IDF('Chinese')=(2/3)*(log(5/5)+1)=0.67
TF-IDF('Beijing')=(1/3)*(log(5/2)+1)=0.64

后面的5代表的是文本总数(平滑+1),5和2分别代表包含’Chinese’的文本总数和包含’Beijing’的文本总数,那么,最终的向量为,

[0.64,0.67,0,0,0,0]

可以使用sklearn的TfidfVectorizer函数来计算TF-IDF得到VSM;函数CountVectorizer能够计算词频矩阵,同时参数中可以设置停用词。

5.1.1.3 N-Gram

  连续出现的N个词/字母。N-Gram相当于一种VSM向量的构造方式,向量的值还是通过上面两种方式计算的,比如实习的项目Readable Detector就是用2-Gram或3-Gram构造了向量[‘aa’,’ab’,’ac’,…],然后用词频TF作为值(可以改进成TF-IDF)。N-Gram还可以结合马尔科夫链,比如项目Gibberish-Detector

  改进版:NNLM、RNNLM。

5.1.2 TM(主题模型)

Topic Model

5.1.2.1 LSA(潜在语义分析)

5.1.2.2 LDA(隐含狄利克雷分布)

5.2 Word Embedding(词嵌入模型)

5.2.1 Word2Vec

  Word2Vec相当于使用神经网络对One-Hot进行了降维,并且考虑了上下文关系,能表示语义信息。使用的神经的网络是一个简化版的,其隐藏层没有激活函数,也就是线性的单元,输出层用的是Softmax。我们并不是用该网络来预测,而是用训练出的参数构造词向量。

5.2.1.1 CBOW

  Continuous Bag-of-Words,网络的输入是某一个特征词的上下文相关的词对应的One-Hot,输出是该词的One-Hot,

image-20220110203614118

设VSM的长度为V(上图为4),希望得到的词向量长度为N,选定单词为coffee,窗口大小为2,则输入的上下文单词为Idrinkeveryday,将这些单词的One-Hot向量分别乘以共享的输入权重矩阵WV×N,所得的向量相加求平均作为隐藏层向量(其实相当于是K-Hot直接乘),然后乘以输出权重矩阵W’N×V,得到输出,与Label比较,用反向传播法更新参数矩阵。

  训练完成后,每个单词的One-Hot乘以输入权重矩阵WV×N得到的就是我们需要的词向量。由于One-Hot只有1位是1,因此可以用如下的方式加快计算,

image-20220110225306809

5.2.1.2 Skip-Gram

  与CBOW相反,输入是选择的特征词的One-Hot,输出是上下文相关的词的One-Hot。例如我们有一句话,The quick brown fox jumps over lazy dog,选定单词为brown,窗口大小为2,则输出的上下文单词为Thequickfoxjumps,则我们获得一组训练数据(brown,The)(brown,qucik)(brown,fox)(brown,jumps)

image-20220110223427206

整个句子就能获得一组训练数据,然后放入网络训练,训练好之后,同CBOW一样,每个单词的One-Hot乘以输入权重矩阵WV×N得到的就是我们需要的词向量。

  在CBOW中,预测行为的次数跟整个文本的词数几乎是相等的,复杂度约为O(V),设窗口大小为K,Skip-Gram的复杂度约为O(KV),因此CBOW训练得更快。在Skip-Gram当中,每个词都要受到周围的词的影响,进行K次的预测、调整,因此当数据量较少或者为生僻词时, 这种多次的调整会使得词向量相对的更加准确;尽管在CBOW中,每个词也是会受到多次周围词的影响,但是它的调整是跟周围的词一起调整的,调整的值会平均分到该词上,相当于该生僻词没有受到专门的训练。因此Skip-Gram对于罕见词、罕见搭配更友好,而CBOW可以更好地表示更频繁的单词。此外,由于能够衍生出更多的训练样本,Skip-Gram非常适合小训练集

5.2.2 Bert

6 NER(命名实体识别)