【发布时间】:2021-09-02 16:13:11
【问题描述】:
我正在从头开始实现 sklearn 的 (vectorizer.idf_) 函数并比较结果。所以对于一个给定的语料库来说,
SKLEARN 实施:-
corpus = [
'this is the first document',
'this document is the second document',
'and this is the third one',
'is this the first document',
]
from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer()
vectorizer.fit(corpus)
skl_output = vectorizer.transform(corpus)
print(vectorizer.get_feature_names())
OUTPUT:- ['and', 'document', 'first', 'is', 'one', 'second', 'the', 'third', 'this']
print(vectorizer.idf_)
OUTPUT:- [1.91629073 1.22314355 1.51082562 1. 1.91629073 1.91629073
1. 1.91629073 1. ]
我的自定义代码如下,其中我有一个 fit() 方法,该方法将语料库转换为字典和一个名为 idf() 的函数,它将计算特定单词在给定语料库中出现的次数和变换() 函数,我正在计算 idf 值。
corpus = [
'this is the first document',
'this document is the second document',
'and this is the third one',
'is this the first document',
]
def fit(dataset):
storage_set = set()
if isinstance(dataset,list):
for document in dataset:
for word in document.split(" "):
storage_set.add(word)
storage_set = sorted(list(storage_set))
vocab = {j:i for i,j in enumerate(storage_set)}
#Idf_values_of_all_unique_words=IDF(dataset,storage_set)
#print(list(storage_set))
return vocab
vocab = fit(corpus)
print(vocab)
OUTPUT:- {'and': 0, 'document': 1, 'first': 2, 'is': 3, 'one': 4, 'second': 5, 'the': 6, 'third': 7, 'this': 8}
def idf(dataset,word):
count=0
for row in dataset:
if word in row:
count+=1
return count
def transform(dataset,vocab):
row = []
col = []
values = []
idf_value=[]
for ibx,document in enumerate(dataset):
word_freq = dict(Counter(document.split()))
for word, freq in word_freq.items():
col_index = vocab.get(word,-1)
if col_index != -1:
if len(word)<2:
continue
col.append(col_index)
row.append(ibx)
term_freq = freq/(len(document)) # the number of times a word occured in a document
idf_ = 1+math.log((1+len(dataset))/(1+idf(dataset,word)))
values.append((term_freq) * (idf_))
idf_value.append(idf_)
print(idf_value)
OUTPUT:- [1.0, 1.0, 1.0, 1.5108256237659907, 1.2231435513142097, 1.0, 1.2231435513142097, 1.0, 1.0, 1.916290731874155, 1.916290731874155, 1.0, 1.0, 1.0, 1.916290731874155, 1.916290731874155, 1.0, 1.0, 1.0, 1.5108256237659907, 1.2231435513142097]
所以如果我比较 sklearn 输出的 idf 分数,它是一个由 9 个值组成的数组,因为语料库中有 9 个不同的单词,但我得到一个大小为 22 的数组。有人可以帮我理解我在做什么错了。
【问题讨论】:
-
使用
print()查看变量中的值以及执行了哪些代码行 - 并将其与纸上的计算进行比较。 -
你已经嵌套了
for-loops - 第一次运行 4 次(文档数),内部运行 9 次(单词数),所以它甚至可能产生 36 个元素。这可能意味着您以错误的方式计算它。可能您将每个值单独保存 - 对于每个文档分隔值。但是对于每个单词,您应该从所有文档中累积值。也许您应该将结果保留为values[word] = [result1, result2],然后使用它们全部计算(term_freq) * (idf_)
标签: python scikit-learn nlp tfidfvectorizer