ОБРАБОТКА ЕСТЕСТВЕННОГО ЯЗЫКА (ЧАСТЬ II)
Далее это часть серии статей о НЛП. (Отметьте Часть I и Часть III)
Как мы видели в предыдущей статье, НЛП предоставляет интересные возможности, которые сегодня меняют многие отрасли. Круто, что компьютер может так много, но как ему это удается? О да, вы поняли, мы собираемся погрузиться в некоторые серьезные вещи!
Структура НЛП
Мы собираемся шаг за шагом построить структуру обработки естественного языка, и к концу этого «учебника» вы сможете построить свою собственную модель НЛП. Давайте начнем!

Прежде всего, давайте посмотрим на этот фрагмент текста. Это цитата Билла Гейтса, и она одна из моих любимых. Было бы здорово, если бы мой компьютер мог прочитать эту цитату и особенно «понять» ее, не так ли? Чтобы попасть туда, нам нужно применить пару шагов.

Предварительная обработка данных
Предварительная обработка данных считается самой раздражающей частью работы, потому что она технически непривлекательна и относительно трудоемка, но все же важна. Среди специалистов по данным есть известное высказывание: Мусор на входе, мусор на выходе. Это означает, что если вы снабдите свою модель машинного обучения грязными данными, она отбросит их прямо вам в лицо (извините 😊). Другими словами, это даст вам бессмысленные результаты. Достаточно справедливо, верно? Поэтому эта часть работы должна быть тщательно проделана.
Обычно при работе со структурированными данными предварительная обработка данных часто включает удаление повторяющихся данных, значений NULL и ошибок. Когда дело доходит до текстовых данных, существует множество распространенных методов предварительной обработки данных, также известных как методы очистки текста.
Чтобы применить методы предварительной обработки, мы будем использовать очень мощную библиотеку Python: NLTK: Natural Language ToolKit. NLTK предоставляет набор библиотек обработки текста для классификации, токенизации, выделения корней, тегов и т. д. Подождите, мы собираемся увидеть все эти функции вместе через пару минут. Быть в курсе!
• Сегментация предложений
По сути, это акт разделения нашего текста на отдельные предложения. В нашем случае мы получим следующее:
1. «Я могу понять желание иметь миллионы долларов, с этим приходит определенная свобода, осмысленная свобода».
2. «Но как только вы добьетесь большего, я должен вам сказать, что это тот же самый гамбургер».
3. «Билл Гейтс — председатель и основатель Microsoft»
В этом случае мы можем предположить, что каждое предложение представляет собой отдельную идею. В результате будет намного проще разработать алгоритм, который понимает одно предложение, а не весь абзац.
• Токенизация
Теперь разобьем наш текст на предложения, давайте еще лучше и разобьем на слова, или правильнее «токены».
Например, начнем с первого предложения из нашей цитаты:
"Я понимаю, что хочу иметь миллионы долларов. С этим приходит определенная свобода, осмысленная свобода".
После применения токенизации это будет выглядеть следующим образом:
«Я», «могу», «понимаю», «хочу», «иметь», «миллионы», «из», «доллары», «», «есть», «а» , «определенный», «свобода», «», «значимый», «свобода», «,», «это», «приходит», «с», «это», «.»
text = '''I can understand wanting to have millions of dollars, there’s a certain freedom, meaningful freedom, that comes with that. But once you get much beyond that, I have to tell you, it’s the same hamburger. Bill Gates — Chairman & Founder of Microsoft''' #Import NLTK Library import nltk #Segmentation nltk.tokenize.sent_tokenize(text) #Tokenization nltk.tokenize.word_tokenize(text)
• Удаление текста
Если вы думаете о том же, что и я, то вы ошибаетесь... но мы все равно собираемся снять несколько вещей.
✓ Сделайте текст строчными: это своего рода контрольная точка нормализации, чтобы избежать количества символов, с которыми мы имеем дело.
✓ Расширение сокращений: Неформальный английский полон сокращений, которые следует заменить, всегда пытаясь нормализовать наш текст, насколько это возможно.
Например, в нашей цитате «есть» будет заменено на «есть».
Я нашел используемый ниже cList на StackOverFlow.
###Make text lowercase & Expand contractions
#Load English contracted/expanded words list from a .py file
from contractions import cList
# Compile a regular expression pattern for matching
import re
c_re = re.compile('(%s)' % '|'.join(cList.keys()))
#Create a function to look for contractions and replace them with their full form
#Put text in lowercase to make sure all words are included
def expandContractions(text, c_re=c_re):
def replace(match):
return cList[match.group(0)]
return c_re.sub(replace, text.lower())
#Notice it's a bit grammatically incorrect, but it doesn't matter since we gonna remove the stopwords later
expanded_text = expandContractions(text)
P.S. Обратите внимание, что это немного грамматически неправильно, но это не имеет значения, так как мы удалим стоп-слова позже 😉
✓ Удалите знаки препинания. Знаки препинания представляют собой нежелательные символы, поэтому давайте их удалим.
###Remove punctuations
#Import string library
import string
#Create a function to remove punctuation / special characters '!"#$%&\'()*+,-./:;<=>?#@[\\]^_`{|}~'
def clean_text(text):
text = re.sub('[%s]' % re.escape(string.punctuation), '', text)
return text
✓ Правописание: идея проста; мы собираемся использовать большой корпус в качестве эталона для правильного написания слов в нашем тексте.
✓ Удалить стоп-слова. Стоп-слова — это часто используемые слова, которые не несут никакой дополнительной важной информации к сообщению, которое содержит каждый текст. Большинство распространенных стоп-слов являются определителями (например, the, a, an), предлогами (например, выше, через, перед) и некоторыми прилагательными (например, хороший, хороший). Выгоним их!
Я могу понять желаниеиметь миллионыдолларов, существует определенная свобода,значимая свобода, которая приходитс этим.
Но как только вы добьётесь гораздо большего этого, я долженсказатьвам, что это тот же самыйгамбургер.
Билл Гейтс — председатель & Основателькомпании Microsoft
###Remove stopwords
#nltk.download('stopwords')
from nltk.corpus import stopwords
#Create a function to remove stopwords
def remove_stopwords (sentence = None):
words = sentence.split()
stopwords_list = stopwords.words("english")
clean_words = []
for word in words:
if word not in stopwords_list:
clean_words.append(word)
return ' '.join(clean_words);

