文本特征提取的两个非常重要的模型:
词集模型:单词构成的集合,即词集中的每个单词都只有一个。
词袋模型:在词集模型的基础上如果一个单词在文档中出现不止一次,统计其出现的次数(频数)。
两者本质上的区别就是词袋模型在词集模型的基础上增加了频率的维度,词集只关注有和没有,词袋还要关注有几个。
如果需要根据每个文档中的单词数量构建词袋模型,可以使用sklearn中的CountVectorizer类。
CountVectorizer以文本数据数组作为输入,其中文本数据可以是个文档仅仅是个句子,返回的就是所要构建的词袋模型。
from sklearn.feature_extraction.text import CountVectorizer
count = CountVectorizer()
doc = np.array(['This is the first document.','This document is the second document.',
'And this is the third one.','Is this the first document?'])
bag = count.fit_transform(doc)
#{'this': 8, 'is': 3, 'the': 6, 'first': 2, 'document': 1, 'second': 5, 'and': 0, 'third': 7, 'one': 4}
# 字典形式呈现,key:词,value:特征索引
print('内容:%s'%count.vocabulary_)
print('特征向量:')
print(bag.toarray())
通过调用CountVectorizer的fit_tranform方法,创建了词袋模型的词汇库,并将代码中doc数组中的句子转换为稀疏的特征向量。
在特征向量中出现的值也称为原始词频tf(t,d)词汇t在文档d中出现的次数——某单词在某句话或某文档中出现的次数。(例如上图特征向量中的2是特征索引为2的单词在第二个句子中出现了2次。)
上面创建的词袋模型中,各项目的序列也称为1元组(1-gram)或单元组(unigram)模型——划分出的每一项都代表一个词汇。
所以自然语言处理(NLP)中个对象的序列也称为n元组(n-gram)。
n元组表示的概念:
1元组:“the”,“sun”,“is”,“shining”。
2元组:“the sun”,“sun is”,“is shining”
CountVecorizer函数中设置ngram_range参数可以使用不同的n元组模型。
count = CountVectorizer(ngram_range=(2,2))
在分析文本时,一个单词如果出现在两种类型的多个文档中,这种频繁出现的单词通常不包含有用的或者具有辨识度的信息。
词频-逆文档频率(TF-IDF模型)可以解决特征向量中单词频繁出现的问题。
tf-idf可以定义为词频与逆文档频率的乘积:
tf-idf(t,d)= tf(t,d)*idf(t,d)
其中tf(t,d)为词频,而逆文档频率idf(t,d)的计算公式为:
nd:文档的总数
df(d,t):包含词汇t的文档d的数量。
对于没有出现在任何训练样本中的词汇,为了保证分母不为0,则加入常数1。
取对数事为了保证文档中出现频率较低的词汇不会被赋予过大的权重。
sklearn中的TfidfTransformer模块以CountVectorizer的原始词频作为输入,并将其转化为TF-IDF:
#TF-IDF
from sklearn.feature_extraction.text import TfidfTransformer
import numpy as np
tfidf = TfidfTransformer()
#打印数组中全部元素
#precision参数表示保留几位小数
np.set_printoptions(precision=2)
tfidf_t = tfidf.fit_transform(bag)print('TF-IDF:')
print(tfidf_t.toarray())
在词袋模型中document是第二个文档出现词频最高的单词,而且他还是文档中出现最为频繁的单词,同时在第三个文档中没有docoment单词的出现,所以document在第二个文档中获得了相对较高的tf-idf(0-69),它可能包含有用或者是有辨识度的信息。
与之前定义的标准tf-idf计算公式不同,sklearn中实现的idg和tf-idf分别为:
通常tf-idf在计算之前都会对原始词频进行归一化处理,TfidfTransformer直接对tf-idf做了归一化处理。
在文档2中,单词document的词频为2(tf=2),由于document在三个文档中出现过,所以它的文档频率为3(df=3)。所以我们可以得到关于document的idf:
tf-idf('document','2') =2*(1+0.0969)=2.1938
然后对第二个文档中所有数值进行该过程,将会得到一个tf-idf向量。
最后对该tf-idf向量进行L2(TfidfTransformer默认使用L2正则化)归一化即可得到sklearn中TfidfTransformer所得到的的值。
本文分享自微信公众号 - 小啦的学习笔记(woshiguolala)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
来源:oschina
链接:https://my.oschina.net/u/3896378/blog/4445891