词袋模型&TF-IDF

前言

在许多NLP任务中,将文档转换成数学形式的“向量”是解决任务所必须的处理过程。其中词袋模型(Bag of Word)、TF-IDF是两种最基本的处理方式。
 

BOW原理

假设有 M M M篇需处理的文档,那么怎样使用向量的形式来表示每一篇文档呢?并且这个向量应该不能丢失掉原始文档的过多信息。

一种思路为, 可以设置 N N N个问题,然后对于每一篇文档,依次回答给定的所有问题,并仅记录问题的答案,再将答案按照一定的格式组合成向量,那么就可以认为该向量包含了原始文档的部分信息。

具体到词袋模型, N N N个问题对应 N N N个词汇,每个问题可以表述为“该篇文档中,第 N N N个词出现几次?”,将所有问题的答案按词典顺序组合成向量,则该向量就是文档在词袋模型中的向量表示。

虽然词袋模型比较直观,但其最大的缺陷就是“丢失了语序信息, 而语序在NLP中十分重要”。
 

gensim实现BOW

corpus = [['human', 'interface', 'computer'],
 ['survey', 'user', 'computer', 'system', 'response', 'time'],
 ['eps', 'user', 'interface', 'system'],
 ['system', 'human', 'system', 'eps'],
 ['user', 'response', 'time'],
 ['trees'],
 ['graph', 'trees'],
 ['graph', 'minors', 'trees'],
 ['graph', 'minors', 'survey']]

from gensim import corpora
# construct dictionary
dct = corpora.Dictionary(documents=corpus)

# call doc2bow method
corpus_bow = [dct.doc2bow(document) for document in corpus]

import pprint
pprint.pprint(corpus_bow)

# outcome
# sparse format: filter 0 count item
[[(0, 1), (1, 1), (2, 1)],
 [(0, 1), (3, 1), (4, 1), (5, 1), (6, 1), (7, 1)],
 [(2, 1), (5, 1), (7, 1), (8, 1)],
 [(1, 1), (5, 2), (8, 1)],
 [(3, 1), (6, 1), (7, 1)],
 [(9, 1)],
 [(9, 1), (10, 1)],
 [(9, 1), (10, 1), (11, 1)],
 [(4, 1), (10, 1), (11, 1)]]

TF-IDF原理

TF-IDF(Term Frequency - Inverse Document Frequency)可以认为是对BOW的改进,在BOW中,文档向量的表示仅采用了词频信息,忽略了词本身的重要性信息,然后词本身的信息也十分重要。举个例子,“的”这个词在一篇文档出现很多次,但该词对一篇文档的信息表示意义却不是很大,而有些文档“主题词”可能只出现一两次,却能充分表示文档的意义。

TF-IDF的计算如下所示:
T F − I D F i , j = T e r m F r e q u e n c y i , j ∗ l o g 2 ( D D o c u m e n t F r e q u e n c y i ) TF-IDF_{i,j} = TermFrequency_{i, j} * log_2(\frac D {DocumentFrequency_i}) TFIDFi,j=TermFrequencyi,jlog2(DocumentFrequencyiD)

i i i表示某个词, j j j表示某篇文档, T e r m F r e q u e n c y i , j TermFrequency_{i, j} TermFrequencyi,j表示第 i i i个词在第 j j j篇文档中的频数, D D D表示文档库中文档的数量, D o c u m e n t F r e q u e n c y i DocumentFrequency_i DocumentFrequencyi表示文档库中包含第 i i i个词的文档的数量。从上述计算表达式可以看出,若某个词在大量文档中都出现,则其TF-IDF值将相对较低。
 

gensim 实现TF-IDF

from gensim import models
# 不对文档向量进行归一化
tf_idf = models.TfidfModel(bow_corpus, normalize=False)

print(tf_idf[bow_corpus[0]]
# outcome
# [(0, 2.1699250014423126), (1, 2.1699250014423126), (2, 2.1699250014423126)]

# import math
# 1 * math.log(9/2, 2) == 2.1699250014423126

# 对文档向量进行归一化
tf_idf = models.TfidfModel(bow_corpus, normalize=True)
print(tf_idf[bow_corpus[0]]

# outcome
# [(0, 0.5773502691896257), (1, 0.5773502691896257), (2, 0.5773502691896257)]

# math.pow(math.pow(0.5773502691896257, 2) * 3, 0.5) == 1.0

 

参考资料

gensim core concept

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值