【问题标题】:how to compare two text document with tfidf vectorizer?如何将两个文本文档与 tfidf 矢量化器进行比较?
【发布时间】:2019-05-13 20:46:51
【问题描述】:

我有两个不同的文本,我想使用 tfidf 矢量化进行比较。 我正在做的是:

  1. 标记每个文档
  2. 使用 TFIDFVectorizer.fit_transform(tokens_list) 进行矢量化

现在我在第 2 步之后得到的向量具有不同的形状。 但根据概念,我们应该对两个向量具有相同的形状。只有这样才能比较向量。

我做错了什么?请帮忙。

提前致谢。

【问题讨论】:

  • 如果我弄错了,有人可以纠正我,但通常我认为你不应该在两个不同的词袋上做fit_transform。您应该在一组上做一个fit_transform,然后使用已经安装的矢量化器在第二组上做一个transform,以便与第一组进行比较
  • 有道理...我会再次尝试在第二个文本上使用转换而不是 fit_transform。确实,我应该在第二个文档上使用第一个文档的词汇来检查相似性。不知道为什么我以前没有想到这一点。谢谢
  • 也许这会有所帮助colab.research.google.com/drive/…

标签: python nltk cosine-similarity tfidfvectorizer


【解决方案1】:

正如 G. Anderson 已经指出的,并且为了帮助未来的人,当我们在文档 D1 上使用 TFIDFVectorizer 的拟合函数时,这意味着对于 D1,构建了词袋。

transform() 函数计算词袋中每个词的 tfidf 频率。

现在我们的目标是将文档 D2 与 D1 进行比较。这意味着我们想看看有多少 D1 的单词与 D2 匹配。这就是为什么我们在 D1 上执行 fit_transform() ,然后只有 D2 上的 transform() 函数会应用 D1 的词袋并计算 D2 中标记的逆频率。 这将给出 D1 与 D2 的相对比较。

【讨论】:

    【解决方案2】:

    我是后来的人之一:)

    所以我对 TF-IDF 的理解是 IDF 是计算两个文档中单词(或 Ngram)的频率?因此,比较每个匹配的内容,并不能真正涵盖该词在两个文档中用于淘汰常用词的常见程度?有没有办法用 Ngrams 做到这一点而不会出现索引错误?

    ValueError: 传递值的形状为 (26736, 1),索引暗示 (60916, 1)

    # Applying TFIDF to vectors
    #instantiate tfidVectorizers() 
    ngram_vectorizer1 = TfidfVectorizer(ngram_range = (2,2)) #bigrams 1st vector
    ngram_vectorizer2 = TfidfVectorizer(ngram_range = (2,2)) #bigrams 2nd
    ngram_vectorizert = TfidfVectorizer(ngram_range = (2,2)) #bigrams total
    # fit model 
    ngram_vector1 = ngram_vectorizer1.fit_transform(text) 
    ngram_vector2 = ngram_vectorizer2.fit_transform(text2)
    ngram_vectort = ngram_vectorizert.fit_transform(total)
    ngramfeatures1 = (ngram_vectorizer1.get_feature_names()) #save feature names
    ngramfeatures2 = (ngram_vectorizer2.get_feature_names()) #save feature names
    ngramfeaturest = (ngram_vectorizert.get_feature_names())
    print("\n\nngramfeatures1 : \n", ngramfeatures1)
    print("\n\nngramfeatures2 : \n", ngramfeatures2)
    print("\n\nngram_vector1 : \n", ngram_vector1.toarray())
    print("\n\nngram_vector2 : \n", ngram_vector2.toarray())
    
    
    #Compute the IDF values 
    first_tfidf_transformer_ngram=TfidfTransformer(smooth_idf=True,use_idf=True)
    second_tfidf_transformer_ngram=TfidfTransformer(smooth_idf=True,use_idf=True)
    total_tfidf_transformer_ngram=TfidfTransformer(smooth_idf=True,use_idf=True) 
    first_tfidf_transformer_ngram.fit(ngram_vector1)
    second_tfidf_transformer_ngram.fit(ngram_vector2)
    total_tfidf_transformer_ngram.fit(ngram_vectort)
    
    
    # print 1st idf values 
    ngram_first_idf = pd.DataFrame(first_tfidf_transformer_ngram.idf_, index=ngram_vectorizer1.get_feature_names(),columns=["idf_weights"]) 
     
    # sort ascending 
    ngram_first_idf.sort_values(by=['idf_weights'])  #this one should really be looking towards something from the "Total" calculations if I'm understanding it correctly? ```
    
    
    
    
    
    
    
    
    
    
    
    
    
    

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    • 我不确定,你想做的事情是什么,也许其他人可以回答得更好。我可以这样回答,TF是指文档中一个词的计数与总词数的比值。 IDF 是指包含该术语的文档数量与该术语的总出现次数的比率。所以 TF 告诉你这个词对那个文档有多重要,而 IDF 告诉这个词对所有文档有多重要……所以当你想清除常用词时,你会找到 IDF,然后根据阈值将其删除。我喜欢这个主意。 (阅读下一条评论,因为不能写更多)
    • 但请理解这一点,当您对 text1 执行 fit_transform 时,您是从 text1 定义一个词汇表。然后你会想使用这个词汇来计算 text2 上的 idf。您目前正在做的是为 text1 和 text2 找到不同的词汇表,因此无法计算 idf,因为始终只有 1 个文档。在 text1 上应用 fit_transform 方法后对 text 2 做一个变换方法,然后你会得到更好的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-07
    • 2014-03-03
    • 2019-01-04
    • 1970-01-01
    • 1970-01-01
    • 2015-06-20
    • 2018-06-04
    相关资源
    最近更新 更多