✓ Часть фильтрации речи: цель состоит в том, чтобы определить лексическую категорию каждого слова, присвоив ему тег: Глагол, Прилагательное, Существительное, Наречие, Местоимение, Предлог…
###Part of Speech Tagger
#nltk.download('averaged_perceptron_tagger')
import nltk
from nltk import pos_tag, word_tokenize
#Create a function to pull out nouns & adjectives from text
def nouns_adj(text):
is_noun_adj = lambda pos: pos[:2] == 'NN' or pos[:2] == 'JJ'
tokenized = word_tokenize(text)
nouns_adj = [word for (word, pos) in pos_tag(tokenized) if
is_noun_adj(pos)]
return ' '.join(nouns_adj)
#Return list of tuple [word; PoS]
tokens = word_tokenize(clean_text_sw)
tuple_list = nltk.pos_tag(tokens)

✓ Лемматизация текста. В большинстве языков слова могут появляться в разных формах. Было бы интересно заменить каждое слово его базовой формой, чтобы наш компьютер мог понять, что разные предложения могут говорить об одном и том же понятии. Итак, давайте LLAMAtize нашу цитату!
В нашем случае: «Я могу понять желание иметь миллионы долларов».
становится «Я понимаю, что [хочу] иметь [миллион] [долларов]».
###Lemmatization
#nltk.download('wordnet')
#Lemmatize text with appropriate POS tag
from nltk.stem import WordNetLemmatizer
from nltk.corpus import wordnet
#Create a function to map NLTK's POS tags to the format wordnet lemmatizer would accept
def get_wordnet_pos(word):
tag = nltk.pos_tag([word])[0][1][0].upper()
tag_dict = {"J": wordnet.ADJ,
"N": wordnet.NOUN,
"V": wordnet.VERB,
"R": wordnet.ADV}
return tag_dict.get(tag, wordnet.NOUN)
#Create an instance of the WordNetLemmatizer()
lemmatizer = WordNetLemmatizer()
#Create a function to return text after lemmatization
def lemmatize_text(text):
lemm_text = [lemmatizer.lemmatize(w, get_wordnet_pos(w)) for w in nltk.word_tokenize(clean_text_sw)]
return ' '.join(lemm_text)
✓ Распознавание именованных объектов: это процесс, в котором алгоритм берет строку текста (предложение или абзац) в качестве входных данных и идентифицирует соответствующие существительные (люди, места, организации и т. д.), которые упоминаются в эта строка.
###Named Entity recognition
#nltk.download('maxent_ne_chunker')
#nltk.download('words')
from nltk import ne_chunk
#Create a function to tokenize and PoS your text
def NER(text):
text = nltk.tokenize(text)
text = nltk.pos_tag(text)
return text
text_NER = NER(text)
pos_list = ne_chunck(text_NER)
