Назад в библиотеку

ОБРАБОТКА ЕСТЕСТВЕННОГО ЯЗЫКА

Автор: Ю.А. Золушкин, Васяева  Т.A.
Источник:Материалы научно-практической конференции для молодых ученых Young scientists’ researches and achievements in science посвященной 100-летнему юбилею Донецкого национального технического университета. – Донецк: ДонНТУ, 2021. – C. 71-79.

Аннотация:

Золушкин Ю.А., Васяева Т.А. Обработка естественного языка. Разобраны основы обработки естественного языка для текста. Рассмотрены основы выделения признаков из текста, с целью дальнейшего использования их для алгоритмов машинного обучения. Выполнена реализация рассмотренного с применением Python-библиотеки NLTK.

Annotation:

Zolushkin Y.A., Vasyaeva T.A. Natural language processing. The basics of natural language processing for text are covered. The basics of feature extraction from text are considered, with their further use for machine learning algorithms. The implementation of what was considered with the use of the NLTK Python library has been completed.

Введение

В настоящее время задачи, связанные с обработкой естественного языка, возникают довольно часто. Задача распознавания речи присутствует в чат-ботах, фильтрации спама, машинном переводе, классификации документов, и т.д. В связи с чем в Artificial intelligence (AI) выделено отдельное направление Natural Language Processing.

Natural Language Processing (NLP) – обработка естественного языка – подраздел информационных технологий (ИТ) и искусственного интеллекта (ИИ), посвященный тому, как компьютеры анализируют естественные языки. NLP позволяет применять алгоритмы машинного обучения для текста и речи [1].

Постанока проблемы

Задача исследования состоит в том, чтобы изучить специфику работы с естественным языком, разработать и реализовать методику подготовки текста для применения моделей автоматизированного перевода в сфере IT-технологий. В дальнейшем планируется разработать нейросетевой русско-английский и англо-русский переводчик, ориентированный на указанную тематику.

Natural Language Processing

Обработка естественного языка предполагает выполнение следующих этапов:
- токенизация;
- нормализация;
- фильтрация;
- векторизация.

1. Токенизация – это процесс разделения текста на компоненты. В качестве таких компонент могут выступать предложения, слова или отдельные символы.

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

Два основных алгоритма нормализации это лемматизация и стемминг [2].

Стемминг–упрощенный алгоритм морфологического разбора слова, оптимизированный под максимально быстрое нахождение префикса, общего для всех грамматических форм заданного слова. Обычно получаемая при стемминге основа включает в себя морфологический корень, вместе с приставкой. У стеммера всегда есть некоторый процент ошибок, возникающих из особенностей словоизменения естественного языка и невозможности согласовать примитивную идею отсечения "окончаний" с русским словоизменением, а тем более с такими языковыми явлениями, как беглые гласные. В русском лексиконе примерно 1.7% словоформ имеют такую особенность, например, мешок-мешки, взять-возьму. Английский язык так же имеет обширный набор исключений из регулярных правил - неправильные глаголы, существительные, склоняющиеся не по общему правилу.

Лемматизация –более тонкий процесс, который использует словарь и морфологический анализ, целью которого является привести слово к его канонической форме – лемме.

3. Фильтрация. При анализе текста алгоритмами машинного обучения его лучше перевести в низкий регистр (за исключением собственных имен и аббревиатур), удалить знаки препинания, удалить неинформативные слова (стоп-слова).

Стоп-слова – это такие слова и фразы, которые удаляются без потери смысла. Стоп-слова, во время применения машинного обучения к текстам, могут добавить много шума, поэтому необходимо избавляться от нерелевантных слов.

4. Векторизация и извлечение признаков

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

Bag of words (мешок слов) – это популярная и простая техника извлечения признаков, используемая при работе с текстом. Создается вектор длиной в словарь, для каждого слова считается количество вхождений в текст, и это число подставляется на соответствующую позицию в векторе. При этом какая-либо информация о порядке слов в тексте отсутствует

Для такой модели нужно определить словарь и подсчитать вхождение слов. Когда размер словаря увеличивается, вектор документа тоже растет. Длина вектора равна количеству известных слов. В некоторых случаях может быть очень большой объем данных и тогда вектор может состоять из тысяч или миллионов элементов. Более того, каждый документ может содержать лишь малую часть слов из словаря. Как следствие, в векторном представлении будет много нулей. Векторы с большим количеством нулей называются разреженным векторами (sparse vectors), они требуют больше памяти и вычислительных ресурсов.

N-граммы – комбинации из n последовательных терминов для упрощения распознавания текстового содержание. Эта модель определяет и сохраняет смежные последовательности слов в тексте. Таким образом, это более сложный способ создания словаря.

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

Например, предложение «The cat sat on the mat» можно разложить на следующий набор 2-грамм:

{"The", "The cat", "cat", "cat sat", "sat", "sat on", "on", "on the", "the", "the mat", "mat"}

Также его можно разложить на такой набор 3-грамм:

{"The", "The cat", "cat", "cat sat", "The cat sat", "sat", "sat on", "on", "cat sat on", "on the", "the", "sat on the", "the mat", "mat", "on the mat"}

