- PVSM.RU - https://www.pvsm.ru -
Когда начинаешь погружаться в сферу NLP, сразу задумываешься, как модели представляют себе наш текст/наши слова? Ведь не логично бы звучало, если модель обрабатывала наши слова, как обычную последовательность букв. Это было бы не удобно и не понятно(как проводить операции со словами?).
Есть разные методы преобразования слов. Один из самых известных для не самых сложных моделей: TF-IDF.
TF-IDF(Term Frequency-Inverse Document Frequency) — это метод, который преобразует слова в числовые векторы, что делает их более понятными для моделей машинного обучения.
Причем числовые векторы здесь содержат TF-IDF значения, а не просто любые числа.
Значения TF-IDF пытаются показать насколько важно слово для нас в этом документе(наборе текстовых данных).
Когда мы имеем текстовые данные, нам нужно разбить их на куски. Это можно сделать по предложениям, смысловым абзацам, целым текстам или как-то по-другому.
Вот формулы подсчета TF-IDF:
t - наше слово
d - наш документ
В формуле мы делим число вхождений нашего слова в данный документ на общее число слов в документе.
TF(Term Frequency) - обозначает частоту нашего слова в документе.
t - наше слово
D - корпус документов(список всех текстовых данных)
В формуле мы берем логарифм от деления общего числа всех документов(длина D) на число документов из корпуса D, которые содержат наше слово.
Логарифм используется для сглаживания значений.
IDF(Inverse Document Frequency) - обозначает обратную частоту, с которой наше слово встречается в документах корпуса.
Умножая TF и IDF, получаем формулу TF-IDF:
Большой вес в TF-IDF получат слова с высокой частотой в пределах конкретного документа и с низкой частотой употреблений в других документах.
Для закрепления и лучшего понимания напишем TF-IDF сами.
План:
договоримся в каком формате будут приходить текстовые данные
посчитаем TF-IDF
вернем нужную информацию
Данные будем получать в формате списка документов(в нашем случае список предложений).
Возвращать будет матрицу значений TF-IDF для каждого слова/документ.
Сначала импортируем нужные библиотеки.
import numpy as np
import pandas as pd
Получим данные, приведем их в нужный формат - каждый новый документ(у нас предложение) будет с новой строки, поэтому разделим их по "n", получим список.
(Текст взяли из случайной статьи на Википедиа [1].)
with open('data.txt', 'r') as file:
content = file.read()
print(content)
data = content.split("\n")
Сейчас самое сложное - напишем функцию tf-idf.
Разобьём ее на четыре части:
Создаем словарь
TF
IDF
TF-IDF
#1
vocab = [] # cоздаем список всех слов.
for text in texts: # проходимся по каждому документу(преложению)
words = text.split() # разбиваем его на слова
for word in words: # проходимся по каждому слову
if not word in vocab: # если такого слова еще нет в нашем списке
vocab.append(word) # добавлем новое слово
Так мы заполняем список уникальными словами.
#2
# наш словарь TF в формате: "слово": [tf_в_документе1, tf_в_документе2, tf_в_документеN]
tf_dict = {}
for word in vocab: # проходимся по каждому слову из списка всех слов
tf_dict_this_word = [] # список всех tf(для каждого документа ) для данного слова
for text in texts: # проходимся по всем документам
if word in text: # если слово в документе
count_word = text.split().count(word) # считаем сколько его в этом документе
# считаем tf для данного документа и добавляем в список всех tf для этого слова
# tf = кол-во слова в документе / длина документа
tf_dict_this_word.append(count_word/len(text.split()))
else:
tf_dict_this_word.append(0) # если слова в этом документе нет - добавляем 0
tf_dict[word] = tf_dict_this_word # добавлем новую запись в наш словарь в нужно формате
У нас уже есть таблица TF для всех слов ко всем документам.
#3
idf_dict = {} # словарь IDF в формате: "слово" : его_idf
for word in vocab: # проходимся по всем словам
# считаем во скольки документах есть данное слово
count_word = sum(1 for text in texts if word in text.split())
# считаем idf и записывем в словарь
# idf = log( кол-во всех документов / кол-во документов содержащих наше слово )
idf_dict[word] = np.log(len(texts) / count_word)
IDF посчитали, осталось перемножить и вернуть.
#4
# словарь посчитанных tf-idf( "слово" : [tf-idf_в_док1, tf-idf_в_док2, tf-idf_в_докN] )
tf_idf = {}
for word in vocab: # проходимся по каждому слову
# по элементно умножаем idf слова на список tf для этого слова
# tf-idf = tf * idf
tf_idf[word] = np.array(tf_dict[word])*idf_dict[word]
Собираем в одну функцию и возвращаем:
def tf_idf(texts: list):
#vocab
vocab = []
for text in texts:
words = text.split()
for word in words:
if not word in vocab:
vocab.append(word)
#tf
tf_dict = {}
for word in vocab:
tf_dict_this_word = []
for text in texts:
if word in text:
count_word = text.split().count(word)
tf_dict_this_word.append(count_word/len(text.split()))
else:
tf_dict_this_word.append(0)
tf_dict[word] = tf_dict_this_word
#idf
idf_dict = {}
for word in vocab:
count_word = sum(1 for text in texts if word in text.split())
idf_dict[word] = np.log(len(texts) / count_word)
#tf-idf
tf_idf = {}
for word in vocab:
tf_idf[word] = np.array(tf_dict[word])*idf_dict[word]
return tf_idf
(Взяли текст из этой статьи [2])
Наши текстовые данные(data.txt):
Произведения Альтова исполняли Геннадий Хазанов («Геракл», «Вобла», «Хор в посольстве», «Волки и овцы», «Плавки»), Клара Новикова («Кармен»), Ефим Шифрин («Кающаяся Мария Магдалина», «Покушение», «Блуждающая грудь», «Золушка», «Оазис», «Сексонфу», «Бычара», «Личный пример»), Владимир Винокур («Кувырок судьбы»).
Кроме того, свои произведения исполняет и автор.
Семён Альтов выделяется среди прочих выступающих писателей-юмористов своеобразной исполнительской манерой — Альтов читает свои монологи с непроницаемым и даже мрачным выражением лица, однообразным низким голосом со своеобразным акцентом, даже не улыбаясь.
Манера произношения Альтова пародируется многими эстрадными артистами (Братья Пономаренко, Игорь Христенко и т. д.).
my_tf_idf = tf_idf(data) # используем нашу функцию, передавая наши данные
# для визуала создаем DataFrame и транспонируем его(для красоты, опять же)
tfidf_table = pd.DataFrame(my_tf_idf).T
print(tfidf_table) # смотрим результат
Видим такую таблицу значений TF-IDF:

