TF (Term Frequency) -IDF (Inverse Document Frequency) с нуля на Python.

Создание модели TF-IDF с нуля

В этой статье я объясню, как реализовать технику tf-idf в python с нуля, эта техника используется для поиска смысла предложений, состоящих из слов, и устраняет неспособность техники мешка слов, которая хороша для классификации текста или для помощи машинное чтение слов в числах.

Оглавление:

  • Терминология.
  • Частота сроков (TF).
  • Документ Частота.
  • Частота обратного документа.
  • Реализация на Python.

1 - Терминология:

  • t - термин (слово)
  • d - документ (набор слов)
  • N - количество корпусов
  • корпус - полный набор документов

2-периодичность (TF):

Предположим, у нас есть набор текстовых документов на английском языке, и мы хотим оценить, какой документ наиболее релевантен запросу «Наука о данных - это круто!» Самый простой способ начать - удалить документы, которые не содержат всех трех слов «Данные», «есть», «Наука» и «Круто», но при этом остается много документов. Чтобы различать их, мы можем подсчитать, сколько раз каждый термин встречается в каждом документе; количество раз, когда термин встречается в документе, называется его периодичностью термина.

Вес термина, встречающегося в документе, просто пропорционален частоте использования термина.

Формула:

tf (t, d) = количество t в d / количество слов в d

3 -Частота документов:

Этот измеряет важность документа во всем корпусе, это очень похоже на TF. Единственное отличие состоит в том, что TF - это частотомер для термина t в документе d, где DF - это количество появлений термина t в наборе документов N. Другими словами, DF - это количество документы, в которых присутствует слово. Мы рассматриваем одно вхождение, если термин присутствует в документе хотя бы один раз, нам не нужно знать, сколько раз этот термин присутствует.

df (t) = появление t в документах

4.Частота обратного документа (IDF):

При вычислении TF все термины считаются одинаково важными. Однако известно, что определенные термины, такие как «есть», «из» и «то», могут встречаться много раз, но не имеют большого значения. Таким образом, нам нужно уменьшить частые термины и увеличить количество редких, вычисляя IDF, включается коэффициент обратной частоты документов, который уменьшает вес терминов, которые очень часто встречаются в наборе документов, и увеличивает масса терминов, которые встречаются редко.

IDF - это величина, обратная частоте документа, которая измеряет информативность термина t. Когда мы вычисляем IDF, он будет очень низким для наиболее часто встречающихся слов, таких как стоп-слова (потому что стоп-слова, такие как «есть», присутствуют почти во всех документах, и N / df даст очень низкое значение этому слову. ). Это, наконец, дает то, что мы хотим, относительный вес.

idf (t) = N / df

Теперь есть несколько других проблем с IDF, в случае большого корпуса, скажем 100000000, значение IDF взрывается, чтобы избежать эффекта, который мы берем в журнал idf.

Во время запроса, когда встречается слово, которого нет в словаре, df будет 0. Поскольку мы не можем делить на 0, мы сглаживаем значение, добавляя 1 к знаменателю.

вот окончательная формула:

Формула:

idf (t) = log (N / (df + 1))

Теперь tf-idf является правильной мерой для оценки того, насколько важно слово для документа в коллекции или корпусе. Существует много различных вариантов TF-IDF, но пока давайте сосредоточимся на этой базовой версии.

Формула:

tf-idf (t, d) = tf (t, d) * log (N / (df + 1))

5 -Внедрение TF-IDF в Python с нуля:

Чтобы создать TF-IDF с нуля на Python, представьте себе эти два предложения из другого документа:

first_sentence: «Наука о данных - самая сексуальная работа 21 века».

second_sentence: «Машинное обучение - ключ к науке о данных».

На первом этапе мы должны создать функцию TF для расчета общей частоты встречаемости слов для всех документов. Вот коды ниже:

Сначала, как обычно, необходимо импортировать необходимые библиотеки:

import pandas as pd
import sklearn as sk
import math 

Итак, давайте загрузим наши предложения и объединим их в единый набор:

first_sentence = "Data Science is the sexiest job of the 21st century"
second_sentence = "machine learning is the key for data science"
#split so each word have their own string
first_sentence = first_sentence.split(" ")
second_sentence = second_sentence.split(" ")#join them to remove common duplicate words
total= set(first_sentence).union(set(second_sentence))
print(total)

Выход :

