Въведение в Bag of Words и как да го кодираме в Python за NLP

Бели и черни плочки за четкане върху черна повърхност от Pixabay

Bag of Words (BOW) е метод за извличане на функции от текстови документи. Тези функции могат да се използват за обучение на алгоритми за машинно обучение. Той създава речник от всички уникални думи, срещащи се във всички документи в учебния комплект.

Казано по-просто, това е съвкупност от думи, които представляват изречение с брой на думите и най-вече пренебрегвайки реда, в който се появяват.

BOW е подход, широко използван при:

  1. Обработка на естествен език
  2. Извличане на информация от документи
  3. Класификации на документи

На високо ниво тя включва следните стъпки.

Генерираните вектори могат да бъдат въведени във вашия алгоритъм за машинно обучение.

Нека започнем с пример за разбиране, като вземем някои изречения и генерираме вектори за тях.

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

1. "Джон обича да гледа филми. Мери харесва и филми."
2. "Джон също обича да гледа футболни мачове."

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

1. ['Джон', 'харесва', 'до', 'гледай', 'филми', 'Мери', 'харесва', 'филми', 'също.']
2. ["Джон", "също", "харесва", "до", "гледай", "футбол", "игри"]

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

1. {"Джон": 1, "харесва": 2, "до": 1, "гледай": 1, "филми": 2, "Мери": 1, "също": 1}
2. {"Джон": 1, "също": 1, "харесва": 1, "до": 1, "гледай": 1, "футбол": 1, "игри": 1}

Ако приемем, че тези изречения са част от документ, по-долу е комбинираната честота на думите за целия ни документ. И двете изречения са взети под внимание.

 {"Джон": 2, "харесва": 3, "до": 2, "гледай": 2, "филми": 2, "Мери": 1, "също": 1, "също": 1, " футбол ": 1," игри ": 1}

Горният речник от всички думи в документ със съответния брой на думите им ще се използва за създаване на векторите за всяко от изреченията.

Дължината на вектора винаги ще бъде равна на размера на лексиката. В този случай дължината на вектора е 11.

За да представим нашите оригинални изречения във вектор, всеки вектор се инициализира с всички нули - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Това е последвано от итерация и сравнение с всяка дума от нашия речник и увеличаване на векторната стойност, ако изречението има тази дума.

Джон обича да гледа филми. Мери също харесва филми.
[1, 2, 1, 1, 2, 1, 1, 0, 0, 0]
Джон също обича да гледа футболни мачове.
[1, 1, 1, 1, 0, 0, 0, 1, 1, 1]

Например в изречение 1 думата харесва се появява на втора позиция и се появява два пъти. Така че вторият елемент от нашия вектор за изречение 1 ще бъде 2: [1, 2, 1, 1, 2, 1, 1, 0, 0, 0]

Векторът винаги е пропорционален на размера на нашия речник.

Голям документ, при който генерираният речник е огромен, може да доведе до вектор с много 0 стойности. Това се нарича оскъден вектор. Редките вектори изискват повече памет и изчислителни ресурси при моделирането. Огромният брой позиции или размери могат да направят процеса на моделиране много труден за традиционните алгоритми.

Кодиране на нашия BOW алгоритъм

Входът към нашия код ще бъде множество изречения, а изходът ще бъдат векторите.

Входният масив е следният:

["Джо чакаше влака", "Влакът закъсня", "Мери и Саманта взеха автобуса",
"Потърсих Мери и Саманта на автогарата",
„Мери и Саманта пристигнаха на автогарата рано, но изчакаха до обяд за автобуса“]

Стъпка 1: Токенизирайте изречение

Ще започнем с премахване на стопсбутки от изреченията.

Stopwords са думи, които не съдържат достатъчно значение, за да бъдат използвани без нашия алгоритъм. Не бихме искали тези думи да заемат място в нашата база данни или да заемат ценно време за обработка. За това можем лесно да ги премахнем, като съхраним списък с думи, които смятате за стоп думи.

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

def word_extraction (изречение):
    ignore = ['a', "the", "is"]
    думи = re.sub ("[^ \ w]", "", изречение) .split ()
    clean_text = [w.lower () за w в думи, ако не е в игнориране]
    върнете почистения_текст

За по-стабилна имплементация на стопсбукове можете да използвате python nltk библиотека. Тя има набор от предварително зададени думи на език. Ето един пример:

внос nltk
от стопбутовете за импортиране nltk.corpus
 определени (stopwords.words ( "английски"))

Стъпка 2: Приложете токенизацията към всички изречения

def tokenize (изречения):
    думи = []
    за изречение в изречения:
        w = word_extraction (изречение)
        words.extend (w)
        
    думи = подредени (списък (набор (думи)))
    връщайте думи

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

Резултатът от този метод ще бъде:

