sklearn中CountVectorizer与TfidfTransformer使用案例

一、词频处理的应用

词频

故名思议说的是文章中每个单词的出现频数统计量。
通过统计词频,基本可以获取一篇文本的关键字,从而了解一篇文本主要讲述的大致内容

比如,“你女神在空虚寂寞冷的时候甩给你一篇有关女性化妆的长文,但是你对于YSL,雪花秀这些东西是什么鬼并不知道。如果你看了半天也不知道她发给你的东西是什么鬼的话,女神会觉得你显然是个“土牛”,如果通过获取一些关键信息并第一时间进行检索,将会使得你可以在第一时间找到撩妹的话题,这样一来,你既节约了时间,有获得了女神的芳心”

同时,对于词频的统计也将是进一步得到文本简介的第一步。

二、CountVectorizer与TfidfTransformer

在了解这个之前,了解一下TF-IDF还是比较有必要的。

TF-IDF(Term Frequency–Inverse Document Frequency)是一种用于资讯检索与文本挖掘的常用加权技术。TF-IDF是一种统计方法,用以评估一个字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。TF-IDF加权的各种形式常被搜索引擎应用,作为文件与用户查询之间相关程度的度量或评级。

TF-IDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。TF-IDF实际上是:TF * IDF。
  
(1)词频(Term Frequency,TF)指的是某一个给定的词语在该文件中出现的频率。即词w在文档d中出现的次数count(w, d)和文档d中总词数size(d)的比值。

1
tf(w,d) = count(w, d) / size(d)

这个数字是对词数(term count)的归一化,以防止它偏向长的文件。(同一个词语在长文件里可能会比短文件有更高的词数,而不管该词语重要与否。)
  
(2)逆向文件频率(Inverse Document Frequency,IDF)是一个词语普遍重要性的度量。某一特定词语的IDF,可以由总文件数目除以包含该词语之文件的数目,再将得到的商取对数得到。即文档总数n与词w所出现文件数docs(w, D)比值的对数。  

1
idf = log(n / docs(w, D))

TF-IDF根据 tf 和 idf 为每一个文档d和由关键词w[1]…w[k]组成的查询串q计算一个权值,用于表示查询串q与文档d的匹配度:

1
tf-idf(q, d) = sum { i = 1..k | tf-idf(w[i], d) } = sum { i = 1..k | tf(w[i], d) * idf(w[i]) }

某一特定文件内的高词语频率,以及该词语在整个文件集合中的低文件频率,可以产生出高权重的TF-IDF。因此,TF-IDF倾向于过滤掉常见的词语,保留重要的词语。

在IDF中可以发现,当某个词在语料库中各个文档出现的次数越多,它的IDF值越低,当它在所有文档中都出现时,其IDF计算结果为0,而通常这些出现次数非常多的词或字为“的”、“我”、“吗”等,它对文章的权重计算起不到一定的作用。

Scikit-Learn中TF-IDF权重计算方法主要用到两个类:CountVectorizer和TfidfTransformer

1.CountVectorizer
CountVectorizer类会将文本中的词语转换为词频矩阵,例如矩阵中包含一个元素a[i][j],它表示j词在i类文本下的词频。它通过fit_transform函数计算各个词语出现的次数,通过get_feature_names()可获取词袋中所有文本的关键字,通过toarray()可看到词频矩阵的结果。

from sklearn.feature_extraction.text import CountVectorizer

#语料
corpus = [
        'This is the first document.',
        'This is the second second document.',
        'And the third one.'
        'Is this the first document?'
        ]

# 将文本中的词语,转换成词频矩阵

vectorizer = CountVectorizer()

# 计算词语出现的频率
X = vectorizer.fit_transform(corpus)

# 获取词袋中所有文本关键词
words = vectorizer.get_feature_names()
print(words)

# 查看词频结果
'''
同时在输出每个句子中包含特征词的个数。例如,第一句“This is the first document.”,它对应的
词频为[0, 1, 1, 1, 0, 0, 1, 0, 1],假设初始序号从1开始计数,则该词频表示存在第2个位置的单
词“document”共1次、第3个位置的单词“first”共1次、第4个位置的单词“is”共1次、第9个位置的单词
“this”共1词。所以,每个句子都会得到一个词频向量。
'''
print(X.toarray())

2.TfidfTransformer
TfidfTransformer用于统计vectorizer中每个词语的TF-IDF值。具体用法如下:
from sklearn.feature_extraction.text import TfidfTransformer

#类调用
transformer = TfidfTransformer()
print(transformer)

tfidf = transformer.fit_transform(X)

print(tfidf.toarray())

PS.在做中文词频处理时,需要事先对文本进行分词。
英文的话就不必要了,因为英文本身就是单词与单词分开的。

比如:

we are young.

处理前:

北京的冬天太冷,我没有足够的衣裳过冬。

处理后:

北京 的 冬天 太 冷 , 我 没有 足够 的 衣裳 过冬 。

三、一个完整的Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import jieba #易用高效的分词库

'''
避免专业名词被拆分
如 机器学习 ---> 机器 学习 X
机器学习 √
'''
jieba.add_word('机器学习')
jieba.add_word('人工智能')
jieba.add_word('AI')

file_object = open('article.txt')
try:
all_the_text = file_object.read( )
finally:
file_object.close( )

text = all_the_text
text_cut = " ".join(jieba.cut(text,cut_all = True))


corpus_zh = [text_cut]

#转换词频矩阵
vectorizer_zh = CountVectorizer()
# 计算词频出现频率
X_zh = vectorizer_zh.fit_transform(corpus_zh)

# 获取词袋中文本关键词
word_zh = vectorizer_zh.get_feature_names()

print(word_zh)
#数据转换 输出所有shape的元素
X_zh_array = X_zh.toarray().flat
print(X_zh_array)

#统计X_zh中每个词语的TF-IDF值
trancformer_zh = TfidfTransformer()
tf_zh = trancformer_zh.fit_transform(X_zh)

tf_zh_array = tf_zh.toarray().flat

# 包装一个字典
result_dic = {}

print("词---->权重")
for i in range(len(tf_zh_array)):
key = "%s"%(word_zh[i])
result_dic[key] = tf_zh_array[i]

# 对字典进行排序
result_dic= sorted(result_dic.items(), key=lambda d:d[1], reverse = True)

print(result_dic)

由此,基于sklearn的中文词频及关键字获取已经实现。

参考资料:

坚持原创技术分享,您的支持将鼓励我继续创作!