Метод “Мешок слов” (BoW) является техникой в области обработки естественного языка (NLP). Он广泛应用于 преобразовании текстовых данных в машиночитаемый формат, конкретно в числовые значения, не учитывая грамматику и порядок слов. Понимание BoW важно для任何人, работающего с текстовыми данными. Python предоставляет множество инструментов и библиотек для эффективной реализации Мешка слов.
В этом руководстве мы погрузимся в Мешок слов, познакомимся с его концепциями, рассмотрим его применения и пройдемся по детальной реализации на Python. К концу этого руководства вы сможете применить модель Мешка слов к реальным проблемам. Если вы новички в NLP, обратитесь к нашему модулю “Обработка естественного языка на Python”, чтобы узнать больше.
Что такое Мешок слов?
Метод “Мешок слов” является техникой для извлечения признаков из текстовых данных для задач машинного обучения, таких как классификация текста и анализ sentiment. Это важно, потому что алгоритмы машинного обучения не могут обрабатывать текстовые данные. Процесс преобразования текста в числа известен как извлечение признаков или кодирование признаков.
“Мешок слов” основан на возникновении слов в документе. Процесс начинается с поиска словаря в тексте и измерения их возникновения. Он называется мешком, потому что порядок и структура слов не учитываются, только их возникновение.
Модель “Мешок слов” отличается от модели “Непрерывный мешок слов” (CBOW), которая обучает плотные слово-векторы, используя окружающие слова для предсказания целевого слова, captures семантические отношения между словами. CBOW требует обучения на большом корпусе и produces низкоразмерные векторы, которые ценны для сложных приложений NLP, где важен контекст слов.
Аспект |
BOW |
CBOW |
Цель |
Подсчитывает количество встреnений каждого слова |
Предсказывает целевое слово на основе контекста |
Тип вывода |
Высокомерный, разреженный вектор |
Низкомерная, сплошная嵌入ка |
Учитывает контекст |
Нет (игнорирует порядок слов) |
Да (использует окружающие слова) |
Представление |
Разреженный частотный вектор |
Сплошной вектор, captures semantics |
Сложность |
Низкий (не требует обучения) |
Высокий (требует обучения на большом корпусе данных) |
Типичные приложения |
Классификация текста, анализ sentiment |
Word embeddings, НLP задачи, требующие контекста |
Why Use Bag of Words?
Bag of Words полезен во многих задачах НLP, некоторые причины его использования включают:
- Экстракция признаков: Она преобразует неструктурированные текстовые данные в структурированные, которые могут быть использованы в качестве входных данных для различных алгоритмов машинного обучения.
- Простота и эффективность: BoW легко реализовать вычислительно, и он хорошо работает для малых и средних текстовых корпусов.
- Похожесть документов: Его можно использовать для расчета похожести между текстовыми документами с использованием таких методов, как косинусная相似ность.
- Классификация текста: При комбинировании с методами, такими как Naive Bayes, BoW эффективно для задач классификации текста, таких как определение спама, и анализ sentiment.
However, there are also drawbacks, such as not considering semantics, word structure, or word ordering.
Шаги для реализации метода Bag of Words на Python
Для создания модели bag-of-words мы берем все слова в корпусе и создаем столбец с каждым словом. Строки represent предложения. Если определенное слово существует в предложении, оно представлено единицей, а если слова нет, оно представлено нулём. Каждое слово в столбце represents один признак.
В конце концов, мы получаем разреженную матрицу. Разреженная матрица — это матрица с множеством нулей.
Предварительная обработка данных
Для создания модели Bag of Words на Python, нам нужно выполнить несколько шагов预处理. Эти шаги включают токенизацию и удаление стоп-слов.
Токенизация — это процесс разбиения фрагмента текста на более мелкие единицы, обычно слова. Вы можете выполнить токенизацию с использованием NLTK.
Стоп-слова — это.common слова в английском языке, такие как “the,” “that” и “a”, которые не contribute к polaritете предложения.
import nltk from nltk.corpus import stopwords from nltk.tokenize import word_tokenize Скачать стоп-слова и токенизатор, если вы еще это не сделали nltk.download("punkt") nltk.download("stopwords") Пример предложения sentence = "This is an example showing how to remove stop words from a sentence." Разбить предложение на слова words = word_tokenize(sentence) Получить список стоп-слов на английском языке stop_words = set(stopwords.words("english")) Удалить стоп-слова из предложения filtered_sentence = [word for word in words if word.lower() not in stop_words] Соединить слова обратно в предложение filtered_sentence = " ".join(filtered_sentence) print(filtered_sentence)
Результат:
example showing remove stop words sentence.
Создание словаря
Словарь – это коллекция уникальных слов, найденных в корпусе текста. Создание словаря involves собирание всех уникальных слов из корпуса и подсчет их встречаемости. Этот словарь полезен для различных задач НLP, таких как моделирование языка, word embeddings и классификация текста.
Этот код_below создает простое распределение частот слов в корпусе, полезное для базовых задач НLP, таких как создание словаря или понимание содержимого текста:
- The корpus переменная содержит несколько примеров предложений. В реальных приложениях это будет содержать больший, более разнообразный текстовый материал.
- vocab =
defaultdict(int)
упрощает подсчёт частоты слов, автоматически�始化ируя任何 новое слово счётом 0, что позволяет напрямую увеличивать счётчик без проверок. - Каждое предложение токенизируется путем преобразования его в нижний регистр и извлечения слов с использованием регулярных выражений. Шаблон
\b\w+\b
идентифицирует слова, содержащие только буквенно-цифровые символы, игнорируя пунктуацию и другие символы. - Количество каждого слова обновляется в словаре vocab.
- Словарь сортируется по частоте в порядке убывания, что позволяет легко увидеть самые распространенные слова вверху, и отображается для справки.
import re Импортировать модуль регулярных выражений для помощи в обработке текста from collections import ( defaultdict, ) Импортировать defaultdict для удобного подсчета частоты слов Пример корпус текста - небольшой набор предложений для анализа corpus = [ "Tokenization is the process of breaking text into words.", "Vocabulary is the collection of unique words.", "The process of tokenizing is essential in NLP.", ] Инициализировать defaultdict с целочисленными значениями для хранения частоты слов defaultdict(int) инициализирует каждый новый ключ с默认ным целочисленным значением 0 vocab = defaultdict(int) Пройти по каждому предложению в корпусе для токенизации и normalization for sentence in corpus: Перевести предложение в нижний регистр для обеспечения一致性 в подсчете (например, 'Tokenization' и 'tokenization' treated как одно и то же слово) Использовать регулярные выражения для поиска слов, состоящих только из алфавитно-цифровых символов words = re.findall(r"\b\w+\b", sentence.lower()) Для каждого найденного слова increment его счет в словаре vocab for word in words: vocab[word] += 1 Преобразовать defaultdict vocab в обычный словарь для удобного обращения и сортировки Сортировать словарь по частоте слов в порядке убывания и преобразовывать его в новый словарь sorted_vocab = dict(sorted(vocab.items(), key=lambda x: x[1], reverse=True)) Отображать отсортированный словарь с каждым словом и его счетчиком частоты print("Vocabulary with Frequencies:", sorted_vocab)
Output:
Vocabulary with Frequencies: {'is': 3, 'the': 3, 'of': 3, 'process': 2, 'words': 2, 'tokenization': 1, 'breaking': 1, 'text': 1, 'into': 1, 'vocabulary': 1, 'collection': 1, 'unique': 1, 'tokenizing': 1, 'essential': 1, 'in': 1, 'nlp': 1}
Ручное создание словаря может быть трудоемким, особенно для больших корпусов. CountVectorizer из Scikit-learn автоматизирует этот процесс и позволяет для более гибкой обработки текста, как мы увидим позже.
Реализация метода “Баг оф Вордс” с нуля на Python
Давайте начнем с простого implementations метода “Баг оф Вордс” с нуля на Python. Это поможет вам понять базовые элементы и механику его работы “под капотом”.
Ручная реализация
Шаг 1: Предварительная обработка текстовых данных
Начнем с определения простой функции для обработки текста, включая токенизацию, перевод в нижний регистр и удаление пунктуации.
from collections import defaultdict import string # Пример текстовых данных: предложения corpus = [ "Python is amazing and fun.", "Python is not just fun but also powerful.", "Learning Python is fun!", ] # Функция для предварительной обработки текста def preprocess(text): # Преобразование в нижний регистр text = text.lower() # Удаление пунктуации text = text.translate(str.maketrans("", "", string.punctuation)) # Токенизация: разбиение текста на слова tokens = text.split() return tokens # Применение предварительной обработки к образцу корпуса processed_corpus = [preprocess(sentence) for sentence in corpus] print(processed_corpus)
Вывод:
[['python', 'is', 'amazing', 'and', 'fun'], ['python', 'is', 'not', 'just', 'fun', 'but', 'also', 'powerful'], ['learning', 'python', 'is', 'fun']]
Шаг 2: Создание словаря
Теперь нам нужно просканировать все документы и создать полный список уникальных слов, то есть наш словарь.
Инициализировать пустое множество для словаря vocabulary = set() Создать словарь for sentence in processed_corpus: vocabulary.update(sentence) Перевести в отсортированный список vocabulary = sorted(list(vocabulary)) print("Vocabulary:", vocabulary)
Шаг 3: Calculate Word Frequencies and Vectorize
Теперь мы calculated частоту каждого слова в словаре для каждого документа в обработанном корпусе.
def create_bow_vector(sentence, vocab): vector = [0] * len(vocab) Инициализировать вектор нулей for word in sentence: if word in vocab: idx = vocab.index(word) Найти индекс слова в словаре vector[idx] += 1 Увеличить счетчик в этом индексе return vector
На этом этапе вы создадите представление Bag of Words для каждого документа в вашем корпусе.
Создать вектор BoW для каждого предложения в обработанном корпусе bow_vectors = [create_bow_vector(sentence, vocabulary) for sentence in processed_corpus] print("Bag of Words Vectors:") for vector in bow_vectors: print(vector)
Результат:
Bag of Words Vectors: [0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1] [1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1] [0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1]
Использование CountVectorizer из Scikit-learn
Ручное создание модели Bag of Words полезно для обучения, но для производственных приложений вы захотите использовать эффективные, оптимизированные библиотеки, такие как Scikit-learn.
Функция на Python, которую мы используем для токенизации, CountVectorizer, импортируется из sklearn.feature_extraction.text
. Одной из особенностей CountVectorizer
является max_features
, который代表了您希望在词袋模型中拥有的最大单词数。 В данном случае мы используем None, что означает, что будут использованы все особенности.
После создания экземпляра CountVectorizer
используйте метод .fit_transform(
), чтобы создать модель词袋. Затем используйте .toarray()
, чтобы преобразовать модель词袋 в массивы numpy, которые можно использовать в модели машинного обучения.
Once fitted, CountVectorizer has built a dictionary of feature indices. The index value of a word in the vocabulary is linked to its frequency in the whole training corpus.
from sklearn.feature_extraction.text import CountVectorizer # Исходный корпус corpus = [ "Python is amazing and fun.", "Python is not just fun but also powerful.", "Learning Python is fun!", ] # Создание объекта CountVectorizer vectorizer = CountVectorizer() # Подгонка и преобразование корпуса X = vectorizer.fit_transform(corpus) # Вывод созданного словаря print("Vocabulary:", vectorizer.get_feature_names_out()) # Вывод матрицы Bag-of-Words print("BoW Representation:") print(X.toarray())
Output:
markdownVocabulary: ['also' 'amazing' 'and' 'but' 'fun' 'is' 'just' 'learning' 'not' 'powerful' 'python'] BoW Representation: [[0 1 1 0 1 1 0 0 0 0 1] [1 0 0 1 1 1 1 0 1 1 1] [0 0 0 0 1 1 0 1 0 0 1]]
Example: Applying Bag of Words
Let’s now apply the BoW model to a small text corpus consisting of three movie reviews to illustrate the entire process.
We’ll use Scikit-learn’s CountVectorizer to apply the BoW model to this small text corpus.
Here are the steps that we will take:
CountVectorizer
tokenizes the text, removes punctuation, and lowercase the words automatically..fit_transform(corpus)
преобразует корпус в матрицу документ-терм, где hver строка представляет документ, а hver столбец represents слово из словаря.X_dense
– это плотная матрица, которая представляет частоту каждого слова в каждом документе.
from sklearn.feature_extraction.text import CountVectorizer # Пример корпуса рецензий на фильмы corpus = [ "I loved the movie, it was fantastic!", "The movie was okay, but not great.", "I hated the movie, it was terrible.", ] # Инициализировать CountVectorizer vectorizer = CountVectorizer() # Подогнать и преобразовать корпус в матрицу документ-терм X = vectorizer.fit_transform(corpus) # Преобразовать матрицу документ-терм в плотный формат (необязательно для визуализации) X_dense = X.toarray() # Получить словарь (картирование слов в позициях индексов) vocab = vectorizer.get_feature_names_out() # Вывести словарь и матрицу документ-терм print("Vocabulary:", vocab) print("Document-Term Matrix:\n", X_dense)
Результат:
Vocabulary: ['but' 'fantastic' 'great' 'hated' 'it' 'loved' 'movie' 'not' 'okay' 'terrible' 'the' 'was'] Document-Term Matrix: [[0 1 0 0 1 1 1 0 0 0 1 1] # Первый отзыв: "Мне понравился фильм, он был fantastic!" [1 0 1 0 1 0 1 1 1 0 1 1] # Второй отзыв: "Фильм был нормальный, но не великолепный." [0 0 0 1 1 0 1 0 0 1 1 1]] # Третий отзыв: "Я ненавижу фильм, он был ужасен."
Вот как мы можем интерпретировать вышеприведенный результат:
- Каждому уникальному слову в корпусе присваивается индекс, и слова располагаются в алфавитном порядке. Например, “но” находится на индексе 0, “fantastic” на индексе 1, “фильм” на индексе 6 и так далее.
- Каждая строка в матрице документов представляет собой рецензию на фильм, а каждая колонка соответствует слову из словаря. Значения в матрице представляют собой частоту каждого слова в данном документе.
- Первый отзыв: [0 1 0 0 1 1 1 0 0 0 1 1] означает, что:
- Слово “fantastic” встречается один раз (1 на индексе 1),
- Слово “loved” встречается один раз (1 на индексе 5),
- Слово “фильм” встречается один раз (1 на индексе 6),
- Слово “он” встречается один раз (1 на индексе 4),
- И так далее.
Вектор BoW можно интерпретировать следующим образом:
- Каждый документ является вектором чисел, представляющих счетчик слов. Размерности вектора равны размеру словаря. В данном случае словарь насчитывает 12 слов, поэтому каждый отзыв преобразуется в 12-мерный вектор.
- Большинство слов в каждой строке равны нулю, потому что не каждый документ содержит каждое слово из словаря. Поэтому модели BoW часто являются разреженными, то есть содержат множество нулей.
Преимущества и ограничения модели Bag of Words
Теперь рассмотрим некоторые преимущества и ограничения модели Bag of Words.
Преимущества
- Простота реализации и интерпретации: Модель Bag of Words является одной из самых простых техник представления текста, что делает ее идеальной для начинающих. Ее простота позволяет быстро реализовать модель без необходимости сложной предобработки или специализированных моделей.
- Легкость использования для задач классификации текста: Bag of Words хорошо подходит для базовых задач, таких как классификация текста, анализ sentiment и обнаружение спама. Эти задачи часто не требуют сложных языковых моделей, поэтому representation BOW является достаточным и эффективным.
Ограничения
- Размер словаря влияет на спarsity представлений: Чем больше словарь, тем более разреженной и многомерной становится representация. Эта разреженность может усложнить обучение моделей и требует тщательной настройки размера словаря для избежания чрезмерных вычислительных затрат.
- Производит разреженные матрицы, которые вычислительно дороги: Поскольку каждый документ представляется частотой каждого слова в потенциально large словаре, результативные матрицы часто consist из большей части нулей, что может быть неэффективно для хранения и обработки в machine learning pipelines. Разреженные матрицы занимают значительное количество памяти и часто требуют специализированных инструментов и библиотек для эффективного хранения и вычислений, особенно с large dataset.
- теряет смысл и контекст: BOW игнорирует порядок слов и структуру предложения, что приводит к потере грамматических отношений и смысла. Эта limitation делает его менее подходящим для задач, где важны контекст, нюанс и порядок слов, таких как перевод или определение sentiment в сложных предложениях.
Следующие стратегии могут быть использованы для уменьшения размера словаря в Bag of Words:
- Игнорирование регистра.
- Удаление знаков препинания.
- Удаление stopwords, то есть часто встречающихся слов, таких как “the” и “a”.
- Обеспечение правильного написания всех слов.
- Использование методов стемминга для уменьшeния слов до их корневой формы.
Следующие шаги: За пределами Bag of Words
Одним из ограничений модели Bag of Words является то, что она behandelt все слова одинаково. К сожалению, это может привести к проблемам, где некоторые слова получают большее значение просто потому, что они часто встречаются.
TF-IDF (Частота термов в документе – Обратная частота документов) является решением этой проблемы, поскольку она корректирует вес слов на основе того, как часто они встречаются во всех документах.
TF-IDF: Расширение Bag of Words
Частота термов (TF) представляет собой частоту терма в документе. Обратная частота документов (IDF) уменьшает влияние часто встречающихся слов во множестве документов. Оценка TF-IDF рассчитывается умножением двух метрик.
Рассмотрим документ, содержащий 200 слов, где слово love встречается 5 раз. TF для слова love составляет (5 / 200) = 0,025. Предположим, у нас есть один миллион документов, и слово love встречается в тысяче из них, обратная частота документов (IDF) вычисляется как log(1000000 / 1000) = 3. Вес TF-IDF является произведением этих величин: 0,025 * 3 = 0,075.
В Scikit-learn это relatively легко вычислить с помощью класса TfidfVectorizer.
from sklearn.feature_extraction.text import TfidfVectorizer # Пример корpus corpus = [ "Python is amazing and fun.", "Python is not just fun but also powerful.", "Learning Python is fun!", ] # Создание TF-IDF векторайзера tfidf_vectorizer = TfidfVectorizer() # Подгонка и преобразование корpus X_tfidf = tfidf_vectorizer.fit_transform(corpus) # Показать словарь print("Vocabulary:", tfidf_vectorizer.get_feature_names_out()) # Показать TF-IDF матрицу print("TF-IDF Representation:") print(X_tfidf.toarray())
Output:
Vocabulary: ['also' 'amazing' 'and' 'but' 'fun' 'is' 'just' 'learning' 'not' 'powerful' 'python'] TF-IDF Representation: [[0. 0.57292883 0.57292883 0. 0.338381 0.338381 0. 0. 0. 0. 0.338381 ] [0.40667606 0. 0. 0.40667606 0.24018943 0.24018943 0.40667606 0. 0.40667606 0.40667606 0.24018943] [0. 0. 0. 0. 0.41285857 0.41285857 0. 0.69903033 0. 0. 0.41285857]]
Реализованная выше TF-IDF матрица предоставляет вам взвешенную меру вместо сырых частот.
Хотя модель «Мешок слов» имеет свои ограничения, особенно для больших и более сложных наборов данных, она по-прежнему является важным строительным блоком во многих приложениях NLP. Понимание ее поможет вам при исследовании более сложных моделей, таких как word embeddings и Transformers.
Отсюда вы можете experimenting с BoW в своих проектах, включая распознавание спама, анализ sentiment, кластеризацию документов и многое другое.
Если вы хотите улучшить модель сверх Bag of Words, вы можете исследовать методы, такие как Word2Vec и GloVe, или модели глубокого обучения, такие как BERT.
Заключительные мысли
Метод ” bolsa de palabras ” является фундаментальным методом, используемым в обработке естественного языка. Он служит простым, но эффективным способом преобразования неструктурированного текста в числовые характеристики, которые могут использоваться алгоритмами машинного обучения. В этом руководстве мы рассмотрели:
- Что такое модель ” bolsa de palabras ” (BoW)?
- Преимущества модели ” bolsa de palabras ” при создании моделей машинного обучения.
- Как реализовать модель ” bolsa de palabras ” на Python.
- Преимущества и ограничения метода ” bolsa de palabras “.
- Теория и мотивация за моделью ” bolsa de palabras “.
- Введение TF-IDF как улучшения традиционного подхода ” bolsa de palabras “.
Познакомьтесь с нашим модулем ” Обработка естественного языка на Python “, чтобы углубиться в обработку естественного языка.
Source:
https://www.datacamp.com/tutorial/python-bag-of-words-model