Это правильный tfidf?

Я пытаюсь получить tfidf из документа. Но я не думаю, что это дает мне правильные значения, или я могу что-то делать неправильно. Пожалуйста, предложите. Код и вывод ниже:

from sklearn.feature_extraction.text import TfidfVectorizer
books = ["Hello there this is first book to be read by wordcount script.", "This is second book to be read by wordcount script. It has some additionl information.", "just third book."]
vectorizer = TfidfVectorizer()
response = vectorizer.fit_transform(books)
feature_names = vectorizer.get_feature_names()
for col in response.nonzero()[1]:
   print feature_names[col], '-', response[0, col]

Обновление 1: (как было предложено juanpa.arrivillaga)

vectorizer = TfidfVectorizer(smooth_idf=False)

Выход:

script - 0.269290317245
wordcount - 0.269290317245
by - 0.269290317245
read - 0.269290317245
be - 0.269290317245
to - 0.269290317245
book - 0.209127954024
first - 0.354084405732
is - 0.269290317245
this - 0.269290317245
there - 0.354084405732
hello - 0.354084405732
information - 0.0
...

Вывод после обновления 1:

script - 0.256536760895
wordcount - 0.256536760895
by - 0.256536760895
read - 0.256536760895
be - 0.256536760895
to - 0.256536760895
book - 0.182528018244
first - 0.383055542114
is - 0.256536760895
this - 0.256536760895
there - 0.383055542114
hello - 0.383055542114
information - 0.0
...

Насколько я понимаю, tfidf = tf * idf. И как я вычисляю это вручную в качестве примера:

документ 1: «Здравствуйте, это первая книга, которую можно прочитать с помощью сценария подсчета слов». документ 2: «Это вторая книга, которую нужно читать по сценарию подсчета слов. В ней есть дополнительная информация». документ 3: "всего лишь третья книга".

Tfidf для приветствия:

tf= 1/12(total terms in document 1)= 0.08333333333
idf= log(3(total documents)/1(no. of document with term in it))= 0.47712125472
0.08333333333*0.47712125472= 0.03976008865 

который отличается от приведенного ниже (привет - 0,354084405732).

Ручной расчет после обновления 1:

tf = 1
idf= log(nd/df) +1 = log (3/1) +1= 0.47712125472 + 1= 1.47712 
tfidf = tf*idf = 1* 1.47712= 1.47712

(не то же самое, что вывод кода "hello - 0.383055542114" после сглаживания idf)

Любая помощь, чтобы понять, что происходит, высоко ценится.


person Manvi    schedule 14.08.2017    source источник
comment
Вы можете увидеть, что именно используется here in the docs. Обратите внимание, что вы не выполняете сглаживание IDF, которое TfidfVectorizer делает по умолчанию.   -  person juanpa.arrivillaga    schedule 14.08.2017
comment
Кроме того, документы, похоже, подразумевают, что частота терминов является необработанной частотой терминов, не нормализованной по длине документа.   -  person juanpa.arrivillaga    schedule 14.08.2017
comment
@juanpa.arrivillaga, не могли бы вы превратить свой комментарий в ответ - это может помочь людям искать/спрашивать одно и то же...   -  person MaxU    schedule 14.08.2017
comment
@MaxU У меня сейчас нет времени, может, сегодня позже...   -  person juanpa.arrivillaga    schedule 14.08.2017
comment
Вы можете посмотреть мои ответы здесь и здесь, чтобы узнать, как работает sklearn tfidfVectorizer   -  person Vivek Kumar    schedule 15.08.2017
comment
Спасибо @juanpa.arrivillaga за предложения. Я обновил код, но все еще не могу получить те же значения из кода и ручных вычислений.   -  person Manvi    schedule 15.08.2017
comment
@Manvi Манви, вы неправильно выполняете ручной расчет и, конечно, не понимаете, как параметры по умолчанию влияют на сглаживание и нормализацию ...   -  person juanpa.arrivillaga    schedule 15.08.2017
comment
@MaxU представил базовый пример, который не выполняет сглаживание или нормализацию, просто как проверку работоспособности.   -  person juanpa.arrivillaga    schedule 15.08.2017


Ответы (1)


Вот вывод без сглаживания или нормализации:

In [2]: from sklearn.feature_extraction.text import TfidfVectorizer
   ...: books = ["Hello there this is first book to be read by wordcount script.", "This is second book to be read by wordcount sc
   ...: ript. It has some additionl information.", "just third book."]
   ...: vectorizer = TfidfVectorizer(smooth_idf=False, norm=None)
   ...: response = vectorizer.fit_transform(books)
   ...: feature_names = vectorizer.get_feature_names()
   ...: for col in response.nonzero()[1]:
   ...:    print(feature_names[col], '-', response[0, col])
   ...:
hello - 2.09861228867
there - 2.09861228867
this - 1.40546510811
is - 1.40546510811
first - 2.09861228867
book - 1.0
to - 1.40546510811
be - 1.40546510811
read - 1.40546510811
by - 1.40546510811
wordcount - 1.40546510811
script - 1.40546510811
this - 1.40546510811
is - 1.40546510811
book - 1.0
to - 1.40546510811
be - 1.40546510811
read - 1.40546510811
by - 1.40546510811
wordcount - 1.40546510811
script - 1.40546510811
second - 0.0
it - 0.0
has - 0.0
some - 0.0
additionl - 0.0
information - 0.0
book - 1.0
just - 0.0
third - 0.0

Итак, рассмотрим результат для "hello":

hello - 2.09861228867

Теперь вручную:

In [3]: import math

In [4]: tf = 1

In [5]: idf = math.log(3/1) + 1

In [6]: tf*idf
Out[6]: 2.09861228866811

Проблема с вашим ручным вычислением заключается в том, что вы используете log по основанию 10, но вам нужно использовать натуральный логарифм.

Если вы все еще чувствуете жгучее желание пройти этапы сглаживания и нормализации, это должно настроить вас на правильное выполнение.

person juanpa.arrivillaga    schedule 15.08.2017
comment
Большое спасибо за вашу помощь. Теперь я понял ... не могли бы вы также предложить, как удалить предупреждение, которое я получаю с тем же кодом, что и VisibleDeprecationWarning: rank устарело; вместо этого используйте атрибут или функцию ndim. - person Manvi; 15.08.2017
comment
@Manvi, я понятия не имею, откуда это предупреждение. Кажется, вы должны задать другой вопрос, но также он кажется довольно понятным - не используйте аргумент rank для любой функции, которая выдает вам это предупреждение, вместо этого используйте ndim или функцию... - person juanpa.arrivillaga; 15.08.2017
comment
@Manvi похоже, что это исходит из базовой реализации sklearn, в которой используется устаревшая функция scipy. Возможно, это было исправлено - я не получаю предупреждения. Попробуйте обновить sklearn - person juanpa.arrivillaga; 15.08.2017
comment
@Manvi Я был на версии 18, версия 19 была выпущена пару дней назад! - person juanpa.arrivillaga; 15.08.2017
comment
Еще одна вещь: код печатает tfidf=0.0 для нескольких... правильно ли это? Также... почему он печатает 0 при использовании response.nonzero()[1]. - person Manvi; 15.08.2017
comment
@Manvi, это действительно должен быть другой вопрос, но в основном вы просто перебираете индексы столбцов значений в вашей двумерной разреженной матрице, которые имеют значение non_zero. Но каждое значение здесь где-то не равно нулю. Просто распечатайте свою матрицу, это должно быть очевидно - person juanpa.arrivillaga; 15.08.2017