TF-IDF计算相似度为什么要对稀疏向量建立索引?

TF-IDF的向量表示的稀疏问题

    之前在看tf-idf代码时候思考了一个问题,不知道对于初学的大部分同学有没有这样一个疑惑,用tf-idf值构成的向量,维度可能跟词表的大小有关,那么对于一句话来说,这样的向量表示是不是太稀疏了?
例如,对于下面的数据(文档),词表大小为32个词,那么我们每一句话(eg:['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'])将用32维的向量表示,但是这句话中只涉及7个词,其余25个位置全为0,这样岂不是很稀疏?对于此表更大的情况,计算相似度的时候会不会很慢甚至出错?

dataset = [['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'], 
               ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
               ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
               ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
               ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
               ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]

    果然会有这样的问题,但是我也看到了解决方法,那就是为稀疏向量建立索引。
今天看到了代码,这个代码使用的是gensim这个库写的,

  
# 获取语料库每个文档中每个词的tfidf值,即用tfidf模型训练语料库
tfidf = models.TfidfModel(corpus)
# 对稀疏向量建立索引
index = similarities.SparseMatrixSimilarity(tfidf[corpus], num_features=len(dictionary.keys()))
sim = index[tfidf[doc_text_vec]]  # 相当于sim = index.get_similarities(tfidf[doc_text_vec])

稀疏向量

其实这种处理方式并不是在tf-idf中特有的,而是对于处理这一类向量的一种方法,这种向量我们称为稀疏向量(sparse vector),与稀疏向量相对应的当然就是密集向量(dense vector)。对于这两种向量的表示,我们可以从下面这个例子看出来:
比如向量(1,0,3,4)的创建有三种方法:

密集向量:直接Vectors.dense(1,0,3,4)

稀疏向量:

方法一:Vector.sparse(4,(0,2,3),(1,3,4)) (0,2,3)

    表示该向量的第0个,第2个,第3个位置,(1,3,4) 表示(0,2,3)位置对应的数值分别为1,3,4

方法二:Vector.sparse(4,(0,1),(2,3),(3,4))

    (0,1)就是(索引,数值)的形式。位置0的数值为1, 位置2的数值为3,位置3的数值为4
对于之前提到的gensim的代码,我debug后得到测试句子的tf-idf向量表示

  (0, 0)	0.3536708
  (0, 1)	0.37080795
  (0, 2)	0.37080795
  (0, 3)	0.12360264
  (0, 4)	0.1768354
  (0, 5)	0.1768354
  (0, 6)	0.1768354
  (0, 7)	0.1768354
  (0, 8)	0.1768354
  (0, 9)	0.1768354
  (0, 10)	0.1768354
  (0, 11)	0.1768354
  (0, 12)	0.1768354
  (0, 13)	0.039230715
  (0, 14)	0.1768354
  (0, 15)	0.070369884
  (0, 16)	0.1768354
  (0, 17)	0.1768354
  (0, 18)	0.1768354
  (0, 19)	0.12360264
  (0, 20)	0.1768354
  (0, 21)	0.1768354
  (0, 22)	0.1768354
  (0, 23)	0.1768354
  (0, 24)	0.1768354
  :     :
  :    :
  (9, 53)	0.1024829
  (9, 55)	0.03036039
  (9, 58)	0.04348179
  (9, 82)	0.077995226
  (9, 92)	0.1024829
  (9, 95)	0.1024829
  (9, 110)	0.3074487
  (9, 122)	0.13699634
  (9, 135)	0.1024829
  (9, 155)	0.2739927
  (9, 168)	0.1024829
  (9, 224)	0.13699634
  (9, 269)	0.13699634
  (9, 311)	0.19599745
  (9, 312)	0.19599745
  (9, 313)	0.19599745
  (9, 314)	0.19599745
  (9, 315)	0.19599745
  (9, 316)	0.3919949
  (9, 317)	0.19599745
  (9, 318)	0.19599745
  (9, 319)	0.19599745
  (9, 320)	0.19599745
  (9, 321)	0.19599745
  (9, 322)	0.19599745

具体什么意思呢,也就是说这个测试样句一共有10个词,第一个词也就是位置为0的那个词,它的值为词表的第一个词时候,它的tf-idf值为0.3536708,所以表示为(0, 0) 0.3536708,那这个位置如果为此表中第二个词的时候,tf-idf值为多少呢?没错就是0.37080795,表示为:(0, 1) 0.37080795,其它的就同理啦

猜你喜欢

转载自www.cnblogs.com/ZhangHT97/p/13380726.html