03[NLP训练营]文本处理(上)


根据上节课的流程,本节先讲前面四个东西。

Word Segmentation

常见工具

Jieba分词https://github.com/fxsjy/jieba
SnowNLP https://github.com/isnowfy/snownlp
LTP http://www.tp-cloud.com/
HanNLP https://github.com/hankcs/HanLP/
其中jieba最常用
下面是使用例子:

#encoding=utf-8
import jieba存基于jeba的分词
seg_list=jieba.cut("贪心学院专注于人工智能教育",cut_all=False)
print("Default Mode:"+"/".join(seg_list))
jieba.add word(“贪心学院")seg_list=jieba.cut("贪心学院专注于人工智能教育",cut_all=Falseprint("Default Mode:"+"/".join(seg_list))

结果:
Default Mode:贪心/学院/专注/于/人工智能/教育
Default Mode:贪心学院/专注/于/人工智能/教育

Segmentation Method 1:Max Matching(最大匹配)

前向最大匹配(forward-max matching)

例子:我们经常有意见分歧
词典:[“我们”,“经常”,“有”,“有意见”,“意见”,“分歧”]
第一步:
先要设定一个变量maxlen=5,因此刚开始的窗口大小为5:
【我们经常有】意见分歧
由于词典没有这个词,所以把窗口减小
【我们经常】有意见分歧×
【我们经】常有意见分歧×
【我们】经常有意见分歧√
找到了一个匹配的词:我们
第二步:
【经常有意见】分歧×
【经常有意】见分歧×
【经常有】意见分歧×
【经常】有意见分歧√
找到了一个匹配的词:经常
一直循环下去,知道全部找完。

后最大匹配(backward-max matching)

例子:我们经常有意见分歧
词典:[“我们”,“经常”,“有”,“有意见”,“意见”,“分歧”]
这个和前向相反,稍微说一下:
第一步:
先要设定一个变量maxlen=5,因此刚开始的窗口大小为5:
我们经常【有意见分歧】×
我们经常有【意见分歧】×
我们经常有意【见分歧】×
我们经常有意见【分歧】√
找到了一个匹配的词:分歧
第二步:
我们【经常有意见】分歧×
我们【经【常有意见】分歧×
我们【经常【有意见】分歧√
找到了一个匹配的词:有意见
后面就不说了。

Max Matching(最大匹配)的缺点

属于贪心算法,只能得到局部最优解
效率不高
不能考虑歧义
没有细分,例如上面的【有意见】应该分成【有】【意见】

Segmentation Method 2:Incorporate Semantic(考虑语义)

例子:经常有意见分歧
词典:[“有”,“有意见”,“意见”,“分歧”,“见”,“意”]
把整个考虑语义的算法看成一个模块,吃进去句子分词的形式,吐出来该形式的概率,概率越大,说明越像人话,例如:
【经常】【有意见】【分歧】经过模块得到0.3
【经常】【有】【意见】【分歧】经过模块得到0.6
说明第二种分词要比第一种好。
整个算法步骤:
1、读取语句;
2、生成所有的分割组合;
3、判断概率最大的分割组合。(这事情是有专门的模块或者说工具可以帮我们来解决,这个工具就是language model)
关于LM如何怎么计算概率,之前的课程有说了,就是马尔科夫假设。

缺点

复杂度太高,就是那个第二步太多组合。。。
要解决这个问题,就是用经典的动态规划算法维特比算法。
这个算法就是把方法2中的第一步和第二步结合起来考虑 。

例子:“经常有意见分歧”
词典:[“经常”,“经”,“有”,“有意见”,“意见”,“分歧”,“见”,“意”,“见分歧”,“分”]
概率:[0.1,0.05,0.1,0.1,0.2,0.2,0.05,0.05,0.05,0.1]
-log(x):[2.3,3,2.3,2.3,1.6,1.6,3,3,3,2.3]
这里log加负号是为了转换为求最小值。
解决方案:
先画这么一个图
下图中的数字就是单个字在上面对应的概率,如果对应的字没有概率我们就假设: l o g ( 1 0 8 ) = 20 -log(10^{-8})=20
在这里插入图片描述
看完单个字,我们来看两个字的:
在这里插入图片描述
然后看3个字的
在这里插入图片描述
词典里面没有四个字符的。。。画图就完毕了
把左边看做开始,把右边看做结束
那么从开始到结束有很多个路径,那么路径长度就是一个有向带权图。
在这里插入图片描述
然后找一条最短的路径,求这个最短路径有很多方法,这里用维特比。
f ( 8 ) f(8) 表示从节点1到8的最短路径
f ( 7 ) f(7) 表示从节点1到7的最短路径
以此类推。。。
现在要求 f ( 8 ) f(8) f ( 8 ) f(8) 有三个可能:
f ( 5 ) + 3 f(5)+3
f ( 6 ) + 1.6 f(6)+1.6
f ( 7 ) + 20 f(7)+20
从上面三个找最小的那个
f ( 7 ) f(7) :只有一种可能,从 f ( 6 ) f(6) 过来。
f ( 6 ) f(6) 有三个可能:从3,4,5过来。
本来可以用递归来实现,但是递归效率不好,就先把计算结果保存到数组中:

f(1) f(2) f(3) f(4) f(5) f(6) f(7) f(8)
0 3 2.3 4.6 7.6 4.6 7.9 6.2
1 1 1 3 4 3 6 6

下面一行是上个节点的序号,然后反推出路径是:1、3、6、8。

Word Segmentation Summary知识点总结:

-基于匹配规则的方法:最大匹配
-基于概率统计方法(LM,HMM,CRF)
-分词可以认为是已经解决的问题
需要掌握什么?
-可以自行实现基于最大匹配和Unigram LM的方法

Spell Correction (拼写纠错)

概念

(用户输入(input)用户输入(correction)
天起---------------------------------天气
theris------------------------------------theirs
机器学系-------------------------------机器学习
拼写错误有两种:
1、错别字
2、不是错别字,语法错I go home,应该是I am going home
第一种情况可以直接从词库进行判断,当输入的词不在词库里面,那么就可以判定是错别字。
第二种情况可以用语言模型来判断,当某个位置上的上下文概率很低,那么就可以判断这里出现了语法错误。

Find the words with smallest edit distance

我们把单词与替换词之间用一个概念来描述:编辑距离
可以理解为替换为目标词需要的操作的复杂度。
假设我们定义把错误词替换为目标词有下面三个操作:
1、insert
2、delete
3、replace
therr这个词到there的编辑距离为一个操作(replace操作):
t h e r r e ther|r\to e
therr这个词到thesis的编辑距离为三个操作(replace+replace+insert)
t h e r s r i + s the|r\to s|r\to i|+s
当然如果编辑距离相同,就需要考虑上下文等因素来进行排序。
计算编辑距离的目的是得到候选(candidates)词,但是这个计算要涉及到词典里面所有词,明显是很低效的。其时间复杂度为: O ( v )  V is number of word in dictionary O(v)\space \text{V is number of word in dictionary}
怎么办?

新方法

在这里插入图片描述
怎么来生成?由于操作是固定好的,三个:
1、insert
2、delete
3、replace
假如我们有一个单词appl
如果编辑距离为1,并选择replace操作,可以生成:
bppl/cppl/…
aapl/abpl/…
同样我们还可以用别的操作。
然后把生成得到的单词集合,进行过滤。
这里注意,为什么选择1/2的编辑距离?因为拼写错误大多数情况下都是产生编辑距离为1或2的错误。

过滤

问题定义
给定一个字符串 s s ,我们要找出最有可能成为正确的字符串 c c ,也就是
c ^ = a r g m a x c c a n d i d a t e s p ( c s ) \widehat c=argmax_{c\in candidates}p(c|s)
其中candidates是上一步生成的候选集合,根据贝叶斯公式:
c ^ = a r g m a x c c a n d i d a t e s p ( s c ) p ( c ) p ( s ) (1) \widehat c=argmax_{c\in candidates}\cfrac{p(s|c)p(c)}{p(s)}\tag1


贝叶斯公式的推导:
联合概率有:
p ( x , y ) = p ( x y ) p ( y ) = p ( y x ) p ( x ) p(x,y)=p(x|y)p(y)=p(y|x)p(x)
p ( x y ) = p ( y x ) p ( x ) p ( y ) p(x|y)=\frac{p(y|x)p(x)}{p(y)}


公式(1)中,s是给定的,所以 p ( s ) p(s) 是一个常量,所以可以等价为:
c ^ = a r g m a x c c a n d i d a t e s p ( s c ) p ( c ) \widehat c=arg\underset{c\in candidates}{max}p(s|c)p(c)
现在c代表正确的输入,s代表用户的输入
正确:apple
用户1:app
用户2:appl
用户3:appl
用户4:app
用户5:appla
用户6:appl
那么 p ( a p p l a p p l e ) = 3 6 = 50 % p(appl|apple)=\cfrac{3}{6}=50\% p ( a p p a p p l e ) = 2 6 = 33 % p(app|apple)=\cfrac{2}{6}=33\%
p ( s c ) p(s|c) 代表对于一个正确的字符串c,用户输入成错误的s的几率。
p ( c ) p(c) 实际上是字符串c的unigram,就是c在所有的文本中出现的几率(或者说出现次数/总词数)。

Stop Words Removal

对于NLP的应用,我们通常先把停用词、出现频率很低的词汇过滤掉,这其实类似于特征筛选的过程。
这里面涉及两大类词汇:
停用词:在英文里,比如“the”,“an",“their”这些都可以作为停用词来处理。但是,也需要考虑自己的应用场景(例如情感分析)
出现频率很低的词汇:出现频率特别低的词汇对分析作用不犬,所以一般也会去掉。把停用词、出现频率低的词过滤之后,即可以得到一个词典库。

Stemming:one way to normalize

词的标准化操作,尤其是对英文单词
下面意思都类似,怎么合并?希望它们回归为原型,但是由于还原操作是基于规则的,所以不一定还原为有效的单词。
went,go,going 还原为go
fly,flies还原为fli
deny,denied,denying还原为deni
fast,faster,fastest还原为fast
最常用Stemming的算法:PorterStemmer


除了这个方法,还有一种方法叫做:lemmatization,它在还原的时候一定是还原为原词的
具体可以参考:
https://nlp.stanford.edu/IR-book/html/htmledition/stemming-and-lemmatization-1.html


下面具体来看看步骤:
黑色是规则,绿色是例子
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

发布了140 篇原创文章 · 获赞 35 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/oldmao_2001/article/details/104465925
今日推荐