我按照示例here使用sklearn计算TF-IDF值。
我的代码如下。
from sklearn.feature_extraction.text import TfidfVectorizer
myvocabulary = ['life', 'learning']
corpus = {1: "The game of life is a game of everlasting learning", 2: "The unexamined life is not worth living", 3: "Never stop learning"}
tfidf = TfidfVectorizer(vocabulary = myvocabulary, ngram_range = (1,3))
tfs = tfidf.fit_transform(corpus.values())
我想为life
中的3个文档计算两个单词learning
和corpus
的tf-idf值。
但是,我从代码中获得的值完全不同。请帮助我找到我的代码中的错误以及如何修复它。
答案 0 :(得分:2)
重点是在构造术语频率矩阵之前,不应将词汇量限制为仅两个词(“生命”,“学习”)。如果这样做,所有其他单词将被忽略,它将影响术语频率计数。
如果想通过使用sklearn获得与示例中完全相同的数字,还需要考虑其他几个步骤:
示例中的功能是unigrams(单个单词),所以我有
设置ngram_range=(1,1)
。
该示例使用与sklearn不同的规范化 频率部分(术语计数按文档长度标准化 在示例中,而sklearn默认使用原始术语计数)。 因此,我对术语频率进行了计数和归一化 在计算idf部分之前单独进行。
idf部分示例中的规范化也不是
sklearn的默认值。这可以调整以匹配示例
将smooth_idf
设置为false。
Sklearn的矢量化器默认情况下只丢弃一个字
字符,但这些单词保留在示例中。在代码中
下面,我修改了token_pattern
以允许1个字符
词语的
最终的tfidf矩阵是通过将归一化计数乘以idf向量得到的。
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn.preprocessing import normalize
import pandas as pd
corpus = {1: "The game of life is a game of everlasting learning", 2: "The unexamined life is not worth living", 3: "Never stop learning"}
cvect = CountVectorizer(ngram_range=(1,1), token_pattern='(?u)\\b\\w+\\b')
counts = cvect.fit_transform(corpus.values())
normalized_counts = normalize(counts, norm='l1', axis=1)
tfidf = TfidfVectorizer(ngram_range=(1,1), token_pattern='(?u)\\b\\w+\\b', smooth_idf=False)
tfs = tfidf.fit_transform(corpus.values())
new_tfs = normalized_counts.multiply(tfidf.idf_)
feature_names = tfidf.get_feature_names()
corpus_index = [n for n in corpus]
df = pd.DataFrame(new_tfs.T.todense(), index=feature_names, columns=corpus_index)
print(df.loc[['life', 'learning']])
然而,实际上很少需要这样的修改。通过直接使用TfidfVectorizer
,通常可以获得良好的结果。