{'data', 'Science', 'job', 'sexiest', 'the', 'for', 'science', 'machine', 'of', 'is', 'learning', '21st', 'key', 'Data', 'century'}

Теперь давайте добавим способ подсчета слов с помощью словарной пары ключ-значение для обоих предложений:

wordDictA = dict.fromkeys(total, 0) 
wordDictB = dict.fromkeys(total, 0)
for word in first_sentence:
    wordDictA[word]+=1
    
for word in second_sentence:
    wordDictB[word]+=1

Теперь мы помещаем их в фрейм данных и затем просматриваем результат:

pd.DataFrame([wordDictA, wordDictB])

Нет, давайте напишем функцию TF:

def computeTF(wordDict, doc):
    tfDict = {}
    corpusCount = len(doc)
    for word, count in wordDict.items():
        tfDict[word] = count/float(corpusCount)
    return(tfDict)
#running our sentences through the tf function:
tfFirst = computeTF(wordDictA, first_sentence)
tfSecond = computeTF(wordDictB, second_sentence)
#Converting to dataframe for visualization
tf = pd.DataFrame([tfFirst, tfSecond])

и это ожидаемый результат:

Это все для формулы TF, просто я хочу поговорить о стоп-словах, которые мы должны удалить, потому что они являются наиболее часто встречающимися словами, которые не придают никакого дополнительного значения вектору документа. Фактически, их удаление увеличит эффективность вычислений и использования пространства .

В библиотеке nltk есть метод загрузки стоп-слов, поэтому вместо явного упоминания всех стоп-слов мы можем просто использовать библиотеку nltk и перебирать все слова и удалять стоп-слова. Есть много эффективных способов сделать это, но я просто приведу простой метод.

это образец стоп-слов на английском языке:

и это простой код для загрузки стоп-слов и их удаления.

import nltk
nltk.download('stopwords')
from nltk.corpus import stopwords
stop_words = set(stopwords.words('english'))
filtered_sentence = [w for w in wordDictA if not w in stop_words]
print(filtered_sentence)

выход :

['data', 'Science', 'job', 'sexiest', 'science', 'machine', 'learning', '21st', 'key', 'Data', 'century']

И теперь, когда мы закончили раздел TF, мы переходим к части IDF:

def computeIDF(docList):
    idfDict = {}
    N = len(docList)
    
    idfDict = dict.fromkeys(docList[0].keys(), 0)
    for word, val in idfDict.items():
        idfDict[word] = math.log10(N / (float(val) + 1))
        
    return(idfDict)
#inputing our sentences in the log file
idfs = computeIDF([wordDictA, wordDictB])

и теперь мы реализуем формулу idf, давайте закончим с вычислением TFIDF

def computeTFIDF(tfBow, idfs):
    tfidf = {}
    for word, val in tfBow.items():
        tfidf[word] = val*idfs[word]
    return(tfidf)
#running our two sentences through the IDF:
idfFirst = computeTFIDF(tfFirst, idfs)
idfSecond = computeTFIDF(tfSecond, idfs)
#putting it in a dataframe
idf= pd.DataFrame([idfFirst, idfSecond])
print(idf)

выход :

Это была большая работа. Но полезно знать, если в будущем вас попросят кодировать TF-IDF с нуля. Однако это можно сделать намного проще благодаря библиотеке sklearn. Давайте посмотрим на пример из них ниже:

#first step is to import the library
from sklearn.feature_extraction.text import TfidfVectorizer
#for the sentence, make sure all words are lowercase or you will run #into error. for simplicity, I just made the same sentence all #lowercase
firstV= "Data Science is the sexiest job of the 21st century"
secondV= "machine learning is the key for data science"
#calling the TfidfVectorizer
vectorize= TfidfVectorizer()
#fitting the model and passing our sentences right away:
response= vectorize.fit_transform([firstV, secondV])

и это ожидаемый результат:

Резюме :

В этом посте мы собираемся объяснить, как использовать Python и технику обработки естественного языка (NLP), известную как Term Frequency - Inverse Document Frequency (tf-idf) для обобщения документов.

Мы будем использовать sklearn вместе с nltk для выполнения этой задачи.

Помните, что вы можете найти полностью рабочий код в моем репозитории на github здесь.

Спасибо за чтение, и я буду рад обсудить любые вопросы или исправления, которые могут у вас возникнуть :) Найдите меня в LinkedIn, если вы хотите обсудить машинное обучение или что-то еще.