Такие наборы называют мешком биграмм или мешком триграмм соответственно.

Более того, когда создан словарь, следует оценить наличие слов. Самый простой, бинарный подход (1 – есть слово, 0 – нет слова). Есть и другие методы:

Количество.Подсчитывается, сколько раз каждое слово встречается в документе.

Частотность.Подсчитывается, как часто каждое слово встречается в тексте (по отношению к общему количеству слов);

TF-IDF (частота слова и обратная частота документа) — это показатель, который используется для оценки важности слова в документе.

TF (частота слов) характеризует отношение числа вхождений конкретного слова к общему набору слов в документе. Чем выше TF, тем весомее конкретное слово в рамках документа.

где числитель – вхождение слова в документ, знаменатель – общее число слов в документе.

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

где N – общее количество документов в коллекции, n(qi) – количество документов, содержащих слово qi.

Кодом слова будет являться произведение TF на IDF.

Если при работе с естественным языком предполагается использовать нейронные сети, то отсутствует необходимость в извлечении признаков. Соответственно векторизация заключается в представлении каждого токена в виде чисел: кода или вектора (one hot encoding или embedding).

Если каждому коду ставится в соответствие число можно использовать оценку наличия слов в тексте (количество, частота, TF-IDF).

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

One-hot encoding - является самым простым способом преобразования и выполняется следующим образом: каждый компонент представляет бинарный вектор (значения 0 или 1), единица ставится тому элементу, который соответствует номеру компонента в словаре [5].

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

Embedding – плотные векторные представления. Векторные представления слов являются малоразмерными векторами вещественных чисел. Каждому токену так же сопоставляется вектор, но его размерность существенно ниже чем у One-Hot Encoding.

Получить векторные представления можно двумя способами:
1. Конструировать векторные представления в процессе решения основной задачи (изначально создаются случайные векторы слов, которые затем обучаются).
2. Загрузить в модель векторные представления, полученные в результате другого машинного обучения.

Существуют хорошо распространенные предварительно обученные плотные векторные представления слов как для английского:
‒ GloVe (Global Vectors);
‒ Word2Vec, Google;
‒ FastText, Facebook.

Так и для русского языка:
‒ RusVectōrēs;
‒ RUSSE.

Реализация и экспериментальные исследования

В работе реализованы описанные методы обработки естественного языка. Реализация выполнена на языке программирования Python с использованием облачного сервиса на основе Jupyter Notebook – Google Colab. Тестирование выполнено на примере англоязычного текста (научная статья). Данный текст (рис.1) считывается с файла с расширением .docx.

Рисунок 1 – Фрагмент исходного текста

Обработка естественного языка выполняется с применением библиотеки nltk, а также дополнения данной библиотеки.

Токенизация

Выполним токенизацию [3] по предложениям с применением методов библиотеки nltk:
sentences = nltk.sent_tokenize(text)
for sentence in sentences:
     print(sentence)

Результатом токенизации по предложениям будет список, в котором каждое предложение будет элементом списка.

Следующие действия приведут к токенизации по словам:
words=[]
for sentence in sentences:
     words.append(nltk.word_tokenize(sentence))
print(words)

Таким образом, в результате токенизации, текст разбит на отдельные компоненты – предложения или слова (по необходимости).

Нормализация

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

Для сравнения этих двух методов, применим к полученным токенам методы стемминга и лемматизации:
Для реализации стемминга напишем функцию «compare_stemmer»:
def compare_stemmer(stemmer, word, pos):
     str1=stemmer.stem(word)
     return str1

Для её применения на примере нашего текста напишем код:
stemmer = PorterStemmer()
k=len(words)
S1=[]
for i in range(k):
     str1=[]
for word in words[i]:
     str1.append(compare_stemmer(stemmer, word, pos = wordnet.VERB))
S1.append(str1)
print(str1)
Аналогично напишем функцию для лемматизации «compare_lemmatizer»:
def compare_lemmatizer(lemmatizer, word, pos):
     str2=lemmatizer.lemmatize(word, pos)
     return str2
И приведем код для её использования:
lemmatizer = WordNetLemmatizer()
k=len(words)
S2=[]
for i in range(k):
     str2=[]
     for word in words[i]:
          str2.append(compare_lemmatizer(lemmatizer, word, pos = wordnet.VERB))
     S2.append(str2)
     print(str2)

Сравнивая результаты стемминга и лемматизации можно сделать вывод: алгоритм стемминга работает быстрее, но при этом есть случаи, когда слова теряют сове лексическое значение, например, существительные становятся глаголами (в тексте присутствует слово «information», после обработки стеммингом получилось слово «inform»), прилагательные становятся существительными (было слово «incoming», а получили «incom»), теряется время глагола (например, «reciev» - «receives»). В случае лемматизации все слова привелись к начальной форме, с сохранением времени глаголов, и слова не потеряли своего значения в тексте, что является очень полезным фактором для реализации нейронного переводчика.

Фильтрация

После нормализации слов, для уменьшения размера текста, следует удалить из текста неинформативные слова – стоп-слова (рис. 2). Библиотека NLTK имеет в себе список стоп-слов для английского языка. Чтобы просмотреть список стоп-слов, можно выполнить команду:

