Обработка естественного языка — различия между версиями

Материал из Викиконспекты
Перейти к: навигация, поиск
м (rollbackEdits.php mass rollback)
 
(не показаны 54 промежуточные версии 11 участников)
Строка 1: Строка 1:
'''Обработка естественного языка''' (''Natural Language Processing'') - пересечение [[Машинное обучение | машинного обучения]] и математической лингвистики<ref>[https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%BD%D0%B0%D1%8F_%D0%BB%D0%B8%D0%BD%D0%B3%D0%B2%D0%B8%D1%81%D1%82%D0%B8%D0%BA%D0%B0 Математическая лингвистика]</ref>, направленное на изучение методов анализа и синтеза естественного языка. Сегодня NLP применяется во многих сферах, в том числе в голосовых помощниках, автоматических переводах текста и фильтрации текста. Основными тремя направлениями являются: [[Распознавание речи | распознавание речи]]  (Speech Recognition), понимание естественного языка (Natural Language Understanding<ref>[https://en.wikipedia.org/wiki/Natural-language_understanding  Natural Language Understanding]</ref> ) и генерация естественного языка (Natural Language Generation<ref>[https://en.wikipedia.org/wiki/Natural-language_generation Natural Language Generation]</ref>).
+
'''Обработка естественного языка''' (''Natural Language Processing, NLP'') {{---}} пересечение [[Машинное обучение | машинного обучения]] и математической лингвистики<ref>[https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%BD%D0%B0%D1%8F_%D0%BB%D0%B8%D0%BD%D0%B3%D0%B2%D0%B8%D1%81%D1%82%D0%B8%D0%BA%D0%B0 Математическая лингвистика]</ref>, направленное на изучение методов анализа и синтеза естественного языка. Сегодня NLP применяется во многих сферах, в том числе в голосовых помощниках, автоматических переводах текста и фильтрации текста. Основными тремя направлениями являются: [[Распознавание речи | распознавание речи]]  (Speech Recognition), понимание естественного языка (Natural Language Understanding<ref>[https://en.wikipedia.org/wiki/Natural-language_understanding  Natural Language Understanding]</ref> ) и генерация естественного языка (Natural Language Generation<ref>[https://en.wikipedia.org/wiki/Natural-language_generation Natural Language Generation]</ref>).
 
== Задачи ==
 
== Задачи ==
NLP решает большой набор задач, который можно разбить по уровням. Среди этих задач, можно выделить следующие:
+
{{Определение
* Распознавание текста, речи, синтез речи (сигнал)
+
|definition=
* Морфологический анализ, канонизация (слово)
+
'''Корпус''' {{---}} подобранная и обработанная по определённым правилам совокупность текстов, используемых в качестве базы для исследования языка.
* POS-тэгирование, распознавание именованных сущностей, выделение слов (словосочетание)
+
}}
* Синтаксический разбор, токенизация предложений (предложение)
+
NLP решает большой набор задач, который можно разбить по уровням (в скобках). Среди этих задач, можно выделить следующие:
* Извлечение отношений, определение языка, анализ эмоциональной окраски (абзац)
+
* Распознавание текста, речи, синтез речи (сигнал);
* Аннотация документа, перевод, анализ тематики (документ)
+
* Морфологический анализ, канонизация (слово);
* Дедубликация, информационный поиск (корпус)
+
* POS-тэгирование, распознавание именованных сущностей, выделение слов (словосочетание);
 +
* Синтаксический разбор, токенизация предложений (предложение);
 +
* Извлечение отношений, определение языка, анализ эмоциональной окраски (абзац);
 +
* Аннотация документа, перевод, анализ тематики (документ);
 +
* Дедубликация, информационный поиск (корпус).
  
 
== Основные подходы ==
 
== Основные подходы ==
 +
=== Предобработка текста ===
 +
Предобработка текста переводит текст на естественном языке в формат удобный для дальнейшей работы. Предобработка состоит из различных этапов, которые могут отличаться в зависимости от задачи и реализации. Далее приведен один из возможных набор этапов:
 +
* Перевод всех букв в тексте в нижний или верхний регистры;
 +
* Удаление цифр (чисел) или замена на текстовый эквивалент (обычно используются регулярные выражения);
 +
* Удаление пунктуации. Обычно реализуется как удаление из текста символов из заранее заданного набора;
 +
* Удаление пробельных символов (whitespaces);
 +
* Токенизация (обычно реализуется на основе регулярных выражений);
 +
* Удаление стоп слов;
 +
* Стемминг;
 +
* Лемматизация;
 +
* Векторизация.
 +
 
=== Стемминг ===
 
=== Стемминг ===
Количество корректных словоформ, значения которых схожи, но написания отличаются суффиксами, приставками, окончаниями и прочим, очень велико, что усложняет создание словарей и дальнейшую обработку. Стемминг позволяет привести слово к его основной форме. Суть подхода в нахождении основы слова, для этого с конца и начала слова последовательно отрезаются его части. Правила отсекания для стеммера создаются заранее (лингвистами), что делает данный подход трудоемким, так как при подключении очередного языка нужны новые лингвистические исследования. Вторым недостатком подхода является возможная потеря информации при отрезании частей, например, мы можем потерять информацию о части речи.  
+
Количество корректных словоформ, значения которых схожи, но написания отличаются суффиксами, приставками, окончаниями и прочим, очень велико, что усложняет создание словарей и дальнейшую обработку. Стемминг позволяет привести слово к его основной форме. Суть подхода в нахождении основы слова, для этого с конца и начала слова последовательно отрезаются его части. Правила отсекания для стеммера создаются заранее, и чаще всего представляют из себя регулярные выражения, что делает данный подход трудоемким, так как при подключении очередного языка нужны новые лингвистические исследования. Вторым недостатком подхода является возможная потеря информации при отрезании частей, например, мы можем потерять информацию о части речи.  
  
 
=== Лемматизация ===
 
=== Лемматизация ===
Данный подход является альтернативой стемминга. Основная идея в приведении слова к словарной форме - лемме. Например для русского языка:
+
Данный подход является альтернативой стемминга. Основная идея в приведении слова к словарной форме {{---}} лемме. Например для русского языка:
* для существительных — именительный падеж, единственное число
+
* для существительных — именительный падеж, единственное число;
* для прилагательных — именительный падеж, единственное число, мужской род
+
* для прилагательных — именительный падеж, единственное число, мужской род;
* для глаголов, причастий, деепричастий глагол в инфинитиве несовершенного вида
+
* для глаголов, причастий, деепричастий {{---}} глагол в инфинитиве несовершенного вида.
  
 
=== Векторизация ===
 
=== Векторизация ===
Большинство математических моделей работают в векторных пространствах больших размерностей, поэтому необходимо отобразить текст в векторном пространстве. Основным походом являет bag-of-words (мешок слов): для документа формируется вектор размерности словаря, для каждого слова выделяется своя размерность, для документа записывается признак насколько часто слово встречается в нем, получаем вектор. Наиболее распространенным методом для вычисления признака является TF-IDF (TF - term frequency, частота слова, IDF - inverse document frequency, обратная частота документа). TF вычисляется, например, счетчиком вхождения слова. IDF обычно вычисляют как логарифм от числа документов в корпусе, разделённый на количество документов, где это слово представлено. Таким образом, если какое-то слово встретилось во всех документах корпуса, то такое слово не будет никуда добавлено. Плюсами мешка слов является простая реализация, однако данный метод теряет часть информации, например, порядок слов.  
+
{{main|Векторное представление слов}}
Для уменьшения потери информации можно использовать мешок N-грамм (добавлять не только слова, но и словосочетания), или использовать методы векторных представлений слов - это, например, позволяет снизить ошибку на словах с одинаковыми написаниями, но разными значениями.
+
Большинство математических моделей работают в векторных пространствах больших размерностей, поэтому необходимо отобразить текст в векторном пространстве. Основным походом является мешок слов (bag-of-words): для документа формируется вектор размерности словаря, для каждого слова выделяется своя размерность, для документа записывается признак насколько часто слово встречается в нем, получаем вектор. Наиболее распространенным методом для вычисления признака является TF-IDF<ref>[https://ru.wikipedia.org/wiki/TF-IDF TF-IDF]</ref> (TF {{---}} частота слова, term frequency, IDF {{---}} обратная частота документа, inverse document frequency). TF вычисляется, например, счетчиком вхождения слова. IDF обычно вычисляют как логарифм от числа документов в корпусе, разделённый на количество документов, где это слово представлено. Таким образом, если какое-то слово встретилось во всех документах корпуса, то такое слово не будет никуда добавлено. Плюсами мешка слов является простая реализация, однако данный метод теряет часть информации, например, порядок слов.  
 +
Для уменьшения потери информации можно использовать мешок N-грамм (добавлять не только слова, но и словосочетания), или использовать методы векторных представлений слов это, например, позволяет снизить ошибку на словах с одинаковыми написаниями, но разными значениями.
  
 
=== Дедубликация ===
 
=== Дедубликация ===
Строка 28: Строка 45:
  
 
=== Семантический анализ ===
 
=== Семантический анализ ===
Семантический (смысловой) анализ текста - выделение семантических отношений, формировании семантического представления. В общем случае семантическое представление является графом, семантической сетью, отражающим бинарные отношения между двумя узлами — смысловыми единицами текста. Глубина семантического анализа может быть разной, а в реальных системах чаще всего строится только лишь синтаксико-семантическое представление текста или отдельных предложений.
+
Семантический (смысловой) анализ текста {{---}} выделение семантических отношений, формировании семантического представления. В общем случае семантическое представление является графом, семантической сетью, отражающим бинарные отношения между двумя узлами — смысловыми единицами текста. Глубина семантического анализа может быть разной, а в реальных системах чаще всего строится только лишь синтаксико-семантическое представление текста или отдельных предложений.
 +
Семантический анализ применяется в задачах анализа тональности текста<ref>[https://en.wikipedia.org/wiki/Sentiment_analysis Анализ тональности текста]</ref>(Sentiment analysis), например, для автоматизированного определения положительности отзывов.
 +
 
 +
=== Распознавание именованных сущностей и извлечение отношений ===
 +
Именованные сущности {{---}} объекты из текста, которые могут быть отнесены к одной из заранее заявленных категорий (например, организации, личности, адреса). Идентификация ссылок на подобные сущности в тексте является задачей распознавания именованных сущностей.
 +
Станкевич Андрей Сергеевич {{---}} лауреат специальной премии корпорации IBM.
 +
'''Станкевич Андрей Сергеевич'''[личность] {{---}} лауреат специальной премии корпорации '''IBM'''[компания].
 +
Определение семантических отношений между именованными сущностями или другими объектами текста, является задачей извлечения отношений. Примеры отношений: (автор,книга), (организация,главный_офис).
 +
 
 +
Эти два подхода применяются во многих задачах, например, извлечение синонимов из текста, автоматическом построении онтологий и реализованы во многих работающих системах, например, NELL<ref>[http://rtw.ml.cmu.edu/rtw/ NELL]</ref> и Snowball<ref>[http://www.mathcs.emory.edu/~eugene/papers/dl00.pdf Snowball]</ref>.
 +
 
 +
=== Использование N-грамм ===
 +
{{Определение
 +
|definition=
 +
'''N-грамма''' {{---}} последовательность из <tex>n</tex> элементов.
 +
}}
 +
В NLP N-граммы используются для построения вероятностных моделей, задач схожести текстов, категоризации текста и языка.
 +
 
 +
Построив N-граммную модель можно определить вероятность употребления заданной фразы в тексте. N-граммная модель рассчитывает вероятность последнего слова N-граммы, если известны все предыдущие, при этом полагается, что вероятность появления каждого слова зависит только от предыдущих слов.
 +
 
 +
Использование N-грамм применяется в задаче выявления плагиата. Текст разбивается на несколько фрагментов, представленных N-граммами. Сравнение N-грамм друг с другом позволяет определить степень сходства документов. Аналогичным способом можно решать задачу исправления орфографических ошибок, подбирая слова кандидаты для замены.
 +
 
 +
=== Частеречная разметка ===
 +
Частеречная разметка (POS-тэгирование, англ. part-of-speech tagging) используется в NLP для определения части речи и грамматических характеристик слов в тексте с приписыванием им соответствующих тегов. Модель необходима, когда значение слова зависит от контекста. Например, в предложениях "Столовая ложка" и "Школьная столовая" слово "столовая" имеет разные части речи. POS-тэгирование позволяет сопоставить слову в тексте специальный тэг на основе его значения и контекста.
  
=== NER и Relation Extraction ===
+
Алгоритмы частеречной разметки делятся на несколько групп:
Именованные сущности - объекты из текста, которые могут быть отнесены к одной из заранее заявленных категорий (например, организации, личности, адреса). Идентификация ссылок на подобные сущности в тексте является задачей распознавания именованных сущностей. Определение семантических отношений между именованными сущностями или другими объектами текста, является задачей извлечения отношений. Эти два подхода применяются во многих задачах, например, извлечение синонимов из текста, автоматическом построении онтологий.
+
* ''Стохастический метод''. Такой метод имеет два похожих друг на друга подхода. Первый подход основывается на частоте встречаемости слова с конкретным тэгом: если определенное слово встречается чаще всего с тэгом "существительное", то скорее всего и сейчас оно будет иметь такой тэг. Второй вариант использует n-граммы {{---}} анализируя входную последовательность, алгоритм высчитывает вероятность, что в данном контексте будет определенный тэг. В конце просчета вероятностей выбирается тэг, который имеет наибольшую вероятность. Библиотека TextBlob<ref>[https://textblob.readthedocs.io/en/dev/ TextBlob]</ref> в своей основе использует стохастический метод.
 +
* ''Основанные на правилах''. Метод основан на заранее известных правилах. Алгоритм состоит из двух стадий. Сначала расставляются потенциальные тэги всем словам на основе словаря или по какому-либо другому принципу. Далее, если у какого-нибудь слова оказалось несколько тэгов, правильный тэг выбирается на основе рукописных правил. Правил должно быть много, чтобы решить все возникшие неопределенности и учесть все случаи. Например, правило: слова длиной меньше трех символов являются частицами, местоимениями или предлогами. Однако такое правило не учитывает некоторые короткие слова из других частей речи. В библиотеке NLTK<ref>[https://www.nltk.org/ NLTK]</ref> используется данный метод.
 +
* ''С использованием [[Скрытые Марковские модели|скрытой марковской модели]]''. Пусть в нашей Марковской модели ''тэги'' будут '''скрытыми состояниями''', которые производят '''наблюдаемое событие''' {{---}} ''слова''. С математической точки зрения, мы хотим найти такую ''последовательность тэгов (C)'', которая будет максимизировать условную вероятность <tex>P(C|W)</tex>, где <tex>C = C_1, C_2, \dots C_T</tex> и <tex>W = W_1, W_2, \dots W_T</tex>. Воспользовавшись формулой Байеса получим, что максимизировать необходимо следующее выражение: <tex>p(C_1, C_2, \dots C_T) \cdot p(W_1, W_2, \dots W_T | C_1, C_2, \dots C_T)</tex>. Библиотека spaCy<ref>[https://spacy.io/ spaCy]</ref> основана на скрытой марковской модели.
  
 +
POS-тэгирование является неотъемлемой частью обработки естественного языка. Без частеречной разметки становится невозможным дальнейший анализ текста из-за возникновения неопределенностей в значениях слов. Данный алгоритм используется при решении таких задач как перевод на другой язык, определение смысла текста, проверка на пунктуационные и речевые ошибки. Также можно автоматизировать процесс определения хештегов у постов и статей, выделяя существительные в приведенном тексте.
  
 +
Благодаря частому использованию POS-тэгирования на практике, существует много встроенных библиотек с готовыми реализациями. Например, NLTK, scikit-learn<ref>[https://scikit-learn.org scikit-learn]</ref>, spaCy, TextBlob, HunPOS<ref>[https://code.google.com/archive/p/hunpos/ HunPOS]</ref>, Standford POS Tagger<ref>[https://nlp.stanford.edu/software/tagger.shtml Stanford]</ref> и другие. Примеры использования некоторых библиотек:
 +
* TextBlob (''стохастический метод''):
 +
from textblob import TextBlob 
 +
text = ("The quick brown fox jumps over the lazy dog") 
 +
blob_object = TextBlob(text)
 +
print(blob_object.tags)
 +
'''output:''' [('The', 'DT'), ('quick', 'JJ'), ('brown', 'JJ'), ('fox', 'NN'), ('jumps', 'VBZ'), ('over', 'IN'), ('the', 'DT'), ('lazy', 'JJ'), ('dog', 'NN')]
 +
* NLTK (''основанный на правилах''):
 +
import nltk
 +
from nltk.tokenize import word_tokenize
 +
text = word_tokenize("Hello welcome to the world of to learn Categorizing and POS Tagging with NLTK and Python")
 +
nltk.pos_tag(text)
 +
'''output:''' [('Hello', 'NNP'), ('welcome', 'NN'), ('to', 'TO'), ('the', 'DT'), ('world', 'NN'), ('of', 'IN'), ('to', 'TO'), ('learn', 'VB'), ('Categorizing', 'NNP'), ('and', 'CC'), ('POS', 'NNP'), ('Tagging', 'NNP'), ('with', 'IN'), ('NLTK', 'NNP'), ('and', 'CC'), ('Python', 'NNP')]
 +
* spaCy (''с использованием скрытой марковской модели''):
 +
import spacy
 +
nlp = spacy.load("en_core_web_sm")
 +
doc = nlp("The quick brown fox jumps over the lazy dog")
 +
for token in doc:
 +
    print((token.text, token.pos_))
 +
'''output:''' [('The', 'DT'), ('quick', 'JJ'), ('brown', 'JJ'), ('fox', 'NN'), ('jumps', 'NNS'), ('over', 'IN'), ('the', 'DT'), ('lazy', 'JJ'), ('dog', 'NN')]
 +
* HunPOS:
 +
from os.path import expanduser
 +
home = expanduser("~")
 +
from nltk.tag.hunpos import HunposTagger
 +
_path_to_bin = home + '/hunpos-1.0-linux/hunpos-tag'
 +
_path_to_model = home + '/hunpos-1.0-linux/en_wsj.model'
 +
ht = HunposTagger(path_to_model=_path_to_model, path_to_bin=_path_to_bin)
 +
text = "The quick brown fox jumps over the lazy dog"
 +
ht.tag(text.split())
 +
'''output:''' [('The', 'DT'), ('quick', 'JJ'), ('brown', 'JJ'), ('fox', 'NN'), ('jumps', 'NNS'), ('over', 'IN'), ('the', 'DT'), ('lazy', 'JJ'), ('dog', 'NN')]
 +
* Stanford POS tagger
 +
from os.path import expanduser
 +
home = expanduser("~")
 +
from nltk.tag.stanford import POSTagger
 +
_path_to_model = home + '/stanford-postagger/models/english-bidirectional-distsim.tagger'
 +
_path_to_jar = home + '/stanford-postagger/stanford-postagger.jar'
 +
st = POSTagger(path_to_model=_path_to_model, path_to_jar=_path_to_jar)
 +
text = "The quick brown fox jumps over the lazy dog"
 +
st.tag(text.split())
 +
'''output:''' [('The', 'DT'), ('quick', 'JJ'), ('brown', 'JJ'), ('fox', 'NN'), ('jumps', 'VBZ'), ('over', 'IN'), ('the', 'DT'), ('lazy', 'JJ'), ('dog', 'NN')]
  
 
== Библиотеки для NLP ==
 
== Библиотеки для NLP ==
 
=== NLTK (Natural Language ToolKit)<ref>[https://www.nltk.org/ NLTK]</ref> ===
 
=== NLTK (Natural Language ToolKit)<ref>[https://www.nltk.org/ NLTK]</ref> ===
 +
Пакет библиотек и программ для символьной и статистической обработки естественного языка, написанных на Python и разработанных по методологии SCRUM. Содержит графические представления и примеры данных. Поддерживает работу с множеством языков, в том числе, русским.
 +
 
Плюсы:
 
Плюсы:
* Самая известная и полная по функционалу библиотека для NLP
+
* Наиболее известная и многофункциональная библиотека для NLP;
* Большое количество сторонних расширений
+
* Большое количество сторонних расширений;
* Быстрая токенизация предложений
+
* Быстрая токенизация предложений;
* Поддерживается множество языков
+
* Поддерживается множество языков.
 
Минусы
 
Минусы
* Медленная
+
* Медленная;
* Сложная в изучении и использовании
+
* Сложная в изучении и использовании;
* Работает со строками
+
* Работает со строками;
* Нет встроенных сетей
+
* Не использует нейронные сети;
* Нет встроенных векторов слов
+
* Нет встроенных векторов слов.
  
 
=== spaCy<ref>[https://spacy.io/ spaCy]</ref> ===
 
=== spaCy<ref>[https://spacy.io/ spaCy]</ref> ===
 +
Библиотека, разработанная по методологии SCRUM на языке Cypthon, позиционируется как самая быстрая NLP библиотека. Имеет множество возможностей, в том числе, разбор зависимостей на основе меток, распознавание именованных сущностей, пометка частей речи, векторы расстановки слов. Не поддерживает русский язык.
 +
 
Плюсы:
 
Плюсы:
* Самая быстрая библиотека для NLP
+
* Самая быстрая библиотека для NLP;
* Простая в изучении и использовании
+
* Простая в изучении и использовании;
* Работает с объектами, а не строками
+
* Работает с объектами, а не строками;
* Есть встроенные вектора слов
+
* Есть встроенные вектора слов;
* Использует нейронные сети для тренировки моделей
+
* Использует нейронные сети для тренировки моделей.
 
Минусы
 
Минусы
* Менее гибкая по сравнению с NLTK
+
* Менее гибкая по сравнению с NLTK;
* Токенизация предложений медленнее, чем в NLTK
+
* Токенизация предложений медленнее, чем в NLTK;
* Поддерживает маленькое количество языков
+
* Поддерживает маленькое количество языков.
  
 
=== scikit-learn<ref>[https://scikit-learn.org scikit-learn]</ref> ===
 
=== scikit-learn<ref>[https://scikit-learn.org scikit-learn]</ref> ===
 +
Библиотека scikit-learn разработана  по методологии SCRUM и предоставляет реализацию целого ряда алгоритмов для обучения с учителем и обучения без учителя через интерфейс для Python. Построена поверх SciPy. Ориентирована в первую очередь на моделирование данных, имеет достаточно функций, чтобы использоваться для NLP в связке с другими библиотеками.
 +
 
Плюсы:
 
Плюсы:
* Большое количество алгоритмов для построения моделей
+
* Большое количество алгоритмов для построения моделей;
* Содержит функции для работы с Bag-of-Words моедлью
+
* Содержит функции для работы с Bag-of-Words моделью;
* Хорошая документация
+
* Хорошая документация.
 
Минусы
 
Минусы
* Плохой препроцессинг, что вынуждает использовать ее в связке с другой библиотекой (например, NLTK)
+
* Плохой препроцессинг, что вынуждает использовать ее в связке с другой библиотекой (например, NLTK);
* Не использует нейронные сети для препроцессинга текста
+
* Не использует нейронные сети для препроцессинга текста.
  
 
=== gensim<ref>[https://radimrehurek.com/gensim/ gensim]</ref> ===
 
=== gensim<ref>[https://radimrehurek.com/gensim/ gensim]</ref> ===
 +
Python библиотека, разработанная по методологии SCRUM, для моделирования, тематического моделирования документов и извлечения подобия для больших корпусов. В gensim реализованы популярные NLP алгоритмы, например, word2vec. Большинство реализаций могут использовать несколько ядер.
 +
 
Плюсы:
 
Плюсы:
* Работает с большими датасетами
+
* Работает с большими датасетами;
* Поддерживает глубокое обучение
+
* Поддерживает глубокое обучение;
* word2vec, tf-idf vectorization, document2vec
+
* word2vec, tf-idf vectorization, document2vec.
 
Минусы
 
Минусы
* Заточена под модели без учителя
+
* Заточена под модели без учителя;
* Не содержит достаточного функционала, необходимого для NLP, что вынуждает использовать ее вместе с другими библиотеками
+
* Не содержит достаточного функционала, необходимого для NLP, что вынуждает использовать ее вместе с другими библиотеками.
 +
 
 +
 
 +
 
 +
Балто-славянские языки имеют сложную морфологию, что может ухудшить качество обработки текста, а также ограничить использование ряда библиотек. Для работы со специфичной русской морфологией можно использовать, например, морфологический анализатор '''pymorphy2'''<ref>[https://github.com/kmike/pymorphy2 pymorphy2]</ref> и библиотеку для поиска и извлечения именованных сущностей '''Natasha'''<ref>[https://github.com/natasha/natasha Natasha]</ref>
  
 
== Примеры использования NLTK ==
 
== Примеры использования NLTK ==
* Sentence Segmentation
+
* Разбиение на предложения:
 +
text = "Предложение. Предложение, которое содержит запятую. Восклицательный знак! Вопрос?"
 
  sents = nltk.sent_tokenize(text)
 
  sents = nltk.sent_tokenize(text)
* Tokenization
+
print(sents)
 +
'''output:''' ['Предложение.', 'Предложение, которое содержит запятую.', 'Восклицательный знак!', 'Вопрос?']
 +
* Токенизация:
 
  from nltk.tokenize import RegexpTokenizer
 
  from nltk.tokenize import RegexpTokenizer
 +
sent = "В этом предложении есть много слов, мы их разделим."
 
  tokenizer = RegexpTokenizer(r'\w+')
 
  tokenizer = RegexpTokenizer(r'\w+')
  tokenizer.tokenize(sents[0])
+
  print(tokenizer.tokenize(sent))
 +
'''output:''' ['В', 'этом', 'предложении', 'есть', 'много', 'слов', 'мы', 'их', 'разделим']
  
 
  from nltk import word_tokenize
 
  from nltk import word_tokenize
  tokens = word_tokenize(sents[0])
+
  sent = "В этом предложении есть много слов, мы их разделим."
* StopWords
+
print(word_tokenize(sent))
 +
'''output:''' ['В', 'этом', 'предложении', 'есть', 'много', 'слов', ',', 'мы', 'их', 'разделим', '.']
 +
* Стоп слова:
 
  from nltk.corpus import stopwords
 
  from nltk.corpus import stopwords
 
  stop_words=set(stopwords.words('english'))
 
  stop_words=set(stopwords.words('english'))
 +
print(stop_words)
 +
'''output:''' {'should', 'wouldn', 'do', 'over', 'her', 'what', 'aren', 'once', 'same', 'this', 'needn', 'other', 'been', 'with', 'all' ...
  
* Stemming And Lemmatization
+
* Стемминг и лемматизация:
 
  from nltk.stem.porter import PorterStemmer
 
  from nltk.stem.porter import PorterStemmer
 
  porter_stemmer = PorterStemmer()
 
  porter_stemmer = PorterStemmer()
  porter_stemmer.stem("crying") // cri
+
  print(porter_stemmer.stem("crying"))
 +
'''output:''' cri
  
 
  from nltk.stem.lancaster import LancasterStemmer
 
  from nltk.stem.lancaster import LancasterStemmer
 
  lancaster_stemmer = LancasterStemmer()
 
  lancaster_stemmer = LancasterStemmer()
  lancaster_stemmer.stem("crying") // cry
+
  print(lancaster_stemmer.stem("crying"))
 +
'''output:''' cry
  
 
  from nltk.stem import SnowballStemmer
 
  from nltk.stem import SnowballStemmer
 
  snowball_stemmer = SnowballStemmer("english")
 
  snowball_stemmer = SnowballStemmer("english")
  snowball_stemmer.stem("crying") // cri
+
  print(snowball_stemmer.stem("crying"))
 +
'''output:''' cri
  
 
  from nltk.stem import WordNetLemmatizer
 
  from nltk.stem import WordNetLemmatizer
 
  wordnet_lemmatizer = WordNetLemmatizer()
 
  wordnet_lemmatizer = WordNetLemmatizer()
  wordnet_lemmatizer.lemmatize("came", pos="v") // come
+
  print(wordnet_lemmatizer.lemmatize("came", pos="v"))
 +
'''output:''' come
  
 
== Пример кода на языке Scala ==
 
== Пример кода на языке Scala ==
Строка 120: Строка 228:
  
 
==Источники информации==
 
==Источники информации==
# [https://en.wikipedia.org/wiki/Natural_language_processing] - статья на Википедии
+
# [https://en.wikipedia.org/wiki/Natural_language_processing] {{---}} статья на Википедии
 +
# [http://www.nltk.org/book/ Natural Language Processing with Python] {{---}} Analyzing Text with the Natural Language Toolkit
 +
# [http://www.cs.colorado.edu/~martin/slp2.html Speech and Language Processing]
 
[[Категория: Машинное обучение]] [[Категория: Обработка естественного языка]]
 
[[Категория: Машинное обучение]] [[Категория: Обработка естественного языка]]

Текущая версия на 19:13, 4 сентября 2022

Обработка естественного языка (Natural Language Processing, NLP) — пересечение машинного обучения и математической лингвистики[1], направленное на изучение методов анализа и синтеза естественного языка. Сегодня NLP применяется во многих сферах, в том числе в голосовых помощниках, автоматических переводах текста и фильтрации текста. Основными тремя направлениями являются: распознавание речи  (Speech Recognition), понимание естественного языка (Natural Language Understanding[2] ) и генерация естественного языка (Natural Language Generation[3]).

Задачи

Определение:
Корпус — подобранная и обработанная по определённым правилам совокупность текстов, используемых в качестве базы для исследования языка.

NLP решает большой набор задач, который можно разбить по уровням (в скобках). Среди этих задач, можно выделить следующие:

  • Распознавание текста, речи, синтез речи (сигнал);
  • Морфологический анализ, канонизация (слово);
  • POS-тэгирование, распознавание именованных сущностей, выделение слов (словосочетание);
  • Синтаксический разбор, токенизация предложений (предложение);
  • Извлечение отношений, определение языка, анализ эмоциональной окраски (абзац);
  • Аннотация документа, перевод, анализ тематики (документ);
  • Дедубликация, информационный поиск (корпус).

Основные подходы

Предобработка текста

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

  • Перевод всех букв в тексте в нижний или верхний регистры;
  • Удаление цифр (чисел) или замена на текстовый эквивалент (обычно используются регулярные выражения);
  • Удаление пунктуации. Обычно реализуется как удаление из текста символов из заранее заданного набора;
  • Удаление пробельных символов (whitespaces);
  • Токенизация (обычно реализуется на основе регулярных выражений);
  • Удаление стоп слов;
  • Стемминг;
  • Лемматизация;
  • Векторизация.

Стемминг

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

Лемматизация

Данный подход является альтернативой стемминга. Основная идея в приведении слова к словарной форме — лемме. Например для русского языка:

  • для существительных — именительный падеж, единственное число;
  • для прилагательных — именительный падеж, единственное число, мужской род;
  • для глаголов, причастий, деепричастий — глагол в инфинитиве несовершенного вида.

Векторизация

Большинство математических моделей работают в векторных пространствах больших размерностей, поэтому необходимо отобразить текст в векторном пространстве. Основным походом является мешок слов (bag-of-words): для документа формируется вектор размерности словаря, для каждого слова выделяется своя размерность, для документа записывается признак насколько часто слово встречается в нем, получаем вектор. Наиболее распространенным методом для вычисления признака является TF-IDF[4] (TF — частота слова, term frequency, IDF — обратная частота документа, inverse document frequency). TF вычисляется, например, счетчиком вхождения слова. IDF обычно вычисляют как логарифм от числа документов в корпусе, разделённый на количество документов, где это слово представлено. Таким образом, если какое-то слово встретилось во всех документах корпуса, то такое слово не будет никуда добавлено. Плюсами мешка слов является простая реализация, однако данный метод теряет часть информации, например, порядок слов. Для уменьшения потери информации можно использовать мешок N-грамм (добавлять не только слова, но и словосочетания), или использовать методы векторных представлений слов это, например, позволяет снизить ошибку на словах с одинаковыми написаниями, но разными значениями.

Дедубликация

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

Семантический анализ

Семантический (смысловой) анализ текста — выделение семантических отношений, формировании семантического представления. В общем случае семантическое представление является графом, семантической сетью, отражающим бинарные отношения между двумя узлами — смысловыми единицами текста. Глубина семантического анализа может быть разной, а в реальных системах чаще всего строится только лишь синтаксико-семантическое представление текста или отдельных предложений. Семантический анализ применяется в задачах анализа тональности текста[5](Sentiment analysis), например, для автоматизированного определения положительности отзывов.

Распознавание именованных сущностей и извлечение отношений

Именованные сущности — объекты из текста, которые могут быть отнесены к одной из заранее заявленных категорий (например, организации, личности, адреса). Идентификация ссылок на подобные сущности в тексте является задачей распознавания именованных сущностей.

Станкевич Андрей Сергеевич — лауреат специальной премии корпорации IBM.
Станкевич Андрей Сергеевич[личность] — лауреат специальной премии корпорации IBM[компания].

Определение семантических отношений между именованными сущностями или другими объектами текста, является задачей извлечения отношений. Примеры отношений: (автор,книга), (организация,главный_офис).

Эти два подхода применяются во многих задачах, например, извлечение синонимов из текста, автоматическом построении онтологий и реализованы во многих работающих системах, например, NELL[6] и Snowball[7].

Использование N-грамм

Определение:
N-грамма — последовательность из [math]n[/math] элементов.

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

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

Использование N-грамм применяется в задаче выявления плагиата. Текст разбивается на несколько фрагментов, представленных N-граммами. Сравнение N-грамм друг с другом позволяет определить степень сходства документов. Аналогичным способом можно решать задачу исправления орфографических ошибок, подбирая слова кандидаты для замены.

Частеречная разметка

Частеречная разметка (POS-тэгирование, англ. part-of-speech tagging) используется в NLP для определения части речи и грамматических характеристик слов в тексте с приписыванием им соответствующих тегов. Модель необходима, когда значение слова зависит от контекста. Например, в предложениях "Столовая ложка" и "Школьная столовая" слово "столовая" имеет разные части речи. POS-тэгирование позволяет сопоставить слову в тексте специальный тэг на основе его значения и контекста.

Алгоритмы частеречной разметки делятся на несколько групп:

  • Стохастический метод. Такой метод имеет два похожих друг на друга подхода. Первый подход основывается на частоте встречаемости слова с конкретным тэгом: если определенное слово встречается чаще всего с тэгом "существительное", то скорее всего и сейчас оно будет иметь такой тэг. Второй вариант использует n-граммы — анализируя входную последовательность, алгоритм высчитывает вероятность, что в данном контексте будет определенный тэг. В конце просчета вероятностей выбирается тэг, который имеет наибольшую вероятность. Библиотека TextBlob[8] в своей основе использует стохастический метод.
  • Основанные на правилах. Метод основан на заранее известных правилах. Алгоритм состоит из двух стадий. Сначала расставляются потенциальные тэги всем словам на основе словаря или по какому-либо другому принципу. Далее, если у какого-нибудь слова оказалось несколько тэгов, правильный тэг выбирается на основе рукописных правил. Правил должно быть много, чтобы решить все возникшие неопределенности и учесть все случаи. Например, правило: слова длиной меньше трех символов являются частицами, местоимениями или предлогами. Однако такое правило не учитывает некоторые короткие слова из других частей речи. В библиотеке NLTK[9] используется данный метод.
  • С использованием скрытой марковской модели. Пусть в нашей Марковской модели тэги будут скрытыми состояниями, которые производят наблюдаемое событиеслова. С математической точки зрения, мы хотим найти такую последовательность тэгов (C), которая будет максимизировать условную вероятность [math]P(C|W)[/math], где [math]C = C_1, C_2, \dots C_T[/math] и [math]W = W_1, W_2, \dots W_T[/math]. Воспользовавшись формулой Байеса получим, что максимизировать необходимо следующее выражение: [math]p(C_1, C_2, \dots C_T) \cdot p(W_1, W_2, \dots W_T | C_1, C_2, \dots C_T)[/math]. Библиотека spaCy[10] основана на скрытой марковской модели.

POS-тэгирование является неотъемлемой частью обработки естественного языка. Без частеречной разметки становится невозможным дальнейший анализ текста из-за возникновения неопределенностей в значениях слов. Данный алгоритм используется при решении таких задач как перевод на другой язык, определение смысла текста, проверка на пунктуационные и речевые ошибки. Также можно автоматизировать процесс определения хештегов у постов и статей, выделяя существительные в приведенном тексте.

Благодаря частому использованию POS-тэгирования на практике, существует много встроенных библиотек с готовыми реализациями. Например, NLTK, scikit-learn[11], spaCy, TextBlob, HunPOS[12], Standford POS Tagger[13] и другие. Примеры использования некоторых библиотек:

  • TextBlob (стохастический метод):
from textblob import TextBlob  
text = ("The quick brown fox jumps over the lazy dog")  
blob_object = TextBlob(text) 
print(blob_object.tags) 
output: [('The', 'DT'), ('quick', 'JJ'), ('brown', 'JJ'), ('fox', 'NN'), ('jumps', 'VBZ'), ('over', 'IN'), ('the', 'DT'), ('lazy', 'JJ'), ('dog', 'NN')]
  • NLTK (основанный на правилах):
import nltk
from nltk.tokenize import word_tokenize
text = word_tokenize("Hello welcome to the world of to learn Categorizing and POS Tagging with NLTK and Python")
nltk.pos_tag(text)
output: [('Hello', 'NNP'), ('welcome', 'NN'), ('to', 'TO'), ('the', 'DT'), ('world', 'NN'), ('of', 'IN'), ('to', 'TO'), ('learn', 'VB'), ('Categorizing', 'NNP'), ('and', 'CC'), ('POS', 'NNP'), ('Tagging', 'NNP'), ('with', 'IN'), ('NLTK', 'NNP'), ('and', 'CC'), ('Python', 'NNP')]
  • spaCy (с использованием скрытой марковской модели):
import spacy
nlp = spacy.load("en_core_web_sm")
doc = nlp("The quick brown fox jumps over the lazy dog")
for token in doc:
   print((token.text, token.pos_))
output: [('The', 'DT'), ('quick', 'JJ'), ('brown', 'JJ'), ('fox', 'NN'), ('jumps', 'NNS'), ('over', 'IN'), ('the', 'DT'), ('lazy', 'JJ'), ('dog', 'NN')]
  • HunPOS:
from os.path import expanduser
home = expanduser("~")
from nltk.tag.hunpos import HunposTagger
_path_to_bin = home + '/hunpos-1.0-linux/hunpos-tag'
_path_to_model = home + '/hunpos-1.0-linux/en_wsj.model'
ht = HunposTagger(path_to_model=_path_to_model, path_to_bin=_path_to_bin)
text = "The quick brown fox jumps over the lazy dog"
ht.tag(text.split())
output: [('The', 'DT'), ('quick', 'JJ'), ('brown', 'JJ'), ('fox', 'NN'), ('jumps', 'NNS'), ('over', 'IN'), ('the', 'DT'), ('lazy', 'JJ'), ('dog', 'NN')]
  • Stanford POS tagger
from os.path import expanduser
home = expanduser("~")
from nltk.tag.stanford import POSTagger
_path_to_model = home + '/stanford-postagger/models/english-bidirectional-distsim.tagger'
_path_to_jar = home + '/stanford-postagger/stanford-postagger.jar'
st = POSTagger(path_to_model=_path_to_model, path_to_jar=_path_to_jar)
text = "The quick brown fox jumps over the lazy dog"
st.tag(text.split())
output: [('The', 'DT'), ('quick', 'JJ'), ('brown', 'JJ'), ('fox', 'NN'), ('jumps', 'VBZ'), ('over', 'IN'), ('the', 'DT'), ('lazy', 'JJ'), ('dog', 'NN')]

Библиотеки для NLP

NLTK (Natural Language ToolKit)[14]

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

Плюсы:

  • Наиболее известная и многофункциональная библиотека для NLP;
  • Большое количество сторонних расширений;
  • Быстрая токенизация предложений;
  • Поддерживается множество языков.

Минусы

  • Медленная;
  • Сложная в изучении и использовании;
  • Работает со строками;
  • Не использует нейронные сети;
  • Нет встроенных векторов слов.

spaCy[15]

Библиотека, разработанная по методологии SCRUM на языке Cypthon, позиционируется как самая быстрая NLP библиотека. Имеет множество возможностей, в том числе, разбор зависимостей на основе меток, распознавание именованных сущностей, пометка частей речи, векторы расстановки слов. Не поддерживает русский язык.

Плюсы:

  • Самая быстрая библиотека для NLP;
  • Простая в изучении и использовании;
  • Работает с объектами, а не строками;
  • Есть встроенные вектора слов;
  • Использует нейронные сети для тренировки моделей.

Минусы

  • Менее гибкая по сравнению с NLTK;
  • Токенизация предложений медленнее, чем в NLTK;
  • Поддерживает маленькое количество языков.

scikit-learn[16]

Библиотека scikit-learn разработана по методологии SCRUM и предоставляет реализацию целого ряда алгоритмов для обучения с учителем и обучения без учителя через интерфейс для Python. Построена поверх SciPy. Ориентирована в первую очередь на моделирование данных, имеет достаточно функций, чтобы использоваться для NLP в связке с другими библиотеками.

Плюсы:

  • Большое количество алгоритмов для построения моделей;
  • Содержит функции для работы с Bag-of-Words моделью;
  • Хорошая документация.

Минусы

  • Плохой препроцессинг, что вынуждает использовать ее в связке с другой библиотекой (например, NLTK);
  • Не использует нейронные сети для препроцессинга текста.

gensim[17]

Python библиотека, разработанная по методологии SCRUM, для моделирования, тематического моделирования документов и извлечения подобия для больших корпусов. В gensim реализованы популярные NLP алгоритмы, например, word2vec. Большинство реализаций могут использовать несколько ядер.

Плюсы:

  • Работает с большими датасетами;
  • Поддерживает глубокое обучение;
  • word2vec, tf-idf vectorization, document2vec.

Минусы

  • Заточена под модели без учителя;
  • Не содержит достаточного функционала, необходимого для NLP, что вынуждает использовать ее вместе с другими библиотеками.


Балто-славянские языки имеют сложную морфологию, что может ухудшить качество обработки текста, а также ограничить использование ряда библиотек. Для работы со специфичной русской морфологией можно использовать, например, морфологический анализатор pymorphy2[18] и библиотеку для поиска и извлечения именованных сущностей Natasha[19]

Примеры использования NLTK

  • Разбиение на предложения:
text = "Предложение. Предложение, которое содержит запятую. Восклицательный знак! Вопрос?" 
sents = nltk.sent_tokenize(text)
print(sents)
output: ['Предложение.', 'Предложение, которое содержит запятую.', 'Восклицательный знак!', 'Вопрос?']
  • Токенизация:
from nltk.tokenize import RegexpTokenizer
sent = "В этом предложении есть много слов, мы их разделим."
tokenizer = RegexpTokenizer(r'\w+')
print(tokenizer.tokenize(sent))
output: ['В', 'этом', 'предложении', 'есть', 'много', 'слов', 'мы', 'их', 'разделим']
from nltk import word_tokenize
sent = "В этом предложении есть много слов, мы их разделим."
print(word_tokenize(sent))
output: ['В', 'этом', 'предложении', 'есть', 'много', 'слов', ',', 'мы', 'их', 'разделим', '.']
  • Стоп слова:
from nltk.corpus import stopwords
stop_words=set(stopwords.words('english'))
print(stop_words)
output: {'should', 'wouldn', 'do', 'over', 'her', 'what', 'aren', 'once', 'same', 'this', 'needn', 'other', 'been', 'with', 'all' ...
  • Стемминг и лемматизация:
from nltk.stem.porter import PorterStemmer
porter_stemmer = PorterStemmer()
print(porter_stemmer.stem("crying"))
output: cri
from nltk.stem.lancaster import LancasterStemmer
lancaster_stemmer = LancasterStemmer()
print(lancaster_stemmer.stem("crying"))
output: cry
from nltk.stem import SnowballStemmer
snowball_stemmer = SnowballStemmer("english")
print(snowball_stemmer.stem("crying")) 
output: cri
from nltk.stem import WordNetLemmatizer
wordnet_lemmatizer = WordNetLemmatizer()
print(wordnet_lemmatizer.lemmatize("came", pos="v"))
output: come

Пример кода на языке Scala

Пример реализации алгоримтма NLP на основе Apache Spark ML[20].

См. также

Примечания

Источники информации

  1. [1] — статья на Википедии
  2. Natural Language Processing with Python — Analyzing Text with the Natural Language Toolkit
  3. Speech and Language Processing