Основы обработки естественного языка за 10 минут

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

Первым делом следует:

1. Установить зависимости (Python версии 3.7 или выше).

2. Скачать IDE или установить Jupyter Notebook.

Чтобы установить Jupyter Notebook, добавьте в командную строку pip install jupyter-notebook, а затем введите jupyter notebook, чтобы запустить его. После этого откроется страница с программой по локальному адресу http://127.0.0.1:8888/token.

3. Установить модули

Для этого введите команду pip install nltk.

NLTK  —  это библиотека Python, которая используется для выполнения всех процессов NLP, таких как выделение основ слов, лемматизация (приведение слова к начальной форме) и др.

В этой статье будут рассмотрены следующие процессы:

1. Токенизация.

2. Стоп-слова.

3. Выделение основы слова.

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

5. Создание базы слов.

6. Маркировка частей речи.

7. Построение цепочек слов.

Но прежде всего разберёмся, что же такое NLP.

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

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

Теперь, когда у нас есть понимание того, что такое NLP, приступим к изучению каждого из её процессов.

1. Токенизация

Токенизация  —  это процесс разделения целого текста на токены (отдельные кусочки). Её делят на 2 типа:

  • Токенизация слов.
  • Токенизация предложений.
import nltk
from nltk.tokenize import sent_tokenize, word_tokenize
example_text = "Hello there, how are you doing today? The weather is great today. The sky is blue. python is awesome"
print(sent_tokenize(example_text))
print(word_tokenize(example_text))

В представленном выше коде мы сначала импортируем модуль nltk, а во второй строчке импортируем токенизаторы sent_tokenize и word_tokenize из библиотеки nltk.tokenize, чтобы затем передать им в качестве параметра исходный текст.

Конечный вариант будет выглядеть вот так:

##sent_tokenize (разделены по предложениям)
['Hello there, how are you doing today?', 'The weather is great today.', 'The sky is blue.', 'python is awesome']

['Hello', 'there', ',', 'how', 'are', 'you', 'doing', 'today', '?', 'The', 'weather', 'is', 'great', 'today', '.', 'The', 'sky', 'is', 'blue', '.', 'python', 'is', 'awesome']

2. Стоп-слова

Стоп-слова  —  это такие слова, которые присутствуют в любом языке и не привносят никакой полезной информации в предложение. В NLP стоп-слова образуют список слов, не важных при анализе данных.

Примеры стоп-слов: «он», «она», «есть» и др.

Наша задача  —  удалить все стоп-слова из текста, чтобы продолжить дальнейшую обработку.

В английском языке насчитывается 179 стоп-слов. Посмотреть их можно в библиотеке NLTK.

Импортируем модуль stopwords из библиотеки nltk.corpus.

from nltk.corpus import stopwords
print(stopwords.words('english'))

######################
#######ВЫВОД##########
######################
['i', 'me', 'my', 'myself', 'we', 'our', 'ours', 'ourselves', 'you', "you're", "you've", "you'll", "you'd", 'your', 'yours', 'yourself', 'yourselves', 'he', 'him', 'his', 'himself', 'she', "she's", 'her', 'hers', 'herself', 'it', "it's", 'its', 'itself', 'they', 'them', 'their', 'theirs', 'themselves', 'what', 'which', 'who', 'whom', 'this', 'that', "that'll", 'these', 'those', 'am', 'is', 'are', 'was', 'were', 'be', 'been', 'being', 'have', 'has', 'had', 'having', 'do', 'does', 'did', 'doing', 'a', 'an', 'the', 'and', 'but', 'if', 'or', 'because', 'as', 'until', 'while', 'of', 'at', 'by', 'for', 'with', 'about', 'against', 'between', 'into', 'through', 'during', 'before', 'after', 'above', 'below', 'to', 'from', 'up', 'down', 'in', 'out', 'on', 'off', 'over', 'under', 'again', 'further', 'then', 'once', 'here', 'there', 'when', 'where', 'why', 'how', 'all', 'any', 'both', 'each', 'few', 'more', 'most', 'other', 'some', 'such', 'no', 'nor', 'not', 'only', 'own', 'same', 'so', 'than', 'too', 'very', 's', 't', 'can', 'will', 'just', 'don', "don't", 'should', "should've", 'now', 'd', 'll', 'm', 'o', 're', 've', 'y', 'ain', 'aren', "aren't", 'couldn', "couldn't", 'didn', "didn't", 'doesn', "doesn't", 'hadn', "hadn't", 'hasn', "hasn't", 'haven', "haven't", 'isn', "isn't", 'ma', 'mightn', "mightn't", 'mustn', "mustn't", 'needn', "needn't", 'shan', "shan't", 'shouldn', "shouldn't", 'wasn', "wasn't", 'weren', "weren't", 'won', "won't", 'wouldn', "wouldn't"]

