Привет, Хабр!

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

В NLTK включены корпуса текстов и словарные ресурсы, такие как WordNet, позволяющие работать с огромным объемом текстовых данных. Это делает NLTK мощным инструментом для анализа и обработки текста на разных языках.

NLTK — это свободно распространяемая библиотека Python, разработанная для работы с человеческим языком. Это комплексный набор инструментов, предназначенный для символьной и статистической обработки естественного языка. Она предоставляет легкий доступ к более чем 50 корпусам текстов и лексическим ресурсам, таким как WordNet, а также набор библиотек для классификации, токенизации, стемминга, метки частей речи, синтаксического анализа и семантического рассуждения.

Быстренько установим...(подразумевается, что у вас уже есть питон)

Откройте командную строку или терминал и выполните следующую команду:

pip install nltk

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

import nltk

nltk.download('popular')

Команда nltk.download('popular') загружает наиболее часто используемые корпуса и модели. Если вам требуются конкретные ресурсы, вы можете загрузить их, заменив 'popular' на соответствующее название. Например, для загрузки WordNet используйте nltk.download('wordnet').

Если вы видите список английских стоп-слов, значит, библиотека NLTK установлена правильно.

Техники предварительной обработки текста в NLP с использованием NLTK

Токенизация

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

  1. В NLTK можно применять так:

    • Разбиение на слова:

      import nltk
      nltk.download('punkt')

      Этот код загрузит необходимые данные punkt, которые используются для токенизации текста.

      from nltk.tokenize import word_tokenize
      
      text = "NLTK упрощает обработку текста."
      word_tokens = word_tokenize(text)
      print(word_tokens)

      Результат кода: ['NLTK', 'упрощает', 'обработку', 'текста', '.']

    • Разбиение на предложения:

      from nltk.tokenize import sent_tokenize
      
      text = "OTUS. Наш сайт https://otus.ru/."
      sentence_tokens = sent_tokenize(text)
      print(sentence_tokens)

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

Удаление стоп-слов

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

  1. Примеры кода:

    • Фильтрация стоп-слов на русском языке:

      Нужно загрузить данные stopwords с помощью NLTK Downloader. Это делается так:

      import nltk
      nltk.download('stopwords')
      from nltk.corpus import stopwords
      from nltk.tokenize import word_tokenize
      
      text = "NLTK помогает в удалении стоп-слов из текста."
      tokens = word_tokenize(text)
      stop_words = set(stopwords.words('russian'))
      filtered_tokens = [word for word in tokens if word not in stop_words]
      
      print(filtered_tokens)

      Результат: ['NLTK', 'помогает', 'удалении', 'стоп-слов', 'текста', '.']

    • Фильтрация стоп-слов на английском языке:

      text = "NLTK helps in removing stopwords from the text."
      tokens = word_tokenize(text)
      filtered_tokens = [word for word in tokens if not word in stopwords.words('english')]
      print(filtered_tokens)
      

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

Стемминг

Стемминг — это процесс сведения слов к их основной (корневой) форме, удаляя окончания и суффиксы. Это помогает уменьшить сложность текста и улучшить производительность алгоритмов анализа.

  1. Примеры кода:

    • Стемминг на английском языке:

      from nltk.stem import PorterStemmer
      from nltk.tokenize import word_tokenize
      
      stemmer = PorterStemmer()
      text = "The stemmed form of leaves is leaf"
      tokens = word_tokenize(text)
      stemmed_words = [stemmer.stem(word) for word in tokens]
      print(stemmed_words)
      

      Результат: ['the', 'stem', 'form', 'of', 'leav', 'is', 'leaf']

    • Стемминг на русском языке:

      from nltk.stem.snowball import SnowballStemmer
      
      stemmer = SnowballStemmer("russian")
      text = "Листовые листочки лист листва листве почему так"
      tokens = word_tokenize(text)
      stemmed_words = [stemmer.stem(word) for word in tokens]
      print(stemmed_words)

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

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

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

  1. Примеры кода:

    • Лемматизация на английском языке:

      Нужно загрузить данные omw-1.4 с помощью NLTK Downloader:

      import nltk
      nltk.download('omw-1.4')
      from nltk.stem import WordNetLemmatizer
      from nltk.tokenize import word_tokenize
      
      lemmatizer = WordNetLemmatizer()
      text = "The lemmatized form of leaves is leaf"
      tokens = word_tokenize(text)
      lemmatized_words = [lemmatizer.lemmatize(word) for word in tokens]
      print(lemmatized_words)
    • Лемматизация на русском языке (используя стеммер, так как для русского языка NLTK не предоставляет прямой лемматизатор):

      stemmer = SnowballStemmer("russian")
      text = "Лемматизированная форма слова листья это лист"
      tokens = word_tokenize(text)
      lemmatized_words = [stemmer.stem(word) for word in tokens]
      print(lemmatized_words)
      

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

