Scikit-learn CountVectorizer与TfidfVectorizer

本文主要介绍两个类的基本使用,CountVectorizer与TfidfVectorizer,这两个类都是特征数值计算的常见方法。对于每一个训练文本,CountVectorizer只考虑每种词汇在该训练文本中出现的频率,而TfidfVectorizer除了考量某一词汇在当前训练文本中出现的频率之外,同时关注包含这个词汇的其它训练文本数目的倒数。相比之下,训练文本的数量越多,TfidfVectorizer这种特征量化方式就更有优势。

1. sklearn.feature_extraction.text.CountVectorizer

这个类的主要作用是统计每一个训练文本中,每个单词出现的频率;然后构成一个特征矩阵,每一行表示一个训练文本的词频统计结果。其思想是,先根据所有训练文本,不考虑其出现顺序,只将训练文本中每个出现过的词汇单独视为一列特征,构成一个词汇表(vocabulary list),该方法又称为词袋法(Bag of Words)

#python2.7 sklearn version 0.18.1
from sklearn.feature_extraction.text import CountVectorizer
X_test = ['I sed about sed the lack',
'of any Actually']

count_vec=CountVectorizer(stop_words=None)
print count_vec.fit_transform(X_test).toarray()
print '\nvocabulary list:\n\n',count_vec.vocabulary_

>>
>>
[[1 0 0 1 1 0 2 1]
 [0 1 1 0 0 1 0 0]]
 
  (0, 4)	1
  (0, 7)	1
  (0, 0)	1
  (0, 6)	2
  (0, 3)	1
  (1, 1)	1
  (1, 2)	1
  (1, 5)	1
  
vocabulary list:

{u'about': 0, u'i': 3, u'of': 5, u'lack': 4, u'actually': 1, u'sed': 6, u'the': 7, u'any': 2}

关于上面的代码,有几点说明:
(1)第6行代码中,stop_words=None表示不去掉停用词,若改为stop_words='english’则去掉停用词;
(2)第12,13行,分别是X_test中,两段文本的词频统计结果;
(3)第15-22行,是稀疏矩阵的表示方式;
(4)CountVectorizer同样适用于中文

# -*- coding: utf-8 -*-
from sklearn.feature_extraction.text import CountVectorizer

X_test = [u'没有 你 的 地方 都是 他乡',u'没有 你 的 旅行 都是 流浪']

count_vec=CountVectorizer(token_pattern=r"(?u)\b\w\w+\b")
print count_vec.fit_transform(X_test).toarray()
print count_vec.fit_transform(X_test)
print '\nvocabulary list:\n'
for key,value in count_vec.vocabulary_.items():
    print key,value

>>
>>
[[1 1 0 1 0 1]
 [0 0 1 1 1 1]]
  (0, 0)	1
  (0, 5)	1
  (0, 1)	1
  (0, 3)	1
  (1, 4)	1
  (1, 2)	1
  (1, 5)	1
  (1, 3)	1

vocabulary list:

他乡 0
地方 1
旅行 2
没有 3
都是 5
流浪 4

2.sklearn.feature_extraction.text.TfidfVectorizer

2.1 tf-idf

首先介绍一下如何计算tf-idf,并且需要明确的是tf-idf=tf*idf,也就是说tf与idf分别是两个不同的东西。其中tf为谋个训练文本中,某个词的出现次数,即词频(Term Frequency);idf为逆文档频率(Inverse Document Frequency),对于词频的权重调整系数。

其中:
词 频 ( T F ) = 某 个 词 在 文 章 中 的 出 现 次 数 \begin{aligned} 词频(TF)=某个词在文章中的出现次数 \end{aligned} TF=

考虑到文章有长短之分,为了便于不同文章的比较,进行"词频"标准化。
词 频 ( T F ) = 某 个 词 在 文 章 中 的 出 现 次 数 文 章 的 总 词 数 或 者 词 频 ( T F ) = 某 个 词 在 文 章 中 的 出 现 次 数 该 训 练 文 本 中 出 现 最 多 次 的 词 数 \begin{aligned} &词频(TF)=\frac{某个词在文章中的出现次数}{文章的总词数}\\[1ex] &或者\\[1ex] &词频(TF)=\frac{某个词在文章中的出现次数}{该训练文本中出现最多次的词数} \end{aligned} TF=TF=

