Natural Language Processing(NLP), закон Ципфа, классификация документов по их содержимому методами машинного обучения. |
||
МЕНЮ Искусственный интеллект Поиск Регистрация на сайте Помощь проекту ТЕМЫ Новости ИИ Искусственный интеллект Разработка ИИГолосовой помощник Городские сумасшедшие ИИ в медицине ИИ проекты Искусственные нейросети Слежка за людьми Угроза ИИ ИИ теория Внедрение ИИКомпьютерные науки Машинное обуч. (Ошибки) Машинное обучение Машинный перевод Реализация ИИ Реализация нейросетей Создание беспилотных авто Трезво про ИИ Философия ИИ Big data Работа разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика
Генетические алгоритмы Капсульные нейросети Основы нейронных сетей Распознавание лиц Распознавание образов Распознавание речи Техническое зрение Чат-боты Авторизация |
2019-12-03 17:44 Ноутбук с кодом, который был написан сотрудниками Samsung для курса «Нейронные сети и обработка текста» можно найти тут. Ну, начнём по порядку. Что такое NLP — можно почитать тут. Касаемо задачи классификации документа по его содержимому(а в общем случае — для любой задачи) на первый взгляд всё может показаться очень простым — заменяем слова на числа: Дела обстоят немного иначе :) Сравните теперь с аналитическим(почти) языком — английским: Вторая проблема — омонимы, в том числе и частеречные. Третья проблема — большой размер данных. В корпусе(множестве документов, документ = какой-то отдельный текст) может находиться огромное кол-во документов, каждый документ состоит из предложений. Каждое предложения является набором слов. И вот каждое такое уникальное слово мы должны где-то хранить. Об этой проблеме поговорим чуть ниже :) Итак, перед нами задача: На первом этапе с помощью регулярных выражений разбиваем каждый документ в корпусе на токены. Например: На втором этапе нам нужно составить словарь(для тех кто не знает что это — краткое интро), ключами которого будут являться наши токены, а значениями — некие числа, которые будут характеризовать данные ключи(токены). Для этого мы считаем частоту вхождения каждого токена в корпус, сортируем эти значения по убыванию/возрастанию частоты — таким образом мы и получаем то самое «число, что описывает некое слово»(эту частоту запишем, например, в массив — читать дальше). Словарь готов! Теперь нам нужно для каждого ключа этого словаря(для каждого токена нашего корпуса документов) просчитать его частоту в каждом документе по незамысловатой формуле: (кол-во документов, в которые входит слово) / (кол-во всех документов)Например, у нас есть 4 документа: 1 = "Казнить нельзя, помиловать. Нельзя наказывать." 2 = "Казнить, нельзя помиловать. Нельзя освободить." 3 = "Нельзя не помиловать." 4 = "Обязательно освободить.» Тогда на выходе мы должны получить вот такой вот словарь: {'наказывать': 0, 'не': 1, 'обязательно': 2, 'казнить': 3, 'освободить': 4, 'помиловать': 5, 'нельзя': 6} Тут-то мы и встречаем ту самую нашу, третью, проблему! Корпус-то большой, слов много! Предлоги, союзы, опечатки — всё в словарь полезет. Нам нужно его отфильтровать, но как это сделать, потеряв как можно меньше информации? tokenized_texts — это список списков. Внешний список — как оболочка. Внутренние списки — список токенов для каждого документа. Словарь построили, отфильтровали — здорово! Осталось векторизовать текст(представить его в виде, условно, матрицы). По одной оси у нас будут располагаться номера документов, а по другой оси — слова, которые встречались в документе. А что будет на пересечении строк и столбцов? Мера важности слова в документе — логично же :) Например, у нас есть 4 документа: line1 = "Казнить нельзя, помиловать. Нельзя наказывать." line2 = "Казнить, нельзя помиловать. Нельзя освободить." line3 = "Нельзя не помиловать." line4 = "Обязательно освободить.» Получаем матрицу вида: (x, y) value (0, 0) 0.39999983 Где x — номер документа, а y — номер токена из нашего предыдущего словаря: {'наказывать': 0, 'не': 1, 'обязательно': 2, 'казнить': 3, 'освободить': 4, 'помиловать': 5, 'нельзя': 6} За это в коде отвечает метод vectorize_texts — https://github.com/Samsung-IT-Academy/stepik-dl-nlp/blob/master/dlnlputils/data/bag_of_words.py Стоит подметить, что метрика accuracy взята в ноутбуке в виду того, что данные распределены равномерно по всем классам. В любом другом случае распределения кол-во элементов по классам — использовать accuracy — не очень целесообразно. Если не понимаете — почему, то спросите в комментариях — отвечу. Эти две строчки кода просто оборачивают наш датасет в оболочку, которую удобнее использовать в процессе обучения нашей модели: Дальнейшие действия в коде мы уже разбирали на других примерах, но давайте еще раз пробежимся: model = nn.Linear(UNIQUE_WORDS_N, UNIQUE_LABELS_N) — задаем модель из одного линейного слоя. Первый параметр — кол-во входных значений(слов/токенов). Второй параметр — кол-во классов, на которые мы хотим научиться делить наши тексты. Ну и всё, по сути-то. Под конец лишь обращу внимание на то, что здесь используется softmax(т.к. здесь многоклассовая классификация). Что это такое и с чем его едят — я покажу и расскажу в одной из следующих статей. P.S. — такой метод называется bag of words(мешок слов) — подразумевается, что мы теряем какую-либо связь во взаимном расположении слов. Источник: m.vk.com Комментарии: |
|