Путаница при расчете TFIDF

Я нашел в Интернете следующий код для расчета TFIDF:

https://github.com/timtrueman/tf-idf/blob/master/tf-idf.py

Я добавил «1+» в функцию def idf (word, documentList), поэтому я не буду разделен на 0 ошибку:

return math.log(len(documentList) / (1 + float(numDocsContaining(word,documentList))))

Но меня смущают две вещи:

  1. В некоторых случаях я получаю отрицательные значения, это правильно?
  2. Меня смущают строки 62, 63 и 64.

Код:

 documentNumber = 0
  for word in documentList[documentNumber].split(None):
       words[word] = tfidf(word,documentList[documentNumber],documentList)

Должен ли TFIDF рассчитываться только по первому документу?


person badc0re    schedule 20.05.2013    source источник


Ответы (2)


  1. Нет. Tf-idf — это tf, неотрицательное значение, умноженное на idf, неотрицательное значение, поэтому оно никогда не может быть отрицательным. Похоже, этот код реализует ошибочное определение tf-idf это было в Википедии в течение многих лет (это было исправлено тем временем).
person Fred Foo    schedule 20.05.2013
comment
хм, я должен проверить это. - person badc0re; 20.05.2013
comment
Я исправил формулу, но у меня есть одна неясность относительно второй вещи из списка выше. Любые подсказки? - person badc0re; 20.05.2013
comment
@ badc0re: я действительно не понимаю этот код. Обычно вы применяете tf-idf ко всему корпусу. - person Fred Foo; 20.05.2013
comment
Еще один пример того, почему копировать код со случайных сайтов github — не лучшая идея... это может быть неработающая копия из Википедии. :-) - person Has QUIT--Anony-Mousse; 20.05.2013
comment
нет, я просто искал пример реализации, и я нашел это. - person badc0re; 20.05.2013
comment
Я опоздал на 5 лет, надеюсь, вы все еще используете SO. Почему idf не может быть -ve? Журнал n ‹ 1 всегда равен -ve, а idf = log_e (общее количество документов/количество документов с термином t в нем). Следовательно, idf, скорее всего, будет -ve. Что-то я пропустил? P.S. При дальнейшем рассмотрении кажется, что пользователь покинул SO ¯_(ツ)_/¯ - person Rushat; 04.04.2018

Если рассматриваемое слово содержится во всех документах коллекции, изменение 1+ приведет к отрицательному значению. Поскольку 0 ‹ (x / (1 + x)) ‹ 1 выполняется для всех x > 0. Что приводит к отрицательному логарифму.

На мой взгляд, правильный IDF для несуществующего слова бесконечен или не определен, но при добавлении 1+ к знаменателю и знаменателю несуществующее слово будет иметь IDF немного выше, чем любое существующее слово, а слова, которые существуют в каждом документе, будут иметь IDF нуля. Оба случая, вероятно, будут хорошо работать с вашим кодом.

person Omnidux    schedule 13.11.2013
comment
Углубившись в эту проблему, я обнаружил, как это делает lucene. Lucene использует 1+ в знаменателе и перед логарифмом, гарантируя, что IDF всегда положителен, но меньше единицы для слов, содержащихся в каждом документе. lucene.apache.org/core/ 4_5_1/core/org/apache/lucene/поиск/ - person Omnidux; 13.11.2013
comment
На самом деле я решил проблему, избегая добавления 1+ и создавая вектор слов, например [0, 3, 1, 0] (поскольку мне нужны векторы для вычисления VSM), и таким образом я вычислил TF-IDF только для не- нулевые значения. В любом случае спасибо за предложение. :) - person badc0re; 14.11.2013