print(stopwords.words("english"))
Для удаления стоп-слов из текста, необходимо применить следующую функцию:
stop_words = set(stopwords.words("english"))
for sentence in sentences:
     words = nltk.word_tokenize(sentence)
     without_stop_words = [word for word in words if not word in stop_words]
     print(without_stop_words)

Рисунок 2 – Список стоп-слов английского языка

После удаления стоп-слов, текст стал короче и информативней. Кроме удаления стоп слов, необходимо удалить знаки препинания, привести к нижнему регистру. Выполнить это удобно используя регулярные выражения[4].

Регулярные выражения применяются не отдельно к словам, а полностью к предложениям. Напишем код для извлечения знаков пунктуации из текста, а также приведения к нижнему регистру:

pattern = r"[^\w]"
sentences = nltk.sent_tokenize(text)
for sentence in sentences:
     sent = re.sub(pattern, " ", sentence)
     sent = sent.lower()
     print(sent)

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

Предполагается работа с нейронной сетью, поэтому задача извлечения признаков перед нами не стоит. Выполним векторизацию текста методами: one hot encoding и embedding (рис. 3).

One hot encoding

Представим наш текст в виде one hot encoding:
values = array(data)
label_encoder = LabelEncoder()
integer_encoded = label_encoder.fit_transform(data)
onehot_encoder = OneHotEncoder(sparse=False)
integer_encoded = integer_encoded.reshape(len(integer_encoded), 1)
onehot_encoded = onehot_encoder.fit_transform(integer_encoded)
print(onehot_encoded)

Рисунок 3 – Векторизация текста в формат one hot encoding

Данная реализация кодирует каждое слово в вектор, где только одна позиция равна единице.

Embedding

Пример использования плотных векторных представлений рассмотрен на примере уже готовых векторных представлений word2vec [6]. Работа программы осуществляется следующим образом: word2vec принимает большой текстовый корпус в качестве входных данных и сопоставляет каждому слову вектор, выдавая координаты слов на выходе. Сначала он генерирует словарь корпуса, а затем вычисляет векторное представление слов, «обучаясь» на входных текстах. Векторное представление основывается на контекстной близости: слова, встречающиеся в тексте рядом с одинаковыми словами (а следовательно, имеющие схожий смысл), будут иметь близкие (по косинусному расстоянию) векторы. Напишем функцию для использования word2vec:

def get_embeddings_(self, tokens):
     embeddings = [word2vec.get_vector(w) for w in tokens if w in word2vec]
     mean = np.mean(word2vec.vectors, 0)
     std = np.std(word2vec.vectors, 0)
     embeddings = [(word2vec.get_vector(w) - mean) / std for w in tokens if w in word2vec and len(w) > 3]
          if len(embeddings) == 0:
     embeddings = np.zeros((1, self.word2vec.vector_size))
     else:
          embeddings = np.array(embeddings)
     if len(embeddings.shape) == 1:
     embeddings = embeddings.reshape(-1, 1)
     return embeddings

Рисунок 4 – Представление текста в формате word2vec

Данный метод кодирует слова не в бинарном представлении, а в веществом. Такое представление уменьшает длину вектора слова.

Выводы

В данной статье последовательно рассмотрены этапы обработки естественного языка: токенизация, нормализация, фильтрация, векторизация.

Так как переводчик представляет отдельные слова в виде идентификаторов, которые никак не отражают взаимосвязи между ними, то было решено использовать нейронные сети. Проведен детальный анализ методов преобразования слов, таких как Embedding и One-hot encoding. Для решения задачи нейронного переводчика был выбрано векторное представление слов Embedding, так как векторы формируются при обучении нейронной сети и учитывают взаимосвязи между словами. Выбран алгоритм нормализации - лемматизация, потому что данный алгоритм приводит слова к начальной форме без потери значения слов.

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

Список использованной литературы

1. Обработка естественного языка в Python. Основы. [Electronic resource] // Интернет-ресурс. – Режим доступа: www/ URL: https://nuancesprog.ru/p/5870/
2. Основы Natural Language Processing для текста [Electronic resource] // Интернет-ресурс. – Режим доступа: www/ URL:https://habr.com/ru/company/Voximplant/blog/446738/
3. Плавное введение в Natural Language Processing [Electronic resource] // Интернет-ресурс. – Режим доступа: www/ URL:https://datastart.ru/blog/read/plavnoe-vvedenie-v-natural-language-processing-nlp\
4. Регулярные выражения в Python: теория и практика. [Electronic resource] / Интернет-ресурс. – Режим доступа: www/ URL: https://tproger.ru/translations/regular-expression-python/
5. Мюллер А., Сара Гвидо. Введение в машинное обучение с помощью Python [Electronic resource] / Интернет-ресурс - Режим доступа: www/ URL: https://timofey.pro/static/pdfdocs/AI_001_myuller_gvido_vvedenie_ML.pdf
6. Scikit-learn. Machine Learning in Python [Electronic resource] / Интернет-ресурс. – Режим доступа: www/ URL: https://scikit-learn.org/stable/