赞
踩
例如One-Hot 编码,只要单个文本中单词出现在字典中,就将其置为1,不管出现多少次
首先,统计出语料中的所有词汇,然后对每个词汇编号,针对每个词建立V维的向量,向量的每个维度表示一个词,所以,对应编号位置上的维度数值为1,其他维度全为0。
优点是简单快捷,缺点是数据稀疏、耗时耗空间、不能很好地展示词与词之间的相似关系,且还未考虑到词出现的频率,因而无法区别词的重要性
计算机只能读懂数字,怎么读懂句子呢?
Bag-of Words(BOW)定义:把文档看作一个袋子,并把文档中的语言打散为单词,不按顺序排列,抓取语言中的主要内容,忽视语言的格式和形式。文档中每个单词的出现都是独立的,不依赖于其它单词是否出现。也就是说,文档中任意一个位置出现的任何单词,都不受该文档语意影响而独立选择的。
例子:
维基百科上给出了如下例子:
John likes to watch movies. Mary likes too.
John also likes to watch football games.
根据上述两句话中出现的单词, 我们能构建出一个字典 (dictionary):
{“John”: 1, “likes”: 2, “to”: 3, “watch”: 4, “movies”: 5, “also”: 6, “football”: 7, “games”: 8, “Mary”: 9, “too”: 10}
该字典中包含10个单词, 每个单词有唯一索引, 注意它们的顺序和出现在句子中的顺序没有关联. 根据这个字典, 我们能将上述两句话重新表达为下述两个向量:
[1, 2, 1, 1, 1, 0, 0, 0, 1, 1]
[1, 1, 1, 1, 0, 1, 1, 1, 0, 0]
这两个向量共包含10个元素, 其中第i个元素表示字典中第i个单词在句子中出现的次数. 如下面的表格所示。
在文本检索和处理应用中, 可以通过该模型很方便的计算词频.
适用场景:
现在想象在一个巨大的文档集合D,里面一共有M个文档,而文档里面的所有单词提取出来后,一起构成一个包含N个单词的词典,利用Bag-of-words模型,每个文档都可以被表示成为一个N维向量。
变为N维向量之后,很多问题就变得非常好解了,计算机非常擅长于处理数值向量,我们可以通过余弦来求两个文档之间的相似度,也可以将这个向量作为特征向量送入分类器进行主题分类等一系列功能中去。
总之通过有效的办法转换为向量之后,后面的一切都变得明朗起来了,因为至少得想办法让计算机理解吧!
代码:
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*- from sklearn.feature_extraction.text import CountVectorizer texts = ['John likes to watch movies, Mary likes too', 'John also likes to watch football games'] cv = CountVectorizer(analyzer='word', max_features=4000) cv_fit = cv.fit_transform(texts) print cv.get_feature_names() # 获得上面稀疏矩阵的列索引,即特征的名字(就是特征词) print '------------------------------------------------------------' print cv_fit.toarray() # 得到分词的系数矩阵-稠密向量矩阵表示 print '------------------------------------------------------------' print cv_fit.toarray().sum(axis=0) # 每个词在所有文档中的词频 print '------------------------------------------------------------' print cv.vocabulary_ # 词汇表-也就是 字典顺序 print '------------------------------------------------------------' print cv_fit # 第一行结果分析: 第0个句子中,**词典中索引为8的元素**, 词频为1
输出结果:
我们直接用scikit-learn的CountVectorizer类来完成词袋模型的实现,这个类可以帮我们完成文本的词频统计与向量化。CountVectorize函数比较重要的几个参数为:
CountVectorizer是通过fit_transform()函数将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在第i个文本下的词频。即各个词语出现的次数,通过get_feature_names()可看到所有文本的关键字,通过toarray()可看到词频矩阵的结果。
还可以使用现有的词袋模型,对其他文本进行特征提取。
代码:
vocabulary = cv.vocabulary_
j = ['John likes icecream and watch food movies']
new_cv = CountVectorizer(min_df=1, vocabulary=vocabulary)
X = new_cv.fit_transform(j)
print X.toarray()
print new_cv.get_feature_names()
结果:
缺点:
但是从上面我们也能够看出,在构造文档向量的过程中可以看到,我们并没有表达单词在原来句子中出现的次序,这也是词袋模型的缺点。因为它仅仅考虑了词频,没有考虑上下文的关系,因此会丢失一部分文本的语义。但是大多数时候,如果我们的目的是分类聚类,则词袋模型表现的很好。
BOW模型有很多缺点,首先它没有考虑单词之间的顺序,其次它无法反应出一个句子的关键词,比如下面这个句子:
“John likes to play football, Mary likes too”
这个句子若用BOW模型,它的词表为:[‘football’, ‘john’, ‘likes’, ‘mary’, ‘play’, ‘to’, ‘too’],则词向量表示为:[1 1 2 1 1 1 1]。若根据BOW模型提取这个句子的关键词,则为 “like”,但是显然这个句子的关键词应该为 “football”。
TF-IDF是一种统计方法,用以评估一个字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。
TF(Term frequency)即词频,其定义为某一个给定的词语在该文件中出现的频率。
t
f
(
w
)
=
单
词
w
在
文
章
中
出
现
的
次
数
该
文
章
的
总
单
词
个
数
tf(w) = \frac{单词w在文章中出现的次数}{该文章的总单词个数}
tf(w)=该文章的总单词个数单词w在文章中出现的次数
IDF(inverse document frequency,逆文本频率)IDF反应了一个词在所有文本中出现的频率,如果一个词在很多的文本中出现,那么它的IDF值应该低,比如“to”;反过来,如果一个词在比较少的文本中出现,那么它的IDF值应该高。比如一些专业的名词如“Machine Learning”。一个极端的情况,如果一个词在所有的文本中都出现,那么它的IDF值应该为0。其公式为:
i
d
f
(
w
)
=
l
o
g
语
料
库
中
文
档
的
总
数
包
含
词
w
的
文
档
数
+
1
idf(w) = log\frac{语料库中文档的总数}{包含词w的文档数 + 1}
idf(w)=log包含词w的文档数+1语料库中文档的总数
那么tf-idf的整体计算公式为:
t
f
−
i
d
f
(
w
)
=
t
f
(
w
)
∗
i
d
f
(
w
)
tf-idf(w) = tf(w) * idf(w)
tf−idf(w)=tf(w)∗idf(w)
TF-IDF值越大说明这个词越重要,也可以说这个词是关键词。
TF-IDF可以在用磁带模型向量化之后,再调用 TF-IDF进行特征处理,也可以直接使用TF-IDF完成向量化和预处理。
代码:
# -*- coding: utf-8 -*- from sklearn.feature_extraction.text import TfidfTransformer from sklearn.feature_extraction.text import CountVectorizer corpus = ['John likes to watch movies, Mary likes too', 'John also likes to watch football games'] # 词袋化 vectorizer = CountVectorizer() X = vectorizer.fit_transform(corpus) print vectorizer.get_feature_names() print X.toarray() # TF-IDF transformer = TfidfTransformer() tfidf = transformer.fit_transform(X) print tfidf.toarray() from sklearn.feature_extraction.text import TfidfVectorizer # 直接使用tf-idf tfidf2 = TfidfVectorizer() re = tfidf2.fit_transform(corpus) print re.toarray()
运行结果:
缺点:
使用了IF-IDF并标准化以后,就可以使用各个文本的词特征向量作为文本的特征,进行分类或者聚类分析。
统计个数和计算频率两种方法虽然非常实用,但是也由其局限性导致词汇量可能变得非常大。词汇量过大又将导致需要非常大的矢量来编码文档,从而对内存产生很大的要求,同时拖慢算法的速度。此时可以使用哈希向量化。哈希向量化可以缓解TfidfVectorizer在处理高维文本时内存消耗过大的问题。
另外,按照传统TF-IDF的思想,往往一些生僻词的IDF(反文档频率)会比较高、因此这些生僻词常会被误认为是文档关键词。
中文分词和英文分词的典型区别:
中文分词的难点:
下面开始介绍几种分词方法:
该方法按照一定策略将待分析的汉字串与一个“充分大的”机器词典中的词条进行匹配,若在词典中找到某个字符串,则匹配成功。识别出一个词。根据扫描方向的不同分为正向匹配和逆向匹配。根据不同长度优先匹配的情况,分为最大(最长)匹配和最小(最短)匹配。根据与词性标注过程是否相结合,又可以分为单纯分词方法和分词与标注相结合的一体化方法。
常用方法有:正向最大匹配、逆向最大匹配、双向匹配
对于输入的一段文本从左至右、以贪心的方式切分出当前位置上长度最大的词。正向最大匹配法是基于词表的分词方法 ,其分词原理是:单词的颗粒度越大,所能表示的含义越确切。
其算法描述如下:
step1: 从左向右取待切分汉语句的m个字符作为匹配字段,m为大机器词典中最长词条个数。
step2: 查找大机器词典并进行匹配。若匹配成功,则将这个匹配字段作为一个词切分出来。若匹配不成功,则将这个匹配字段的最后一个字去掉,剩下的字符串作为新的匹配字段,进行再次匹配,重复以上过程,直到切分出所有词为止。
在实际处理时,先将文档进行倒排处理,生成逆序文档。然后,根据逆序词典,对逆序文档用正向最大匹配法处理即可。
由于汉语中偏正结构较多,若从后向前匹配,可以适当提高精确度。所以,逆向最大匹配法比正向最大匹配法的误差要小。统计结果表明 ,单纯使用正向最大匹配的错误率为 1/16 9,单纯使用逆向最大匹配的错误率为 1/245。例如切分字段“硕士研究生产”,正向最大匹配法的结果会是“硕士研究生 / 产”,而逆向最大匹配法利用逆向扫描,可得到正确的分词结果“硕士 / 研究 / 生产”。
正向最大匹配法得到的分词结果和逆向最大匹配法的到的结果进行比较,从而决定正确的分词方法。
1.如果正反向分词结果词数不同,则取分词数量较少的那个。
2.如果分词结果词数相同 :
首先来简单了解一下n-gram是什么?
一个句子是否合理,就看看它的可能性大小如何”(引自数学之美)。由此,很容易理解语言模型的定义。什么是语言模型(Language Model)?假设 S 表示一个有意义的句子,由一连串特定顺序排列的词 w 1 , w 2 , . . . , w n w_1,w_2,...,w_n w1,w2,...,wn组成,n为句子的长度。
则有: p ( s ) = p ( w 1 ) ∗ p ( w 2 ∣ w 1 ) ∗ p ( w 3 ∣ w 1 , w 2 ) ∗ . . . ∗ p ( w n ∣ w 1 , w 2 , . . . , w n − 1 ) p(s) = p(w_1)*p(w_2|w_1)*p(w_3|w_1,w_2)*...*p(w_n|w_1,w_2,...,w_{n-1}) p(s)=p(w1)∗p(w2∣w1)∗p(w3∣w1,w2)∗...∗p(wn∣w1,w2,...,wn−1),为了使序列 S 的概率最大化,我们也可以最小化 L = ∑ l o g ( w ∣ c o n t e x t ( w ) ) L=\sum log(w|context(w)) L=∑log(w∣context(w)),p(s) 和L都可以被称为语言模型。总而言之,语言模型就是建立了一个基于统计的模型去计算一个序列 S 的可能性。
N-gram就是语言模型。对于前面提到的语言模型从计算上来看,序列的前两个词的条件概率 p ( w 1 ) , p ( w 2 ∣ w 1 ) p(w_1), p(w_2|w_1) p(w1),p(w2∣w1)不难计算,但是,越到后面的单词可能性越多,无法估算。因此,引入马尔可夫假设:任意一个词出现的概率只和它前面的n个词有关。
当 n=1, 一个一元模型(unigram model)即为 : p ( w 1 , w 2 , . . . , w n ) = ∏ i = 1 n p ( w i ) p(w_1,w_2,...,w_n) = \prod_{i=1}^np(w_i) p(w1,w2,...,wn)=∏i=1np(wi)
当 n=2, 一个二元模型(bigram model)即为 : p ( w 1 , w 2 , . . . , w n ) = ∏ i = 1 n p ( w i ∣ w i − 1 ) p(w_1,w_2,...,w_n) = \prod_{i=1}^np(w_i|w_{i-1}) p(w1,w2,...,wn)=∏i=1np(wi∣wi−1)
当 n=3, 一个三元模型(trigram model)即为 : p ( w 1 , w 2 , . . . , w n ) = ∏ i = 1 n p ( w i ∣ w i − 2 , w i − 1 ) p(w_1,w_2,...,w_n) = \prod_{i=1}^np(w_i|w_{i-2}, w_{i-1}) p(w1,w2,...,wn)=∏i=1np(wi∣wi−2,wi−1)
假设n=2,于是 p ( s ) = p ( w 1 ) ∗ p ( w 2 ∣ w 1 ) ∗ p ( w 3 ∣ w 2 ) ∗ . . . ∗ p ( w n ∣ w n − 1 ) p(s) = p(w_1)*p(w_2|w_1)*p(w_3|w_2)*...*p(w_n|w_{n-1}) p(s)=p(w1)∗p(w2∣w1)∗p(w3∣w2)∗...∗p(wn∣wn−1),这就是N-gram模型中的二元模型(bigram)。
有了模型的定义,如何求解模型呢,即该如何计算条件概率呢?
根据定义: p ( w i ∣ w i − 1 ) = p ( w i − 1 , w i ) p ( w i − 1 ) p(w_i|w_{i-1}) = \frac{p(w_{i-1},w_i)}{p(w_{i-1})} p(wi∣wi−1)=p(wi−1)p(wi−1,wi),通过统计语料库(corpus)中的相应词和词对的频数,根据大数定理,只要统计量足够,相对频度就等于概率,即可得到 p ( w i − 1 , w i ) , p ( w i − 1 ) p(w_{i-1},w_i), p(w_{i-1}) p(wi−1,wi),p(wi−1)。这其实就是模型根据训练数据集学习的过程。
由以上介绍的N-gram内容,我们能容易的理解N-gram的一个应用就是评估一个句子是否合理。我这里主要关注N-gram在分词上的应用。思路很简单,既然给定一个句子,N-gram可以计算出一个概率值,那只要列举出所有可能的分词方式,再根据所有可能的分词方式分别计算该句子的概率,选择使句子概率最大的分词方式作为最终分词结果就好了。
例子: 二元语言模型判断句子是否合理
假设现在有一个语料库,我们统计了下面的一些词出现的数量
下面的这些概率值作为已知条件:
p(i|<s>)=0.25, p(english|food)=0.0011, p(food|english)=0.5,p(</s>|food)=0.68,p(want|<s>)=0.25
下面这个表给出的是基于Bigram模型进行计数之结果:
例如,其中第一行,第二列 表示给定前一个词是 “i” 时,当前词为“want”的情况一共出现了827次。据此,我们便可以算得相应的频率分布表如下:
比如说,我们就以表中的p(eat|i)=0.0036这个概率值讲解,从表一得出“i”一共出现了2533次,而其后出现eat的次数一共有9次,p(eat|i)=p(eat,i)/p(i)=count(i,eat)/count(i)=9/2533 = 0.0036。
下面我们通过基于这个语料库来判断s1=“<s> i want english food” 与s2 = "<s> want i english food"哪个句子更合理:
首先来判断p(s1)
P
(
s
1
)
=
P
(
i
∣
<
s
>
)
P
(
w
a
n
t
∣
i
)
P
(
e
n
g
l
i
s
h
∣
w
a
n
t
)
P
(
f
o
o
d
∣
e
n
g
l
i
s
h
)
P
(
<
/
s
>
∣
f
o
o
d
)
=
0.25
×
0.33
×
0.0011
×
0.5
×
0.68
=
0.000031
P(s_1)=P(i|<s>)P(want|i)P(english|want)P(food|english)P(</s>|food)=0.25×0.33×0.0011×0.5×0.68=0.000031
P(s1)=P(i∣<s>)P(want∣i)P(english∣want)P(food∣english)P(</s>∣food)=0.25×0.33×0.0011×0.5×0.68=0.000031
再来求p(s2)?
P ( s 2 ) = P ( w a n t ∣ < s > ) P ( i ∣ w a n t ) P ( e n g l i s h ∣ w a n t ) P ( f o o d ∣ e n g l i s h ) P ( < / s > ∣ f o o d ) = 0.25 ∗ 0.0022 ∗ 0.0011 ∗ 0.5 ∗ 0.68 = 0.00000002057 P(s2)=P(want|<s>)P(i|want)P(english|want)P(food|english)P(</s>|food) =0.25*0.0022*0.0011*0.5*0.68 = 0.00000002057 P(s2)=P(want∣<s>)P(i∣want)P(english∣want)P(food∣english)P(</s>∣food)=0.25∗0.0022∗0.0011∗0.5∗0.68=0.00000002057
通过比较我们可以明显发现0.00000002057<0.000031,也就是说s1= "i want english food"更像人话。
N-gram的一个常见应用
搜索引擎(Google或者Baidu)、或者输入法的猜想\提示。你在用谷歌时,输入一个或几个词,搜索框通常会以下拉菜单的形式给出几个像下图一样的备选,这些备选其实是在猜想你想要搜索的那个词串。
再者,当你用输入法输入一个汉字的时候,输入法通常可以联系出一个完整的词,例如我输入一个“刘”字,通常输入法会提示我是否要输入的是“刘备”。通过上面的介绍,你应该能够很敏锐的发觉,这其实是以N-Gram模型为基础来实现的。比如下图:
那么原理是什么呢?也就是我打入“我们”的时候,后面的“不一样”,”的爱“这些是怎么出来的,怎么排序的?
实际上是根据语言模型得出。假如使用的是二元语言模型预测下一个单词:
排序的过程就是:
p(”不一样“|“我们”)>p(”的爱“|“我们”)>p(”相爱吧“|“我们”)>…>p(“这一家”|”我们“),这些概率值的求法和上面提到的完全一样,数据的来源可以是用户搜索的log。
n-gram的n大小对性能的影响
其中当N为特定值的时候,我们来看一下n-gram可能的总数,如下表
对于上图,我用一个例子来进行解释,加入目前词汇表中就只有三个单词,”我爱你“,那么bigram的总数是
3
2
=
9
3^2 =9
32=9个,有”我我“,我爱,我你,爱爱,爱你,爱我,你你,你我,你爱这9个,所以对应上面的表示是bigrams是
2000
0
2
=
400000000
20000^2=400000000
200002=400000000,trigrams=
2000
0
3
=
8
∗
10
e
12
20000^3= 8*10e12
200003=8∗10e12。
首先用一个简单的例子来了解隐马尔科夫模型HMM:
(1)小明所在城市的天气有{晴天,阴天,雨天}三种情况,小明每天的活动有{宅,打球}两种选项。
(2)作为小明的朋友,我们只知道他每天参与了什么活动,而不知道他所在城市的天气是什么样的。
(3)这个城市每天的天气情况,会和前一天的天气情况有点关系。譬如说,如果前一天是晴天,那么后一天是晴天的概率,就大于后一天是雨天的概率。
(4)小明所在的城市,一年四季的天气情况都差不多。
(5)小明每天会根据当天的天气情况,决定今天进行什么样的活动。
(6)我们想通过小明的活动,猜测他所在城市的天气情况。
那么,城市天气情况和小明的活动选择,就构成了一个隐马尔科夫模型HMM,我们下面用学术语言描述下:
(1)HMM的基本定义: HMM是用于描述由隐藏的状态序列和显性的观测序列组合而成的双重随机过程。在前面的例子中,城市天气就是隐藏的状态序列,这个序列是我们观测不到的。小明的活动就是观测序列,这个序列是我们能够观测到的。这两个序列都是随机序列。
(2)HMM的假设一:马尔科夫性假设。当前时刻的状态值,仅依赖于前一时刻的状态值,而不依赖于更早时刻的状态值。每天的天气情况,会和前一天的天气情况有点关系。
(3)HMM的假设二:齐次性假设。状态转移概率矩阵与时间无关。即所有时刻共享同一个状态转移矩阵。小明所在的城市,一年四季的天气情况都差不多。
(4)HMM的假设三:观测独立性假设。当前时刻的观察值,仅依赖于当前时刻的状态值。小明每天会根据当天的天气情况,决定今天进行什么样的活动。
(5)HMM的应用目的:通过可观测到的数据,预测不可观测到的数据。我们想通过小明的活动,猜测他所在城市的天气情况。
注一:马尔科夫性:随机过程中某事件的发生只取决于它的上一事件,是“无记忆”过程。
注二:HMM被广泛应用于标注任务。在标注任务中,状态值对应着标记,任务会给定观测序列,以预测其对应的标记序列。
注三:HMM属于生成模型,是有向图。
HMM模型一共有三个经典的问题需要解决:
1) 评估观察序列概率。即给定模型
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。