Ура, у нас получилось - мы написали свой TF-IDF.
Спасибо♥
Код на Google Colab [3]
Википедиа [1]
Статья, которую мы использовали [2]
TF_IDF [4]
Github [5]
Kaggle [6]
Я на Github [7]
Я на Kaggle [8]
Мой Датасет на Kaggle [9]
Автор: gunner951
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/393790
Ссылки в тексте:
[1] Википедиа: https://www.wikipedia.org/
[2] этой статьи: https://ru.wikipedia.org/wiki/%D0%90%D0%BB%D1%8C%D1%82%D0%BE%D0%B2,_%D0%A1%D0%B5%D0%BC%D1%91%D0%BD_%D0%A2%D0%B5%D0%BE%D0%B4%D0%BE%D1%80%D0%BE%D0%B2%D0%B8%D1%87
[3] Код на Google Colab: https://colab.research.google.com/drive/118SD5N6O4i-vOSc7F0GrMkyZDwqrrxCF?usp=sharing
[4] TF_IDF: https://en.wikipedia.org/wiki/Tf%E2%80%93idf
[5] Github: https://github.com/
[6] Kaggle: https://www.kaggle.com/
[7] Я на Github: https://github.com/ivansherbakov9
[8] Я на Kaggle: https://www.kaggle.com/ivansher
[9] Мой Датасет на Kaggle: https://www.kaggle.com/datasets/ivansher/nasa-nearest-earth-objects-1910-2024
[10] Источник: https://habr.com/ru/articles/836706/?utm_campaign=836706&utm_source=habrahabr&utm_medium=rss
Нажмите здесь для печати.