- 什么是nlp?
nlu(understanding)+nlg(generation)- nlp面临的挑战
一词多义
pipeline:分词->清洗->标准化(stemming,lemmazation)->特征提取->建模(相似度算法,分类算法)->评估
返回相应问题的答案
1.1 最大匹配方法
最大匹配算法是自然语言处理中的中文匹配算法中最基础的算法,分为前向匹配和后向匹配。
(1)前向最大匹配(forward-max matching)
max_length=5(假设)
词典
[“我们”,“经常”,“有”,“有意见”,“意见”,“分歧”]
例子:我们经常有意见分歧
step1:word=“我们经常有”,不在词典中,去掉最后一个"有","我们经常"不在词典中,去掉最后一个常…,得到"我们"在词典中,获得第一个分词[“我们”]
step2: word=“经常有意见”,不在词典中,从后面去掉一个词…,得到"经常"在词典中,获得分词结果[“我们”,“经常”]
…
最后获得的分词结果[我们|经常|有意见|分歧]
(2)后向最大匹配(backward-max matching)
例子:我们经常有意见分歧
step1: word=“有意见分歧”,不在词典中,去掉第一个"有"…,获得第一个分词[“分歧”]
step2: word=“经常有意见”,不在词典中,去掉第一个"经"…,获得分词[“有意见”,“分歧”]
…
最后获得的分词结果[我们|经常|有意见|分歧]
最大匹配的缺点:
依赖于词典,不能做词细分
局部最优(属于贪心算法)
效率不高(取决于max_length)
有歧义(不能考虑语义)
1.2 语言模型(考虑语义)
输入句子->生成所有可能的分割->利用语言模型,选择其中最好的
语言模型的缺点:
分词方法分两步进行(分割->计算unigram概率),时间复杂度很高
1.3 Viterbi算法(DP算法)
例子:“经常有意见分歧”
词典:[“经常”,“经”,“有”,“有意见”,“意见”,“分歧”,“见”,“意”,“见分歧”,“分”]
概率:[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]
最小编辑距离(DP算法)
insert/delete/replace
therr-> there/their
输入->从词典遍历所有词与输入的编辑距离,找到最小的-> 返回
缺点: 从词典里循环所有词,时间复杂度很高
改进: 输入->生成编辑距离为1,2的字符串->过滤->返回
给定一个字符串s,找出最有可能成为正确的字符串c
c = a r g m a x c ∈ c a n d i d a t e s p ( c ∣ s ) = a r g m a x c ∈ c a n d i d a t e s p ( s ∣ c ) p ( c ) / p ( s ) c = argmax_{c\in candidates }p(c|s)=argmax_{c\in candidates }p(s|c)p(c)/p(s) c=argmaxc∈candidatesp(c∣s)=argmaxc∈candidatesp(s∣c)p(c)/p(s)
p(s|c):对于一个正确的字符串,有多少人写成了s
p( c) : 所有文本中,单词c出现的概率(unigram probablity)
对于NLP的应用,我们通常先把停用词/出现频率很低的词汇过滤掉,类似于特征选择的过程
停用词:‘the’,‘an’,‘their’,但是,也要考虑自己的使用场景
可以先用现有的停用词库,根据自己的场景,删掉不能使用的停用词,附加额外的停用词
4.1 stemming
通过定义后缀规则 sses->ss,ies->i
went,go,going->go(还原的词不一定是有效的单词)
4.2 lemmazaiton
还原后的词是有效单词
5.1 one-hot【向量的大小与词典大小相等】
任何两个词向量的内积都为0,不能表达相似度
产生的是稀疏向量sparsity
向量表达单词
词典:[我们,去,爬山,今天,你们,昨天,跑步]
按照单词在词典库中的顺序
我们:(1,0,0,0,0,0,0)->7维=|词典|
爬山:(0,0,1,0,0,0,0)
跑步:(0,0,0,0,0,0,1)
昨天:(0,0,0,0,0,1,0)
向量表达句子
词典:[我们,又,去,爬山,今天,你们,昨天,跑步]
按照单词在词典库中的顺序
我们|今天|去|爬山:(1,0,1,1,1,0,0,0)->8维=|词典|
你们|昨天|跑步:(0,0,0,0,0,1,1,1)
你们|又|去|爬山|又|去|跑步:(0,1,1,1,0,1,0,1)
词典:[我们,又,去,爬山,今天,你们,昨天,跑步]
按照单词在词典库中的顺序
我们|今天|去|爬山:(1,0,1,1,1,0,0,0)->8维=|词典|
你们|昨天|跑步:(0,0,0,0,0,1,1,1)
你们|又|去|爬山|又|去|跑步:(0,2,2,1,0,1,0,1)
t f i d f ( w ) = t f ( d , w ) ∗ i d f ( w ) tfidf(w)=tf(d,w)*idf(w) tfidf(w)=tf(d,w)∗idf(w)
其中tf(d,w):文档d中w的词频(count based)
idf(w)=log(N\N(w))(在很多文档中出现的单词,idf(w)值越小,重要性不大)
N:语料库中的文档总数
N(w):词w出现在多少个文档中
词典:[今天,上,NLP,课程,的,有,意思,数据,也]
s1:今天|上|NLP|课程->[1log(3\2),1log(3\1),1log(3\1),1log(3\3),0,0,0,0,0]
s2:今天|的|课程|有|意思->[1log(3\2),0,0,1log(3/3),1log(3\1),1log(3\2),1log(3\2),0,0]
s3:数据|课程|也|有|意思->[0,0,0,1log(3\3),0,1log(3\2),1log(3\2),1log(3\1),1log(3\1)]
5.2 词嵌入
向量里每个值都是非0值
king:[-0.95,0.5,-0.05,0.2]
学习词向量
输入(string(109~1010个字符))-> 模型(skip-gram/glove/cbow/rnn/lstm/mf/gaussian enbedding)->词向量
d = |s1-s2|
同一词典句子的长度相同
d = s 1 s 2 / ( ∣ s 1 ∣ ∣ s 2 ∣ ) d = s1 s2/(|s1||s2|) d=s1s2/(∣s1∣∣s2∣)
d(s1,s2)=0
缺点: 只从出现频率来表示单词/句子,距离计算时,频次高的单词对结果影响较大,实际的语义分析时,并不是出现频率越高就越重要
时间复杂度很高的问题,采用层层过滤的思想,将一个复杂度很高的操作变为多个复杂度低的操作的加和
8.1 noisy channel model
p(text|source) ~ p(source|text)p(text)[语言模型]
应用场景(信号->文本):
语音识别
机器翻译
拼写纠错
OCR
密码破解
8.2 language model
用来判断一句话从语法上是否通顺
p(A,B,C,D)= p(A)P(B|A)P(C|AB)P(D|ABC)
条件概率计算:统计条件出现的概率(存在稀疏性的问题)
p(休息|今天,是,春节,我们,都)~p(休息|都)[1st order markov assumption]
p(休息|今天,是,春节,我们,都)~p(休息|我们,都)[2nd order markov assumption]
p(休息|今天,是,春节,我们,都)~p(休息|春节,我们,都)[3rd order markov assumption]
p(今天,是,春节,我们,都,休息)=p(今天)p(是)p(春节)p(我们)p(都)p(休息)
p(今天,春节,是,我们,都,休息)=p(今天)p(是)p(春节)p(我们)p(都)p(休息)
[存在缺陷]
p(今天,是,春节,我们,都,休息)=p(今天)p(是|今天)p(春节|是)p(我们|春节)p(都|我们)p(休息|都)
不依赖于任务
基于填空的思路,将训练好的语言模型应用在语料库中计算概率结果
今天—logp1
今天天气-logp2
今天天气很好-logp3
今天天气很好,适合-logp4
今天天气很好,适合出去-logp5
今天天气很好,适合出去运动logp6
p e r p l e x i t y = 2 − ( x ) , x : a v e r a g e l o g l i k e l i h o o d perplexity=2^{-(x)},x:average\ log\ likelihood perplexity=2−(x),x:average log likelihood
p M L E ( w i ∣ w i − 1 ) = c ( w i − 1 , w i ) c ( w i − 1 ) p_{MLE}(w_i|w_{i-1})=\frac{c(w_{i-1},w_i)}{c(w_{i-1})} pMLE(wi∣wi−1)=c(wi−1)c(wi−1,wi)
p a d d − 1 ( w i ∣ w i − 1 ) = c ( w i − 1 , w i ) + 1 c ( w i − 1 ) + V p_{add-1}(w_i|w_{i-1})=\frac{c(w_{i-1},w_i)+1}{c(w_{i-1})+V} padd−1(wi∣wi−1)=c(wi−1)+Vc(wi−1,wi)+1
V:词典库大小
p a d d − k ( w i ∣ w i − 1 ) = c ( w i − 1 , w i ) + k c ( w i − 1 ) + k V p_{add-k}(w_i|w_{i-1})=\frac{c(w_{i-1},w_i)+k}{c(w_{i-1})+kV} padd−k(wi∣wi−1)=c(wi−1)+kVc(wi−1,wi)+k
k:超参数,可调
将训练好的语言模型应用于验证集语料库,得到perplexity=f(k),求k使f(k)最小
在计算trigram概率时,同时考虑unigram,bigram,trigram出现的频次
p ( w n ∣ w n − 1 , w n − 2 ) = λ 1 p ( w n ∣ w n − 1 , w n − 2 ) + λ 2 p ( w n ∣ w n − 1 ) + λ 3 p ( w n ) p(w_n|w_{n-1},w_{n-2})=\lambda_1p(w_n|w_{n-1},w_{n-2})+\lambda_2p(w_n|w_{n-1})+\lambda_3p(w_n) p(wn∣wn−1,wn−2)=λ1p(wn∣wn−1,wn−2)+λ2p(wn∣wn−1)+λ3p(wn)
λ 1 + λ 2 + λ 3 = 1 \lambda_1+\lambda_2+\lambda_3=1 λ1+λ2+λ3=1
N c N_c Nc出现了c次的单词的个数
没有出现过的单词
p M L E = 0 p_{MLE}=0 pMLE=0
p G T = N 1 N p_{GT}=\frac{N_1}{N} pGT=NN1
出现过的单词
p M L E = c N p_{MLE}=\frac{c}{N} pMLE=Nc
p G T = ( c + 1 ) N c + 1 N c N p_{GT}=\frac{(c+1)N_{c+1}}{N_cN} pGT=NcN(c+1)Nc+1
假设你在钓鱼,已经抓到了18只鱼:10条鲤鱼,3条黑鱼,2条刀鱼,1条鲨鱼,1条草鱼,1条鳗鱼
没有出现过的:
p_{MLE}(飞鱼)=0
p_{GT}(飞鱼)=3/18
出现过的:
p_{MLE}(草鱼)=1/18
p_{GT}(草鱼)=(1+1)x1/(3x18)
一般情况下:p_{GT}
gt缺点: p计算依赖于 N c + 1 N_{c+1} Nc+1,有可能是缺失值
解决方案: 采用算法进行 N c + 1 N_{c+1} Nc+1缺失值填补
图片、音乐、文本、编程
首先根据语料库训练语言模型
voc:[NLP(0.1),I(0.3),like(0.2),studying(0.2),course(0.35),yesterday(0.05)]
根据语言模型采样生成句子
unigram:随机选择生成,语序不太合理
bigram:随机生成第一个单词,根据概率矩阵[包含终止符号,作为采样终止条件],选择概率大的作为后面要生成的单词