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
- Отсутсвует сохранение порядка слов в предложении
- Большие вектора по длине, больше времени считать
- При добавлении нового слова в словарь нужно заново обновлять вектора
А также, но это не точно:
- Плохо распознает редкие слова. Редкие слова будут иметь одинаковую маленькую частотность.
- Часто встречаемые слова, предлоги будут иметь большие значения в векторе. Высокая частотность слова не всегда означает важность этого слова.