逆 文 档 频 率 ( I D F ) = log ⁡ ( 总 样 本 数 包 含 有 该 词 的 文 档 数 + 1 ) 逆文档频率(IDF)=\log\left(\frac{总样本数}{包含有该词的文档数+1}\right) (IDF)=log(+1)

如果一个词越常见,那么分母就越大,逆文档频率就越小越接近0。分母之所以要加1,是为了避免分母为0(即所有文档都不包含该词)。log表示对得到的值取对数(此处为自然对数)。

假定某训练文本长度为1000个词,“中国”、“蜜蜂”、“养殖"各出现20次,则这三个词的"词频”(TF)都为0.02。然后,搜索Google发现,包含"的"字的网页共有250亿张,假定这就是中文网页总数(即总样本数)。包含"中国"的网页共有62.3亿张,包含"蜜蜂"的网页为0.484亿张,包含"养殖"的网页为0.973亿张。则它们的逆文档频率(IDF)和TF-IDF如下:

NULL包含该词的文档数(亿)TFIDFTF-IDF
中国62.30.020.6030.0121
蜜蜂0.4840.022.7130.0543
养殖0.9730.022.4100.0482

如:
0.02 ∗ log ⁡ ( 25000000000 6230000000 + 1 ) = 0.02 ∗ 0.603 = 0.0121 0.02*\log\left(\frac{25000000000}{6230000000+1}\right)=0.02*0.603=0.0121 0.02log(6230000000+125000000000)=0.020.603=0.0121

从上表可见,"蜜蜂"的TF-IDF值最高,"养殖"其次,"中国"最低。所以,如果只选择一个词,"蜜蜂"就是这篇文章的关键词。

2.2 TfidfVectorizer

参数表作用
stop_words停用词表;自定义停用词表
token_pattern过滤规则;
属性表作用
vocabulary_词汇表;字典型
idf_返回idf值
stop_words_返回停用词表
方法表作用
fit_transform(X)拟合模型,并返回文本矩阵
# -*- coding: utf-8 -*-
from sklearn.feature_extraction.text import TfidfVectorizer
X_test = ['没有 你 的 地方 都是 他乡','没有 你 的 旅行 都是 流浪']
stopword = [u'都是'] #自定义一个停用词表,如果不指定停用词表,则默认将所有单个汉字视为停用词;
#但可以设token_pattern=r"(?u)\b\w+\b",即不考虑停用词

tfidf=TfidfVectorizer(token_pattern=r"(?u)\b\w\w+\b",stop_words=stopword)
weight=tfidf.fit_transform(X_test).toarray()
word=tfidf.get_feature_names()

print 'vocabulary list:\n'
for key,value in tfidf.vocabulary_.items():
    print key,value

print 'IFIDF词频矩阵:\n'
print weight

for i in range(len(weight)):  
# 打印每类文本的tf-idf词语权重,第一个for遍历所有文本,
#第二个for便利某一类文本下的词语权重
    print u"-------这里输出第", i, u"类文本的词语tf-idf权重------"
    for j in range(len(word)):
        print word[j], weight[i][j]#第i个文本中,第j个次的tfidf值
        

>>
>>
vocabulary list:
没有 3
他乡 0
地方 1
旅行 2
流浪 4

IFIDF词频矩阵:
[[ 0.6316672   0.6316672   0.          0.44943642  0.        ]
 [ 0.          0.          0.6316672   0.44943642  0.6316672 ]]
-------0 类文本的词语tf-idf权重------
他乡 0.631667201738
地方 0.631667201738
旅行 0.0
没有 0.449436416524
流浪 0.0
-------1 类文本的词语tf-idf权重------
他乡 0.0
地方 0.0
旅行 0.631667201738
没有 0.449436416524
流浪 0.631667201738

参考:

  • http://www.ruanyifeng.com/blog/2013/03/tf-idf.htm
  • Python机器学习即实践

更多内容欢迎扫码关注公众号月来客栈!

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页