А вот как удалить стоп-слова из заданного текста:

from nltk.corpus import stopwords
text = 'he is a good boy. he is very good in coding'
text = word_tokenize(text)
text_with_no_stopwords = [word for word in text if word not in stopwords.words('english')]
text_with_no_stopwords

##########ВЫВОД##########
['good', 'boy', '.', 'good', 'coding']

3. Выделение основы слова

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

В Python для выделения основы есть специальный модуль PorterStemmer . Он импортируется в проект из библиотеки nltk.stem.

Следует помнить, что выделение основы лучше всего работает с одиночными словами.

from nltk.stem import PorterStemmer
ps = PorterStemmer()    ## создаём объект для PorterStemmer
example_words = ['earn',"earning","earned","earns"]  ##слова для примера

for w in example_words:
    print(ps.stem(w))   ##выделяем корни слов, используя ps

##########ВЫВОД##########
earn
earn
earn
earn

Здесь мы видим, что слова "earning", "earned" и "earns" являются однокоренными к слову "earn".

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

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

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

from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer() ## создаём объект для WordNetLemmatizer
example_words = ['history','formality','changes']
for w in example_words:
    print(lemmatizer.lemmatize(w))

#########ВЫВОД############
----Lemmatizer-----
history
formality
change
-----Stemming------
histori
formal
chang

5. WordNet

WordNet  —  это лексикологическая база, то есть словарь английского языка, созданный специально для обработки естественного языка. С помощью wordnet можно подбирать синонимы и антонимы.

В Python этот модуль импортируется из nltk.corpus.

Код для нахождения синонимов или антонимов к слову:

from nltk.corpus import wordnet

synonyms = []   ## создаём пустой список всех синонимов
antonyms =[]    ## создаём пустой список всех антонимов

for syn in wordnet.synsets("happy"): ## загружаем слово
    for i in syn.lemmas():         ## находим все соответств. леммы
        synonyms.append(i.name())  ## добавляем все синонимы
        if i.antonyms():
            antonyms.append(i.antonyms()[0].name()) ## антонимы
print(set(synonyms)) ## преобразуем их в множество 
                     ## уникальных значений
print(set(antonyms))

#########ВЫВОД##########
{'felicitous', 'well-chosen', 'happy', 'glad'}
{'unhappy'}

6. Маркировка частей речи

Маркировка частей речи  —  это процесс преобразования предложения в формы, то есть в список слов или кортежей (каждый кортеж имеет вид [слово, часть речи]). Маркировочные символы здесь рассматриваются как сокращение названий маркированных частей речи и обозначают, является ли слово существительным, прилагательным, глаголом или какой-то ещё частью речи.

Список маркированных частей речи:

CC coordinating conjunction (соединительный союз)
 CD cardinal digit(количественное числительное)
 DT determiner(определяемое слово)
 EX existential there (локатив)
 FW foreign word(иностранное слово)
 IN preposition/subordinating conjunction(предлог/подчинительный союз)
 JJ adjective(прилагательное)
 JJR adjective, comparative(прилагательное сравнит. степени)
 JJS adjective, superlative(прилагательное превосходной степени)
 LS list marker(пункт списка)
 MD modal(модальный глагол)
 NN noun(существительное)
 NNS noun plural(множ. число существительного)
 NNP proper noun, singular (имя собственное)
 NNPS proper noun, plural(имя собственное в множ. числе)
 PDT predeterminer(предетерминатив - слово, стоящее перед определением)
 POS possessive ending(притяжательное окончание)
 PRP personal pronoun(личное местоимение)
 PRP possessive pronoun(притяжательное местоимение)
 RB adverb(наречие)
 RBR adverb, comparative(наречие сравнительной степени)
 RBS adverb, superlative(наречие превосходной степени)
 RP particle(частица)
 TO to go 'to' the store(частица TO)
 UH interjection(междометие)
 VB verb, base form(глагол наст. времени)
 VBD verb, past tense(глагол прошедшего времени)
 VBG verb, gerund/present(глагол-герундий)
 VBN verb, past participle(глагол времени perfect)
 VBP verb, sing. present, non-3d(глагол ед. ч. наст. вр.)
 VBZ verb, 3rd person sing. present(глагол наст. вр. 3 лица)
 WDT wh-determiner(определение с wh-)
 WP wh-pronoun(вопросительное слово с w-)
 WP possessive wh-pronoun(притяжательное местоимение с wh-)
 WRB wh-abverb(наречие с wh-)