Анализ настроений

Анализ настроений, иногда называемый "определением тональности", включает использование NLP, статистических или машинно-обученных алгоритмов для изучения, идентификации и извлечения информации о настроениях из текстов. Он может быть столь же простым, как определение положительной или отрицательной окраски отзыва, или настолько сложным, как определение более тонких эмоциональных состояний, таких как ирония или разочарование.

Анализ настроений не без проблем. Одна из основных сложностей заключается в интерпретации сарказма, иронии и фигуративного языка. Например, фраза "Ну да, конечно, мне очень понравилось, когда мой телефон перестал работать" на самом деле выражает разочарование, хотя на первый взгляд может показаться положительной. Распознавание таких тонкостей требует продвинутых алгоритмов и, часто, контекстуального анализа.

Анализ настроений (или сентимент-анализ) в NLTK часто сводится к классификации текста на позитивный или негативный. Чтобы реализовать анализ настроений, можно использовать разные подходы.

Простая классификация с использованием предварительно обученных данных

import nltk
from nltk.sentiment import SentimentIntensityAnalyzer

nltk.download('vader_lexicon')

sia = SentimentIntensityAnalyzer()
text = "NLTK is amazing for natural language processing!"
print(sia.polarity_scores(text))

Классификация с использованием настраиваемых тренировочных данных

import nltk
from nltk.classify import NaiveBayesClassifier
from nltk.corpus import subjectivity
from nltk.sentiment import SentimentAnalyzer
from nltk.sentiment.util import *

nltk.download('subjectivity')

n_instances = 100
subj_docs = [(sent, 'subj') for sent in subjectivity.sents(categories='subj')[:n_instances]]
obj_docs = [(sent, 'obj') for sent in subjectivity.sents(categories='obj')[:n_instances]]
train_subj_docs = subj_docs[:80]
test_subj_docs = subj_docs[80:100]
train_obj_docs = obj_docs[:80]
test_obj_docs = obj_docs[80:100]
training_docs = train_subj_docs+train_obj_docs
testing_docs = test_subj_docs+test_obj_docs

sentim_analyzer = SentimentAnalyzer()
all_words_neg = neg_tagged_word_feats(sentim_analyzer.all_words(training_docs), mark_negation=True)
unigram_feats = sentim_analyzer.unigram_word_feats(all_words_neg, min_freq=4)
sentim_analyzer.add_feat_extractor(extract_unigram_feats, unigrams=unigram_feats)
training_set = sentim_analyzer.apply_features(training_docs)
test_set = sentim_analyzer.apply_features(testing_docs)

trainer = NaiveBayesClassifier.train
classifier = sentim_analyzer.train(trainer, training_set)

for key,value in sorted(sentim_analyzer.evaluate(test_set).items()):
    print('{0}: {1}'.format(key, value))

Использование TextBlob для анализа настроений

from textblob import TextBlob
import nltk

nltk.download('movie_reviews')
nltk.download('punkt')

text = "I love NLTK. It's incredibly helpful!"
blob = TextBlob(text)
print(blob.sentiment)

Анализ настроений с использованием токенизатора и списка стоп-слов

from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
from nltk.sentiment import SentimentIntensityAnalyzer
import nltk

