NLP — Natural language processing (обработка естественного языка). Направление исскуственного интелекта, которое решает задачи:

  • Классификация текста (автор, жанр, категория)
  • Машинный перевод
  • Анализ семантики и настроения текста
  • Ответы на вопросы
  • Генерация описания по картинке
  • Генерация текста
  • Синтез речи

One-hot вектор

Самое простое представление текста. Пусть дан словарь из N слов.

_x000D_1) День_x000D_2) Дуб_x000D_3) Зеленый_x000D_4) Златая_x000D_5) Кот_x000D_6) Кругом_x000D_7) Лукоморье_x000D_8) Ночь_x000D_9) Ученый_x000D_10) Ходить_x000D_11) Цепь

One-hot вектор — это вектор для кодирования одного слова. Этот вектор длинной со словарь, в котором все нулю, кроме индекса слова. Там стоит 1.

Пример, слово кот будет кодирован следующим образом:

_x000D_Index = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]_x000D_One_hot_vector = [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]

Bag of Words

Это принцип кодирование предложения, как сумма one-hot векторов слов в этом предложении.

Тогда предложение будут иметь следующий вид:

_x000D_У лукоморья дуб зелёный, Златая цепь на дубе том_x000D_ 7 2 3 4 11 2_x000D__x000D_Index = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]_x000D_Bag_Of_Word = [0, 2, 1, 1, 0, 0, 1, 0, 0, 0, 1]

Второе предложение:

_x000D_И днём и ночью кот учёный всё ходит по цепи кругом_x000D_ 1 8 5 9 10 11 6_x000D__x000D_Index = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]_x000D_Bag_Of_Word = [1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1]

    TF-IDF

    Пусть дана коллекция документов D.

    • t — это индекс слова;
    • d — это индекс отдельного документа из коллекции D;
    • count(t, d) — Это сколько раз встречается слова t в документе d;
    • words(d) — Количество слов в документе d;
    • len(D) — количество документов в коллекции D;

    TF (Term Frequency) — это частота встречаемости слова t в документе d. Определяется как количество слов в документе, деленное на общее количество слов.

    (tf(t,d) = frac{ count(t,d) } { words(d) })

    IDF (Inverse Document Frequency) — это обратная частота документа, которая определяется как количество всех документов, деленное на количество документов, в которых встречается слов t

    (idf(t) = log frac{ len(D) } { displaystylesum_{i=0}^{len(D)} count(t,d) > 0 })

    TF-IDF вычисляется по формуле

    (tfidf(t,d) = tf(t,d) times idf(t,D))

    Высокое значение TF-IDF означает, что слово t в документе d встречается больше, чем в остальных документах, а значит более значимый. Если TF-IDF равен нулю, то он встречается во всех документах и малозначительное.

    Идея классификации текста

    1) Перед анализом нужно очистить весь текст от лишних символов и стоп слов.

    2) Затем проанализировать весь текст, составить словарь всех слов и посчитать их частотность. Оставить только те слова, которые употребляются, например, более 3х раз. И обязательно отсортировать по убыванию частотности.

    Также можно фильтровать и сортировать по метрике TF-IDF.

    3) Затем весь текст нужно разбить на строки длиной L, со сдвигом P и поставить этой строке соответствие с категорией. Каждое слово можно обработать через pyrmorphy или nltk и привести в инфинитив.

    Например текст Пушкина:

    _x000D_У лукоморья дуб зелёный;_x000D_Златая цепь на дубе том:_x000D_И днём и ночью кот учёный_x000D_Всё ходит по цепи кругом;_x000D_Идёт направо - песнь заводит,_x000D_Налево - сказку говорит.

    С длиной L=5 и P=2 текст превратится в набор строк:

    _x000D_лукоморье дуб зелёный златой цепь_x000D_зелёный златой цепь дуб тот_x000D_цепь дуб тот день ночью_x000D_тот день ночью кот учёный_x000D_ночью кот учёный всё ходить_x000D_учёный всё ходить цепь кругом_x000D_ходить цепь кругом идти направо_x000D_кругом идти направо песня заводить_x000D_направо песня заводить налево сказка_x000D_заводить налево сказка говорить

    На практике обычно берут L=1000 и P=2.

    Всем этим строкам нужно поставить соответствие Пушкин. Эти обработанные строки можно сохранить в dataset.json.

    4) Каждую строку нужно сконвертировать в BagOfWord и подать в классификатор Dense и обучить нейронную сеть.

    Пример простой сети:

    _x000D_model = ai.CustomModel(_x000D_	model_name = "Model_bow_2",_x000D_	input_shape = input_shape,_x000D_	module = nn.Sequential(_x000D_		_x000D_		nn.Linear(input_shape[0], 512),_x000D_		nn.ReLU(inplace=True),_x000D_		_x000D_		nn.BatchNorm1d(512),_x000D_		_x000D_		nn.Linear(512, 256),_x000D_		nn.ReLU(inplace=True),_x000D_		_x000D_		nn.Linear(256, output_shape[0]),_x000D_		nn.Softmax(dim=-1),_x000D_	),_x000D_)

    input_shape — это входной вектор, размер BagOfWord

    output_shape — это выходной вектор, количество категорий.

    Минусы Bag of Word

    1. Отсутсвует сохранение порядка слов в предложении
    2. Большие вектора по длине, больше времени считать
    3. При добавлении нового слова в словарь нужно заново обновлять вектора

    А также, но это не точно:

    1. Плохо распознает редкие слова. Редкие слова будут иметь одинаковую маленькую частотность.
    2. Часто встречаемые слова, предлоги будут иметь большие значения в векторе. Высокая частотность слова не всегда означает важность этого слова.