интерпретировать результаты TF-IDF от sklearn TfidfVectorizer - PullRequest
0 голосов
/ 22 марта 2019

Я пытаюсь понять, как интерпретировать и согласовывать оценки TF-IDF из sklearn TfidfVectorizer.Для иллюстрации у меня есть очень простой пример:

from sklearn.feature_extraction.text import 
TfidfVectorizer
data = ['dog is sitting on bed', 'cat is 
sitting on sofa', 'where is that dog']

vector = TfidfVectorizer()
tfidf = vector.fit_transform(data)
df = pd.DataFrame(tfidf.toarray(), columns = 
vector.get_feature_names())
df

Результат: print (df)

Если я вычислю TF-IDF, скажем, «собака»«вручную в первом предложении я бы вычислил TF 1/5 = 0,2, потому что« собака »- это одно из 5 слов.Тогда я бы вычислил IDF слова «собака»: оно появляется в 2 из 3 предложений log (3/2) = 0,176.Затем я умножаю 0,2 * 0,176 = 0,0352.Мой вопрос: как рассчитывается это число 0,433067 для «собаки» в первом ряду?

1 Ответ

0 голосов
/ 22 марта 2019

Ваше понимание tf-idf отличается от реализации sklearn.

Согласно документации , три вещи приводят к тому, что вы получаете другой результат:

  1. Частота термина рассчитывается как необработанный счет термина в данном документе

  2. Сглаживание применяется к значению IDF

  3. Нормализация выполнена

Чтобы вернуться к вашему примеру, давайте сначала изменим TfidfVectorizer следующим образом:

vector = TfidfVectorizer(norm=None)

После выполнения fit_transform мы получим следующий вывод:

        bed       cat       dog   is        on   sitting      sofa      that     where
0  1.693147  0.000000  1.287682  1.0  1.287682  1.287682  0.000000  0.000000  0.000000
1  0.000000  1.693147  0.000000  1.0  1.287682  1.287682  1.693147  0.000000  0.000000
2  0.000000  0.000000  1.287682  1.0  0.000000  0.000000  0.000000  1.693147  1.693147

Для первого предложения и слова dog частота слова равна 1, поскольку слово встречается один раз. IDF не равен log(3/2), а скорее log(4/3); 1 добавляется к числителю и знаменателю для предотвращения деления на 0 (это поведение можно отключить, передав smooth_idf=False).

1 + log(4/3) приблизительно равно 1.287682, как и ожидалось.

Если мы затем выполним нормализацию L2:

df.iloc[0] / ((df.iloc[0] ** 2).sum() ** 0.5)

Мы видим, что получаем тот же вывод, что и оригинал:

bed        0.569431
cat        0.000000
dog        0.433067
is         0.336315
on         0.433067
sitting    0.433067
sofa       0.000000
that       0.000000
where      0.000000
Name: 0, dtype: float64
...