Пакет слов (BoW) для обработки текста

Здравствуйте, читатели! Настало время еще одного… Давайте начнем!

Существует множество представлений информации в режиме реального времени, таких как числа, изображения, видео, текст и т. д. На этот раз давайте поговорим о тексте.

Текстовое представление очень давно помогает человечеству, и мы хотим, чтобы оно помогло нашим машинам научиться строить модели и принимать решения. А почему бы не?! Поскольку мы не можем заставить машины понимать текст напрямую, мы создаем числа и модели, которые могут понимать эти числа в векторном представлении и принимать решения.

Одним из таких представлений текста являетсямешок слов (BoW).

Прежде чем мы перейдем к этой теме, просто найдите минутку и подумайте сами, что вам дали кучу документов, в которых текст написан на похожем для вас неизвестном языке. Как бы вы попытались выяснить подобные документы? Вы можете попробовать найти похожие слова и похожие символы в документе и попытаться сопоставить их с другими документами. Документ с наибольшим количеством этих уникальных слов/символов является наиболее похожим документом и имеет более похожее содержание на тот, с которого вы начали. (Теперь это пример, пожалуйста, не позволяйте своим мыслям течь в сторону распознавания образов). Мы используем аналогичный подход, когда учим наши машины находить похожие документы.

Интуитивно мы называем этот подход «МЕШКОМ» слов, потому что нас больше интересуют уникальные слова, которые присутствуют в нашем тексте, а НЕ порядок, в котором они присутствуют. Тем не менее, мы должны принять определенные меры, чтобы очистить текст от некоторых наиболее повторяющихся слов, таких как — a, an, the и т. д., и отфильтровать грамматику, например — знаки препинания, о чем я собираюсь рассказать далее в этом обсуждении.

Просто помните следующее: модель касается только того, встречаются ли известные слова в документе, а не где в документе

Представление текста в виде набора слов описывает вхождение слов в документ и включает в себя две вещи:

  1. Словарь известных слов.
  2. Показатель присутствия известных слов.

Интуитивно мы считаем, что документы похожи, если они имеют похожее содержание, и одного содержания достаточно, чтобы мы узнали что-то о значении документа.

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

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

Утверждение 1. «Джон любит смотреть фильмы. Мэри тоже любит кино».

Утверждение 2. «Джон также любит смотреть футбольные матчи».

Созданные векторы можно использовать в алгоритме машинного обучения.

Эти два предложения также могут быть представлены набором слов.

1. ['John', 'likes', 'to', 'watch', 'movies.', 'Mary', 'likes', 'movies', 'too.']
2. ['John', 'also', 'likes', 'to', 'watch', 'football', 'games']

Кроме того, для каждого предложения удалите несколько вхождений слова и используйте количество слов для представления этого.

1. {"John":1,"likes":2,"to":1,"watch":1,"movies":2,"Mary":1,"too":1}
2. {"John":1,"also":1,"likes":1,"to":1,"watch":1,"football":1,   "games":1}

Если предположить, что эти предложения являются частью документа, ниже приведена объединенная частота слов для всего нашего документа. Оба предложения учитываются.

{"John":2,"likes":3,"to":2,"watch":2,"movies":2,"Mary":1,"too":1,  "also":1,"football":1,"games":1}

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

Длина вектора всегда будет равна размеру словаря. В этом случае длина вектора равна 11.

