В своем предыдущем блоге я объяснил CountVectorizer.

Ссылка на блог - › CountVectorizer

CountVectorizer подсчитывает частоту уникальных слов в корпусе. Это может быть полезно, если вы просто ищете слово и хотите узнать, как часто это слово используется в документе.

Однако, если вы хотите знать, какова основная цель документа, использование только частоты слов в корпусе может привести к ошибочной классификации.

В документе очень часто используются несколько общеупотребительных слов. Если вы введете большое количество этих часто используемых слов непосредственно в классификатор, эти слова будут затенять действительно интересные термины документа.

Обратная частота документов (idf), уменьшает вес часто используемых слов и увеличивает вес слов, которые не используются часто в корпусе (коллекция документов).

Мы собираемся использовать модуль sklearn.feature_extraction для вычисления idf корпуса.

Модуль sklearn.feature_extraction можно использовать для извлечения функций в формате, поддерживаемом алгоритмами машинного обучения, из наборов данных, состоящих из таких форматов, как текст и изображение. Ссылка: https://scikit-learn.org/stable/modules/feature_extraction.html

В этой статье я объясню, как sklearn вычисляет TF, IDF и TF-IDF.

Частота терминов (TF) термина (то есть слова) в документе представляет собой количество раз, когда этот термин присутствует в документе.

idf (термин, doc) - ›ln (Количество документов / df

Мы собираемся использовать нижеследующий корпус, содержащий четыре текстовых документа.

Document1 → В семье Тома 5 детей, 2 собаки и 1 кот.

Document2 → Собаки дружелюбные, кот красивый.

Document3 → Собаке 11 лет.

Document4 → Том живет в Соединенных Штатах Америки.

Мы собираемся написать программу на Python и вычислить значение TF-IDF уникального слова.

Назначим корпусу векторную переменную text.

text=["Tom's family includes 5 kids 2 dogs and 1 cat", 
      "The dogs are friendly.The cat is beautiful",
      "The dog is 11 years old",
      "Tom lives in the United States of America"]

Теперь импортируйте TfidfVectorizer из модуля sklearn.feature_extraction.

from sklearn.feature_extraction.text import TfidfVectorizer

Создайте экземпляр TfidfVectorizer. Использование опции stop_words = ’english’ перестанет рассматривать общеупотребительные английские слова, такие как «a», «an», «is», «the» из документа.

fit_transform экземпляр с указанным выше текстовым вектором.

vectorizer = TfidfVectorizer(stop_words='english')
X = vectorizer.fit_transform(text)

Метод get_feature_names () показывает уникальные слова (без стоп-слов) в документе.

print(vectorizer.get_feature_names())

Результат:

['11', 'america', 'beautiful', 'cat', 'dog', 'dogs', 'family', 'friendly', 'includes', 'kids', 'lives', 'old', 'states', 'tom', 'united', 'years']

Есть 16 уникальных слов.

vectorizer.idf_ покажет idf каждого уникального слова

print(vectorizer.idf_)

Результат:

array([1.91629073, 1.91629073, 1.91629073, 1.51082562, 1.91629073,
       1.51082562, 1.91629073, 1.91629073, 1.91629073, 1.91629073,
       1.91629073, 1.91629073, 1.91629073, 1.51082562, 1.91629073,
       1.91629073])

Всего 16 ЦАХАЛ. По одному на каждое уникальное слово. Но мы не знаем, какое слово принадлежит к какому. Давайте преобразуем его во фрейм данных pandas и напечатаем с заголовком столбца.

import pandas as pd
df=pd.DataFrame(vectorizer.idf_,index=['11', 'america', 'beautiful', 'cat', 'dog', 'dogs', 'family', 'friendly', 'includes', 'kids', 'lives', 'old', 'states', 'tom', 'united', 'years'],columns=['idf'])
df

Результат:

Давайте разберемся, как рассчитывается idf. Давайте посчитаем idf для 11.

«11» находится в третьем документе. Встречается только один раз.

df =1

общее количество документов = 4

Это номер idf.

Но каково значение X?

Напечатаем.

X.todense()

Результат:

matrix([[0.        , 0.        , 0.        , 0.35745504, 0.        ,
         0.35745504, 0.4533864 , 0.        , 0.4533864 , 0.4533864 ,
         0.        , 0.        , 0.        , 0.35745504, 0.        ,
         0.        ],
        [0.        , 0.        , 0.55528266, 0.43779123, 0.        ,
         0.43779123, 0.        , 0.55528266, 0.        , 0.        ,
         0.        , 0.        , 0.        , 0.        , 0.        ,
         0.        ],
        [0.5       , 0.        , 0.        , 0.        , 0.5       ,
         0.        , 0.        , 0.        , 0.        , 0.        ,
         0.        , 0.5       , 0.        , 0.        , 0.        ,
         0.5       ],
        [0.        , 0.46516193, 0.        , 0.        , 0.        ,
         0.        , 0.        , 0.        , 0.        , 0.        ,
         0.46516193, 0.        , 0.46516193, 0.36673901, 0.46516193,
         0.        ]])

Еще раз 16 уникальных значений, но без понятия, какое из них какому слову принадлежит. Как и раньше, давайте преобразуем его во фрейм данных pandas и напечатаем с именами столбцов.

df1=pd.DataFrame(X.todense(),columns=['11', 'america', 'beautiful', 'cat', 'dog', 'dogs', 'family', 'friendly', 'includes', 'kids', 'lives', 'old', 'states', 'tom', 'united', 'years'])
df1

Результат:

Почему он показывает 0,5 из 11?

Это нормализованное значение idf для каждого документа. Давайте разберемся, как это рассчитывается.

Третий документ содержит

The dog is 11 years old 

Из них при расчете idf учитываются только «собаки» «11 лет» и «возраст».

Значения IDF нормализованы с использованием формулы евклидовой нормы.

Вот как sklearn вычисляет значение idf и нормализует его.

Ссылка:

Практика машинного обучения