NLP: когда машины начинают понимать нас (Часть 2)
1. Введение
В прошлой статье мы с вами изучили теоретические основы обработки естественного языка (NLP) и теперь готовы перейти к практике. В мире NLP выбор подходящего языка программирования и инструментов играет ключевую роль в успешной реализации проектов. Одним из наиболее популярных языков для решения задач в этой области является Python. Его простота, читаемость и поддержка мощных библиотек делают его идеальным выбором для разработчиков.
2. Начало работы с NLP
Для начала работы с обработкой естественного языка идеально подойдут Jupyter Lab и Google Colab, так как они позволяют быстро выполнять и тестировать код по частям.
Перед тем как приступить к написанию кода, необходимо установить несколько ключевых библиотек, которые значительно упростят работу в области NLP:
nltk: Natural Language Toolkit — это основная библиотека для обработки естественного языка на Python, предоставляющая доступ ко множеству инструментов и ресурсов для работы с текстовыми данными.
spaCy: Современная и высокопроизводительная библиотека, идеально подходящая для продвинутой обработки текста, включая функции для токенизации и анализа зависимости.
gensim: Библиотека, используемая для тематического моделирования и работы с моделями на основе тем. Она позволяет эффективно обучать и применять модели, использующие векторные представления слов.
scikit-learn: Широко используемая библиотека ML, которая включает множество алгоритмов для классификации, регрессии и кластеризации. Она также предоставляет инструменты для оценки и выбора моделей.
transformers: Библиотека от Hugging Face, позволяющая работать с современными моделями трансформеров, такими как BERT и GPT. Эта библиотека стала стандартом для многих современных приложений в области NLP.\
TensorFlow/Keras или PyTorch: Это фреймворки для глубокого обучения, которые позволяют разрабатывать и обучать нейронные сети для решения сложных задач в NLP.
Чтобы установить все перечисленные библиотеки, выполните следующую команду в терминале:
pip install nltk
pip install gensim
pip install scikit-learn
pip install transformers
pip install tensorflow
pip install keras
pip install torch torchvision torchaudio
pip install -U pip setuptools wheel
pip install -U spacy
После установки spaCy необходимо загрузить языковую модель:
python -m spacy download en_core_web_sm
python -m spacy download ru_core_news_sm
3. Первые шаги с NLTK
Мы будем использовать предложение:
Хабр — это лучший сайт для написания статей, постов и новостей! Всем обязательно советую данную платформу. Она помогает делиться знаниями и узнавать новое.
3.1 Загрузка и чтение текстовых данных
import nltk
# Загрузка необходимых пакетов
nltk.download('punkt') # Токенизация
nltk.download('stopwords') # Стоп-слова
nltk.download('wordnet') # Лемматизация
nltk.download('omw-1.4') # Дополнительные данные для лемматизации
nltk.download('averaged_perceptron_tagger') # POS-теггирование
# Наш текст, с которым мы будем работать
text = "Хабр — это лучший сайт для написания статей, постов и новостей! Всем обязательно советую данную платформу. Она помогает делиться знаниями и узнавать новое."
3.2 Токенизация
Токенизация — процесс разбиения текста на отдельные элементы (токены), такие как слова или предложения.
from nltk.tokenize import sent_tokenize, word_tokenize
# Токенизация на предложения
sentences = sent_tokenize(text, language='russian')
print("Предложения:", sentences)
# Токенизация на слова
words = word_tokenize(text, language='russian')
print("Слова:", words)
Вывод:
Предложения: ['Хабр — это лучший сайт для написания статей, постов и новостей!', 'Всем обязательно советую данную платформу.', 'Она помогает делиться знаниями и узнавать новое.'] Слова: ['Хабр', '—', 'это', 'лучший', 'сайт', 'для', 'написания', 'статей', ',', 'постов', 'и', 'новостей', '!', 'Всем', 'обязательно', 'советую', 'данную', 'платформу', '.', 'Она', 'помогает', 'делиться', 'знаниями', 'и', 'узнавать', 'новое', '.']
3.3 Стемминг
Стемминг — процесс приведения слов к их корню (основе), часто без учета языковых правил.
from nltk.stem.snowball import SnowballStemmer
# Создание стеммера для русского языка
stemmer = SnowballStemmer("russian")
# Применение стеммера к словам
stemmed_words = [stemmer.stem(word) for word in words]
print("После стемминга:", stemmed_words)
Вывод:
После стемминга: ['хабр', '—', 'это', 'лучш', 'сайт', 'для', 'написан', 'стат', ',', 'пост', 'и', 'новост', '!', 'всем', 'обязательн', 'совет', 'данн', 'платформ', '.', 'она', 'помога', 'дел', 'знан', 'и', 'узнава', 'нов', '.']
3.4 Лемматизция
Лемматизация — процесс приведения слов к их нормальной форме (лемме) с учетом контекста и грамматических правил.
Для русского языка в NLTK лемматизация ограничена, поэтому часто используют библиотеку pymorphy2
.
pip install pymorphy2
import pymorphy2
morph = pymorphy2.MorphAnalyzer()
lemmatized_words = [morph.parse(word)[0].normal_form for word in words]
print("После лемматизации:", lemmatized_words)
Вывод:
После лемматизации: ['хабр', '—', 'это', 'хороший', 'сайт', 'для', 'написание', 'статья', ',', 'пост', 'и', 'новость', '!', 'весь', 'обязательно', 'советовать', 'данный', 'платформа', '.', 'она', 'помогать', 'делиться', 'знание', 'и', 'узнавать', 'новый', '.']
3.5 Удаление стоп-слов
Стоп-слова — это часто встречающиеся слова, которые обычно не несут смысловой нагрузки (например, «и», «в», «на»).
from nltk.corpus import stopwords
# Получение списка стоп-слов для русского языка
stop_words = set(stopwords.words('russian'))
# Фильтрация слов
filtered_words = [word for word in lemmatized_words if word.lower() not in stop_words and word.isalpha()]
print("После удаления стоп-слов:", filtered_words)
Вывод:
После удаления стоп-слов: ['хабр', 'хороший', 'сайт', 'написание', 'статья', 'пост', 'новость', 'обязательно', 'советовать', 'данный', 'платформа', 'помогать', 'делиться', 'знание', 'узнавать', 'новый']
3.6 Part-of-Speech (POS) теггирование
POS-теггирование — процесс определения грамматической категории (части речи) для каждого слова в тексте.
NLTK имеет ограниченную поддержку русского языка для POS-теггирования. Поэтому используем библиотеку natasha
.
pip install natasha
from natasha import Doc, MorphVocab, NewsEmbedding, NewsMorphTagger, Segmenter
# Инициализация компонентов
segmenter = Segmenter()
embedding = NewsEmbedding()
morph_tagger = NewsMorphTagger(embedding)
morph_vocab = MorphVocab()
# Обработка текста
doc = Doc(text)
doc.segment(segmenter)
doc.tag_morph(morph_tagger)
# Вывод результатов
for token in doc.tokens:
token.lemmatize(morph_vocab)
print(f"{token.text} -> {token.lemma} ({token.pos})")
Пример вывода:
Хабр -> хабрый (PROPN) — -> — (PUNCT) это -> это (PART) лучший -> хороший (ADJ) сайт -> сайт (NOUN) для -> для (ADP) написания -> написание (NOUN) статей -> стать (NOUN) , -> , (PUNCT) постов -> пост (NOUN) и -> и (CCONJ) новостей -> новость (NOUN) ! -> ! (PUNCT) Всем -> весь (PRON) обязательно -> обязательно (ADV) советую -> советовать (VERB) данную -> данный (ADJ) платформу -> платформа (NOUN) . -> . (PUNCT) Она -> она (PRON) помогает -> помогать (VERB) делиться -> делиться (VERB) знаниями -> знание (NOUN) и -> и (CCONJ) узнавать -> узнавать (VERB) новое -> новый (ADJ) . -> . (PUNCT)
3.7 Примеры кода и упражнения
Напишем функцию, которая принимает текст на русском языке и выполняет следующие операции:
Токенизация предложений и слов.
Лемматизация слов.
Удаление стоп-слов.
Возвращает очищенный список слов.
def preprocess_text(text):
# Токенизация на слова
words = word_tokenize(text, language='russian')
# Лемматизация
lemmatized_words = [morph.parse(word)[0].normal_form for word in words]
# Удаление стоп-слов и знаков пунктуации
filtered_words = [word for word in lemmatized_words if word.lower() not in stop_words and word.isalpha()]
return filtered_words
# Применение функции
clean_words = preprocess_text(text)
print(clean_words)
Вывод:
['хабр', 'хороший', 'сайт', 'написание', 'статья', 'пост', 'новость', 'обязательно', 'советовать', 'данный', 'платформа', 'помогать', 'делиться', 'знание', 'узнавать', 'новый']
4. Работа со spaCy
4.1 Загрузка и обработка текста с помощью пайплайнов
import spacy
# Загрузка модели для русского языка
nlp = spacy.load('ru_core_news_sm')
# Обработка текста
doc = nlp(text)
4.2 Токенизация, лемматизация, POS-тегирование в spaCy
for token in doc:
print(f"Слово: {token.text}, Лемма: {token.lemma_}, Часть речи: {token.pos_}")
Вывод:
Слово: Хабр, Лемма: хабр, Часть речи: PROPN Слово: —, Лемма: —, Часть речи: PUNCT Слово: это, Лемма: это, Часть речи: PART Слово: лучший, Лемма: хороший, Часть речи: ADJ Слово: сайт, Лемма: сайт, Часть речи: NOUN Слово: для, Лемма: для, Часть речи: ADP Слово: написания, Лемма: написание, Часть речи: NOUN Слово: статей, Лемма: стать, Часть речи: NOUN Слово: ,, Лемма: ,, Часть речи: PUNCT Слово: постов, Лемма: пост, Часть речи: NOUN Слово: и, Лемма: и, Часть речи: CCONJ Слово: новостей, Лемма: новость, Часть речи: NOUN Слово: !, Лемма: !, Часть речи: PUNCT Слово: Всем, Лемма: всем, Часть речи: PRON Слово: обязательно, Лемма: обязательно, Часть речи: ADV Слово: советую, Лемма: советую, Часть речи: ADJ Слово: данную, Лемма: данную, Часть речи: ADJ Слово: платформу, Лемма: платформа, Часть речи: NOUN Слово: ., Лемма: ., Часть речи: PUNCT Слово: Она, Лемма: она, Часть речи: PRON Слово: помогает, Лемма: помогать, Часть речи: VERB Слово: делиться, Лемма: делиться, Часть речи: VERB Слово: знаниями, Лемма: знание, Часть речи: NOUN Слово: и, Лемма: и, Часть речи: CCONJ Слово: узнавать, Лемма: узнавать, Часть речи: VERB Слово: новое, Лемма: новый, Часть речи: ADJ Слово: ., Лемма: ., Часть речи: PUNCT
4.3 Вывод глаголов в начальной форме
verbs = [token.lemma_ for token in doc if token.pos_ == 'VERB']
print("Глаголы в тексте:", verbs)
Вывод:
Глаголы в тексте: ['советовать', 'помогать', 'делиться', 'узнавать']
4.4 Синтаксический анализ и визуализация деревьев зависимостей
from spacy import displacy
# Выбор предложения для визуализации
sentence = list(doc.sents)[0]
# Визуализация зависимостей
displacy.render(sentence, style='dep', jupyter=True, options={'compact': True, 'distance': 100})
Вывод:
4.5 Извлечение сущностей
Напишем функцию, которая извлекает все сущности типа ORG
(организации) из нашего текста.
def extract_organizations(text):
doc = nlp(text)
orgs = [ent.text for ent in doc.ents if ent.label_ == 'ORG']
return orgs
# Применение функции
organizations = extract_organizations(text)
print("Организации в тексте:", organizations)
Вывод:
Организации в тексте: ['Хабр']
5. Заключение
В данной статье мы рассмотрели ключевые этапы обработки текста на русском языке с использованием библиотек NLTK и spaCy. Мы научились:
Токенизировать текст на предложения и слова.
Применять стемминг и лемматизацию для приведения слов к их базовым формам.
Удалять стоп-слова, не несущие смысловой нагрузки.
Проводить POS-теггирование для определения частей речи слов в тексте.
Распознавать именованные сущности, такие как имена собственные и организации.
Выполнять синтаксический анализ для выявления структуры предложений.
В следующей части мы углубимся в сложные техники обработки естественного языка, включая: алгоритмы Word2Vec, GloVe и FastText, методы классификации текста и многое другое.