Чтобы представить наши исходные предложения в векторе, каждый вектор инициализируется всеми нулями —[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

За этим следует итерация и сравнение с каждым словом в нашем словаре, а также увеличение значения вектора, если это слово есть в предложении.

John likes to watch movies. Mary likes movies too.[1, 2, 1, 1, 2, 1, 1, 0, 0, 0]
John also likes to watch football games.[1, 1, 1, 1, 0, 0, 0, 1, 1, 1]

Например, в предложении1слово likes появляется на второй позиции и встречается два раза. Таким образом, вторым элементом нашего вектора для предложения1будет2:[1, 2, 1, 1, 2, 1, 1, 0, 0, 0]

Вектор всегда пропорционален размеру нашего словарного запаса.

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

Код алгоритма BoW

Входными данными для нашего кода будут несколько предложений, а выходными будут векторы.

Входной массив таков:

["John waited for the bus", "The bus was late", "Manny and Sabrina took the cab",
"I looked for Manny and Sabrina at the cab rental",
"Manny and Sabrina arrived at the cab rental early but waited until noon for the cab"]

Шаг 1. Токенизация предложения

Мы начнем с удалениястоп-словиз предложений.

Стоп-слова— это слова, которые не имеют достаточного значения для использования без нашего алгоритма, и они используются, когда мы говорим о чем-либо, например, «человек», «яблоко» и т. д. . Мы не хотим, чтобы эти слова занимали место в нашей базе данных или (или) отнимали ценное время обработки. Таким образом, мы можем легко удалить их, сохранив список слов, которые вы считаете стоп-словами, таких как a, an, the и т. д.

Токенизация — это процесс разбиения последовательности строк на части, такие как слова, ключевые слова, фразы, символы и другие элементы в предложениях, называемыетокенами. Эти токены могут быть отдельными словами, фразами или даже целыми предложениями. В процессе токенизации некоторые символы, например знаки препинания, отбрасываются.

def word_extraction(sentence):    
    ignore = ['a', "the", "is"]    
    words = re.sub("[^\w]", " ",  sentence).split()    
    clean_txt = [w.lower() for w in words if w not in ignore]
    return clean_txt

Для более надежной реализации стоп-слов вы можете использовать библиотеку Pythonnltk.

Есть набор предопределенных слов для каждого языка.

Пример:

import nltk from nltk.corpus
import stopwords
set(stopwords.words('english'))

Поскольку наши предложения на английском языке, мы устанавливаем стоп-слова на «english».

Шаг 2. Примените токенизацию ко всем предложениям.

def tokenize(sentences):    
    words = []    
    for sntnce in sentences:        
    w = word_extraction(sntnce)        
    words.extend(w)            
    words = sorted(list(set(words)))    
    return words

Метод повторяет все предложения и добавляет извлеченное слово в массив на каждой итерации.

Выход этого метода будет следующим:

['and', 'arrived', 'at', 'cab', 'but', 'early', 'for', 'i', 'john', 'late', 'looked', 'manny', 'noon', 'sabrina', 'rental', 'the', 'took', 'bus', 'until', 'waited', 'was']

Шаг 3: Создайте словарный запас и сгенерируйте векторы

Используйте методы, определенные в шагах 1 и 2, для создания словаря документа и извлечения слов из предложений.

def generate_bow(allsntncs):        
    vocab = tokenize(allsntncs)    
    print("Word List for Document \n{0} \n".format(vocab));
for sentence in allsntncs:        
    words = word_extraction(sentence)        
    bag_vector = numpy.zeros(len(vocab))        
for wd in words:            
    for i,word in enumerate(vocab):                
        if word == wd:                     
           bag_vector[i] += 1                            
print("{0}\n{1}\n".format(sentence,numpy.array(bag_vector)))

Вот определенный ввод и выполнение нашего кода:

allsntncs = ["John waited for the bus bus", "The bus was late", "Manny and Sabrina took the cab",
"I looked for Manny and Sabrina at the cab rental",
"Manny and Sabrina arrived at the cab rental early but waited until noon for the cab"]
generate_bow(allsntncs)

Выходные векторы для каждого предложения:

Output:
John waited for the bus bus[0. 0. 0. 0. 0. 0. 1. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 2. 0. 1. 0.]
The bus was late[0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 1. 0. 1. 0. 0. 1.]
Manny and Sabrina took the cab[1. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 1. 0. 1. 0. 0. 1. 0. 0. 0. 0.]
I looked for Manny and Sabrina at the cab rental[1. 0. 1. 1. 0. 0. 1. 1. 0. 0. 1. 1. 0. 1. 1. 0. 0. 0. 0. 0. 0.]
Manny and Sabrina arrived at the cab rental early but waited until noon for the cab[1. 1. 1. 2. 1. 1. 1. 0. 0. 0. 0. 1. 1. 1. 1. 0. 0. 0. 1. 1. 0.]

Как видите, каждое предложение сравнивалось с нашим списком слов, созданным на шаге 1. На основе сравнения значение элемента вектора может быть увеличено. Эти векторы можно использовать в алгоритмах машинного обучения для классификации документов и прогнозов.

Мы написали наш код и сгенерировали векторы, но теперь давайте немного разберемся в наборе слов, поняв следующее:

Ограничения BoW

  1. Семантическое значение. Базовый подход BoW не учитывает значение слова в документе(ах). Он полностью игнорирует контекст, в котором используется, поэтому одно и то же слово может использоваться в нескольких местах в зависимости от контекста (или) соседних слов.
  2. Размер вектора. Для большого документа размер вектора может быть огромным, что требует больших вычислений и времени. Будет важно, чтобы вам, возможно, пришлось игнорировать слова, исходя из вашего отношения к вашему варианту использования.

Вместо того, чтобы разбивать наше предложение на одно слово (1-грамм), вы можете разделить его на пару из двух слов (би-грамм или 2-грамм). Иногда биграммное представление кажется намного лучше, чем использование 1-граммового. Их часто можно представить с помощьюобозначения N-грамм.

Управление словарем

По мере увеличения словарного запаса увеличивается и векторное представление документов.

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

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

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

Существуют простые методы очистки текста, которые можно использовать в качестве первого шага, например:

  • Игнорирование регистра
  • Игнорирование знаков препинания
  • Игнорирование частых слов, не содержащих много информации, называемых стоп-словами, таких как "a", "of" и т. д.
  • Исправление слов с ошибками.
  • Сокращение слов до основы (например, «играть» от «играть») с помощьюалгоритмов объединения корней — PorterStemmer(или) Ланкастер Стеммер.
  • Лемматизация, в отличие от стемминга, правильно сокращает флективные слова, гарантируя, что корневое слово принадлежит языку. В лемматизации корневое слово называется лемма. Лемма (во множественном числе леммы или леммы) – это каноническая форма, словарная форма или форма цитирования набора слов.

Более сложный подход — создать словарь из сгруппированных слов. Это изменяет объем словарного запаса и позволяет набору слов улавливать немного больше смысла из документа.

При таком подходе каждое слово или токен называется граммом. Создание словаря из пар двух слов, в свою очередь, называется моделью биграммы. Опять же, моделируются только те биграммы, которые появляются в корпусе, а не все возможные биграммы.

Хорошие новости! Вам не нужно кодироватьBoWвсякий раз, когда вам это нужно, так как он уже является частью многих доступных фреймворков, таких какCountVectorizer в научном наборе узнать.

Наш предыдущий код можно заменить на:

from sklearn.feature_extraction.text import CountVectorizervectorizer = CountVectorizer()
X = vectorizer.fit_transform(allsentences)print(X.toarray())

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

С учетом сказанного, увидимся в моем следующем….мире!