['и', 'пристигнали', 'at', 'bus', 'but', 'рано', 'for', 'i', 'joe', 'late', 'look', 'mary', ' обед "," саманта "," гара "," на "," взе "," влак "," до "," чакаше "," беше "]

Стъпка 3: Създайте речник и генерирайте вектори

Използвайте методите, определени в стъпки 1 и 2, за да създадете лексиката на документа и извлечете думите от изреченията.

дефинирайте_разбиране (всестранности):
    vocab = tokenize (allsentences)
    печат ("Списък с думи за документ \ n {0} \ n" .формат (vocab));
за присъда във всички присъди:
        думи = word_extraction (изречение)
        bag_vector = numpy.zeros (len (vocab))
        за w с думи:
            за i, дума в изброяване (vocab):
                ако дума == w:
                    bag_vector [i] + = 1
                    
        печат ( "{0} \ п {1} \ п" .format (изречение numpy.array (bag_vector)))

Ето определеното въвеждане и изпълнение на нашия код:

allsentences = ["Джо чакаше влака на влака", "Влакът закъсня", "Мери и Саманта взеха автобуса",
"Потърсих Мери и Саманта на автогарата",
„Мери и Саманта пристигнаха на автогарата рано, но изчакаха до обяд за автобуса“]
generate_bow (allsentences)

Изходните вектори за всяко от изреченията са:

изход:
Джо чакаше влака на влака
[0. 0. 0. 0. 0. 0. 1. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 2. 0. 1. 0.]
Влакът закъсня
[0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 1. 0. 1. 0. 0. 1.]
Мери и Саманта се качиха в автобуса
[1. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 1. 0. 1. 0. 0. 1. 0. 0. 0. 0.]
Потърсих Мери и Саманта на автогарата
[1. 0. 1. 1. 0. 0. 1. 1. 0. 0. 1. 1. 0. 1. 1. 0. 0. 0. 0. 0. 0.]
Мери и Саманта пристигнаха на автогарата рано, но изчакаха до обяд за автобуса
[1. 1. 1. 2. 1. 1. 1. 0. 0. 0. 0. 1. 1. 1. 1. 0. 0. 0. 1. 1. 0. 0.]

Както можете да видите, всяко изречение беше сравнено със списъка ни с думи, генериран в Стъпка 1. Въз основа на сравнението стойността на векторния елемент може да се увеличи. Тези вектори могат да бъдат използвани в ML алгоритмите за класификация на документи и прогнози.

Написахме кода си и генерирахме вектори, но сега да разберем малко повече.

Прозрения в торбата с думи

Моделът BOW отчита само дали в документа се среща известна дума или не. Не се интересува от смисъла, контекста и реда, в който се появяват.

Това дава представа, че подобни документи ще имат сходен брой на думите. С други думи, колкото по-подобни са думите в два документа, толкова по-подобни могат да бъдат документите.

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

  1. Семантично значение: основният подход BOW не отчита значението на думата в документа. Той напълно игнорира контекста, в който се използва. Една и съща дума може да се използва на много места въз основа на контекста или на близките думи.
  2. Размер на вектора: За голям документ размерът на вектора може да бъде огромен, което води до много изчисления и време. Може да се наложи да игнорирате думи въз основа на уместността за вашия случай на използване.

Това беше малко въведение в метода BOW. Кодът показа как работи на ниско ниво. Има много повече за разбиране за BOW. Например, вместо да разделим изречението ни с една дума (1-грам), можете да разделите на двойката две думи (би-грам или 2-грам). Понякога двуграмовото представяне изглежда много по-добро от използването на 1 грам. Те често могат да бъдат представени с помощта на N-грам нотация. Изброих някои научни трудове в раздела за ресурси за по-задълбочени познания.

Не е нужно да кодирате BOW винаги, когато имате нужда. Тя вече е част от много налични рамки като CountVectorizer в научен комплект за обучение.

Нашият предишен код може да бъде заменен с:

от sklearn.feature_extraction.text import CountVectorizer

vectorizer = CountVectorizer ()
X = vectorizer.fit_transform (allsentences)

печат (X.toarray ())

Винаги е добре да разберете как работят библиотеките в рамките и да разберете методите, които стоят зад тях. Колкото по-добре разбирате понятията, толкова по-добре можете да направите рамки.

Благодаря, че прочетохте статията. Показаният код е достъпен на моя GitHub.

Можете да ме последвате в Medium, Twitter и LinkedIn. За всякакви въпроси можете да се свържете с мен на имейл (praveend806 [at] gmail [dot] com).

Ресурси за четене на повече от торбата с думи

  1. Wikipedia-BOW
  2. Разбиране на модела „торба на думите“: Статистическа рамка
  3. Модели и приложения на семантиката, запазващи торби с думи