Я пытался реализовать преобразователь tfidf с нуля, аналогичный тому, который реализован в sklearn. Мои векторы IDf такие же, как и в версии sklearn, но когда я умножаю TF и IDF и нормализую их с помощью нормализации L2, я получаю другой результат, чем у sklearn. словарь с ключами в виде слов и значений в качестве индексов
def fit(dataset):
unique_words = set() # at first we will initialize an empty set
if isinstance(dataset, list): # check if its list type or not
lower_dataset = [doc.lower() for doc in dataset]
for doc in lower_dataset: # for each review in the dataset
for word in doc.split(" "): # for each word in the review. #split method converts a string into list of words
if len(word) < 2:
continue
unique_words.add(word)
unique_words = sorted(list(unique_words))
vocab = {j:i for i,j in enumerate(unique_words)}
return vocab
else:
return "You need to pass list of sentances"
Это моя функция для преобразования его в векторы Tf-idf
def transform(dataset, vocab, show_tf=False, show_idf=False, show_count=False):
def compute_tf(dataset, vocab, show_tf=show_tf):
'''Computes Term Frequency'''
count = np.array([doc.count(word) \
for doc in dataset \
for word in vocab])\
.reshape(len(dataset),len(vocab))
if show_count:
print('\nCount Vectors\n')
print(75*'=')
print(count)
print(75*'=')
tf = np.array([count[i][j]/count.sum(axis=1)[i] \
for i in range(len(dataset)) \
for j in range(len(vocab))])\
.reshape(len(dataset),len(vocab))
tf[np.isnan(tf)] = 0
if show_tf:
print('\nTF Matrix\n')
print(75*'=')
print(tf)
print(75*'=')
return to
def compute_idf(dataset, vocab, show_idf=show_idf):
'''Computes Inverse Document Frequency '''
presence = np.array([1 if word in doc else 0 \
for doc in dataset \
for word in vocab])\
.reshape(len(dataset),len(vocab))
idf = np.array([1 + np.log((len(dataset) + 1)/ (presence.sum(axis=0)[j] + 1))\
for j in range(len(vocab)) ])\
.reshape(1,len(vocab))
if show_idf:
print('\nIDF Matrix\n')
print(75*'=')
print(idf)
print(75*'=')
return idf
if isinstance(dataset, list):
dataset = [doc.lower() for doc in dataset]
tf = compute_tf(dataset, vocab)
idf = compute_idf(dataset, vocab)
tf_idf = np.array([(tf[i][j]*idf[0][j]) \
for i in range(len(dataset)) \
for j in range(len(vocab))])\
.reshape(len(dataset), len(vocab))
tf_idf = normalize(tf_idf, norm='l2')
rows = [i for i in range(len(dataset)) \
for j in range(len(vocab)) if tf_idf[i][j] != 0]
columns = [j for i in range(len(dataset))\
for j in range(len(vocab)) if tf_idf[i][j] != 0]
values = [tf_idf[i][j] for i in range(len(dataset)) \
for j in range(len(vocab)) if tf_idf[i][j] != 0]
print('\nNormalized TF-IDF Matrix\n')
return (csr_matrix((values, (rows, columns)),\
shape=(len(dataset), len(vocab))))
else:
return 'You need to pass a list of sentences'
Извините, если этот код слишком длинный и заполнены операторами печати, я новичок в этом, и они мне нужны, чтобы понять, где я ошибаюсь.
Это результат, который я получаю для этих данных
corpus = [
'This is the first document',
'This document is the second document',
'And this is the third one',
'Is this the first document',]
vocab = fit(corpus)
print(transform(corpus, vocab, show_count=True, show_tf=True, show_idf=True))
Мой вывод против Вывод Sklearn