В Python для выделения меток частей речи используется модуль nltk.pos_tag.

import nltk

nltk.download('averaged_perceptron_tagger')

sample_text = '''
An sincerity so extremity he additions. Her yet there truth merit. Mrs all projecting favourable now unpleasing. Son law garden chatty temper. Oh children provided to mr elegance marriage strongly. Off can admiration prosperous now devonshire diminution law.
'''

from nltk.tokenize import word_tokenize
words = word_tokenize(sample_text)

print(nltk.pos_tag(words))
##########ВЫВОД############
[('An', 'DT'), ('sincerity', 'NN'), ('so', 'RB'), ('extremity', 'NN'), ('he', 'PRP'), ('additions', 'VBZ'), ('.', '.'), ('Her', 'PRP$'), ('yet', 'RB'), ('there', 'EX'), ('truth', 'NN'), ('merit', 'NN'), ('.', '.'), ('Mrs', 'NNP'), ('all', 'DT'), ('projecting', 'VBG'), ('favourable', 'JJ'), ('now', 'RB'), ('unpleasing', 'VBG'), ('.', '.'), ('Son', 'NNP'), ('law', 'NN'), ('garden', 'NN'), ('chatty', 'JJ'), ('temper', 'NN'), ('.', '.'), ('Oh', 'UH'), ('children', 'NNS'), ('provided', 'VBD'), ('to', 'TO'), ('mr', 'VB'), ('elegance', 'NN'), ('marriage', 'NN'), ('strongly', 'RB'), ('.', '.'), ('Off', 'CC'), ('can', 'MD'), ('admiration', 'VB'), ('prosperous', 'JJ'), ('now', 'RB'), ('devonshire', 'VBP'), ('diminution', 'NN'), ('law', 'NN'), ('.', '.')]

7. Словарный набор

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

Для преобразования данных в вектор используются специальные Python-библиотеки.

Вот как работает векторное преобразование:

sent1 = he is a good boy
sent2 = she is a good girl
sent3 = boy and girl are good 
        |
        |
  После удаления стоп-слов, лемматизации и выделения корней слов
sent1 = good boy
sent2 = good girl
sent3 = boy girl good  
        | ### Теперь подсчитаем частоту каждого слова 
        |     путём вычисления появления слов в предложении
Частота слов
good     3
boy      2
girl     2
         | ## Теперь, согласно их появлению в предложениях, мы 
         |    присвоим каждому слову значения 1 или 0
         |    соответственно их появлению в предложении
         | ## 1 за присутствие и 0 за отсутствие
         
         f1  f2   f3
        girl good boy   
sent1    0    1    1     
sent2    1    0    1
sent3    1    1    1
### После этого мы передадим форму вектора модели машинного обучения

Процесс выше выполняется с помощью модуля CountVectorizer, он импортируется из модуля sklearn.feature_extraction.text.

Код для внедрения модуля CountVectorizer в Python:

import pandas as pd
sent = pd.DataFrame(['he is a good boy', 'she is a good girl', 'boy and girl are good'],columns=['text'])
corpus = []
for i in range(0,3):
    words = sent['text'][i]
    words  = word_tokenize(words)
    texts = [lemmatizer.lemmatize(word) for word in words if word not in set(stopwords.words('english'))]
    text = ' '.join(texts)
    corpus.append(text)
print(corpus)   #### очищенные данные

from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer() ## создаём объект для CountVectorizer
X = cv.fit_transform(corpus).toarray()
X  ## векторная форма

##########ВЫВОД##########
['good boy', 'good girl', 'boy girl good']
array([[1, 0, 1],
       [0, 1, 1],
       [1, 1, 1]], dtype=int64)

Поздравляю, теперь вы разбираетесь в основах обработки естественного языка в Python!

Читайте также:

Читайте нас в TelegramVK и Яндекс.Дзен


Перевод статьи Abhay Parashar: Basics Of Natural Language Processing in 10 Minutes

Предыдущая статьяАвтоматическое масштабирование CI с помощью Kraken CI
Следующая статья13 трендов в типографике в 2021 году