Ваше понимание tf-idf
отличается от реализации sklearn
.
Согласно документации , три вещи приводят к тому, что вы получаете другой результат:
Частота термина рассчитывается как необработанный счет термина в данном документе
Сглаживание применяется к значению IDF
Нормализация выполнена
Чтобы вернуться к вашему примеру, давайте сначала изменим 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