nltk.download('stopwords')
nltk.download('vader_lexicon')

stop_words = set(stopwords.words('english'))
text = "NLTK is not bad for learning NLP."
filtered_text = ' '.join([word for word in word_tokenize(text) if not word in stop_words])

sia = SentimentIntensityAnalyzer()
print(sia.polarity_scores(filtered_text))

Комбинирование лемматизации и анализа настроений

from nltk.stem import WordNetLemmatizer
from nltk.tokenize import word_tokenize
from nltk.sentiment import SentimentIntensityAnalyzer
import nltk

nltk.download('wordnet')
nltk.download('vader_lexicon')

lemmatizer = WordNetLemmatizer()
text = "The movie was not good. The plot was terrible!"
lemmatized_text = ' '.join([lemmatizer.lemmatize(word) for word in word_tokenize(text)])

sia = SentimentIntensityAnalyzer()
print(sia.polarity_scores(lemmatized_text))

Важно отметить, что для корректной работы некоторых примеров может потребоваться установка дополнительных библиотек, таких как textblob.

Модель "Мешок слов" (Bag of Words, BoW) является основным методом представления текстовых данных в обработке естественного языка (Natural Language Processing, NLP). Она преобразует текст в числовой вектор, где каждое слово в тексте представляется количеством его появлений.

Модель BoW

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

Каждое уникальное слово в тексте соответствует определенному индексу (или "слоту") в векторе. Если слово встречается в тексте, то в соответствующем слоте вектора записывается количество его появлений. Например, текст "яблоко банан яблоко" превратится в вектор [2, 1], если индекс 0 соответствует слову "яблоко", а индекс 1 — слову "банан".

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

Создание BoW с NLTK и использование его для классификации

import nltk
from nltk.tokenize import word_tokenize
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

nltk.download('punkt')

# Пример данных
texts = ["I love this product", "This is a bad product", "I dislike this", "This is the best!"]
labels = [1, 0, 0, 1]  # 1 - позитивный, 0 - негативный

# Токенизация
tokens = [word_tokenize(text) for text in texts]

# Создание BoW модели
vectorizer = CountVectorizer()
bow = vectorizer.fit_transform([' '.join(token) for token in tokens])

# Разделение данных на обучающую и тестовую выборку
X_train, X_test, y_train, y_test = train_test_split(bow, labels, test_size=0.3)

# Обучение классификатора
classifier = MultinomialNB()
classifier.fit(X_train, y_train)

# Оценка классификатора
predictions = classifier.predict(X_test)
print("Accuracy:", accuracy_score(y_test, predictions))

Пример 2: Простой анализ настроений с BoW и NLTK

import nltk
from nltk.corpus import movie_reviews
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import accuracy_score

nltk.download('movie_reviews')

# Загрузка данных
documents = [(list(movie_reviews.words(fileid)), category)
             for category in movie_reviews.categories()
             for fileid in movie_reviews.fileids(category)]
random.shuffle(documents)

# Подготовка данных
texts = [' '.join(doc) for doc, _ in documents]
labels = [1 if category == 'pos' else 0 for _, category in documents]

# Создание BoW модели
vectorizer = CountVectorizer()
bow = vectorizer.fit_transform(texts)

# Разделение данных на обучающую и тестовую выборку
X_train, X_test, y_train, y_test = train_test_split(bow, labels, test_size=0.3)

# Обучение классификатора
classifier = MultinomialNB()
classifier.fit(X_train, y_train)

# Оценка классификатора
predictions = classifier.predict(X_test)
print("Accuracy:", accuracy_score(y_test, predictions))

BoW служит мостом между текстовыми данными и числовыми методами.


NLTK с его легкостью использования делают его идеальным выбором для широкого спектра задач обработки текстовых данных.

Более подробно с NLTK можно ознакомиться здесь.

А практические навыки по аналитике вы можете получить от экспертов отрасли в рамках онлайн-курсов от моих коллег из OTUS. Подробнее в каталоге.

Комментарии (0)