Добро пожаловать в мир анализа настроений! В нынешнюю цифровую эпоху, когда каждый твит, обзор или комментарий могут повлиять на репутацию бизнеса, понимание и анализ настроений стали критически важными. Хотите ли вы оценить удовлетворенность клиентов, отследить тенденции в разговорах в социальных сетях или предсказать общественное мнение о запуске продукта — анализ настроений — ваш лучший инструмент. И есть ли лучший способ погрузиться в эту захватывающую тему, чем создание собственной модели анализа настроений с использованием алгоритма наивного Байеса в Python? Итак, будьте готовы разгадать секреты классификации эмоций и мнений с точностью и аккуратностью. Давайте вместе отправимся в это увлекательное путешествие!

Введение в анализ настроений

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

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

Если вы не знакомы с алгоритмом наивного Байеса, не волнуйтесь! Мы рассмотрим все, что вам нужно знать в этой статье. Мы также предоставим фрагменты кода, чтобы вы могли следить за ними дома.

Что такое наивный байесовский алгоритм?

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

Алгоритм наивного Байеса основан на концепции условной вероятности. Предполагается, что наличие определенной функции в классе не связано с наличием других функций в этом классе. Это допущение называется классово-условной независимостью.

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

Фильтрация спама: у нас есть набор электронных писем, каждое из которых представлено набором слов (функций), и мы хотим классифицировать их как спам или не спам.

Классификация документов: у нас есть набор документов, каждый из которых представлен набором слов (функций), и мы хотим классифицировать их по разным категориям (например, спорт, политика, технологии и т. д.).

Анализ настроений: у нас есть набор обзоров фильмов, каждый из которых представлен набором слов (признаков), и мы хотим классифицировать их как положительные или отрицательные.

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

Обзор набора данных

Набор данных, используемый для этого проекта, — это набор данных «Tweet Sentiment Extraction» от Kaggle. Этот набор данных содержит твиты вместе со связанными с ними метками настроений и выделенным текстом. Выбранный текст дает краткое представление настроения твита. Набор данных используется для обучения моделей анализа тональности для прогнозирования тональности твитов.

Столбцы

  • textID: уникальный идентификатор для каждого фрагмента текста.
  • text: текст твита.
  • настроение: общее настроение твита (положительное, отрицательное или нейтральное).
  • selected_text(только для обучения): текст, который поддерживает тональность твита и служит индикатором тональности.

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

Заявление о проблеме с набором данных

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

Шаги

Вот более подробные объяснения каждого шага для создания модели анализа тональности с использованием алгоритма наивного Байеса в Python:

  1. Получить набор данных с положительными и отрицательными твитами. На первом этапе мы извлечем твиты с положительными и отрицательными настроениями из набора данных. Этого можно добиться, используя функцию split_data_by_sentiment в DataFrame, разделяя данные на отдельные списки положительных и отрицательных твитов.
def split_data_by_sentiment(data, sentiment):
    """
    Split the data DataFrame into separate lists based on sentiment.

    Parameters:
       data (DataFrame): The input DataFrame containing 'text' and 'sentiment' columns.
       sentiment (str): The sentiment label to filter the data.

    Returns:
        list: A list of text corresponding to the specified sentiment.
    """
    return data[data['sentiment'] == sentiment]['text'].tolist()

# Assuming df is your DataFrame containing 'text' and 'sentiment' columns
positive_data = split_data_by_sentiment(df, 'positive')
negative_data = split_data_by_sentiment(df, 'negative')
neutral_data = split_data_by_sentiment(df, 'neutral')

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

  • Преобразовать в нижний регистр. Преобразование всех твитов в строчные буквы. Этот шаг гарантирует, что модель рассматривает слова с разными падежами как одинаковые.
  • Удалить знаки препинания. Удалите все знаки препинания и специальные символы из твитов. Знаки препинания не сильно влияют на анализ настроений и могут быть безопасно удалены.
  • Удалите стоп-слова. Стоп-слова – это общеупотребительные слова, такие как "the", "is", "and" и т. д., которые не несут особой эмоциональной составляющей. Удалите эти слова из твитов, так как они могут внести шум в модель.
  • Определение корней или лемматизация. Выполните определение корней или лемматизацию, чтобы привести слова к их базовой форме. Стемминг приводит слово к его корневой форме, удаляя суффиксы, а лемматизация приводит слова к их словарной форме. Этот шаг помогает уменьшить количество уникальных слов и повышает производительность модели.
  • Токенизация. Разделите предложения на отдельные слова. Это позволяет анализировать каждое слово отдельно и позже строить таблицу подсчета слов.

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

def preprocess_tweet(tweet):
    # Convert the tweet to lowercase
    tweet = tweet.lower()
    
    # Remove punctuation from the tweet using translation
    tweet = tweet.translate(str.maketrans("", "", string.punctuation))
    
    # Tokenize the tweet into individual words
    tokens = nltk.word_tokenize(tweet)
    
    # Initialize a Porter stemmer for word stemming
    stemmer = PorterStemmer()
    
    # Get a set of English stopwords from NLTK
    stopwords_set = set(stopwords.words("english"))
    
    # Apply stemming to each token and filter out stopwords
    tokens = [stemmer.stem(token) for token in tokens if token not in stopwords_set]
    
    # Return the preprocessed tokens
    return tokens

3. Создайте таблицу количества слов: создайте таблицу, в которой показано количество вхождений каждого слова в положительных и отрицательных твитах. Эта таблица, которую часто называют таблицей количества слов или частотой терминов, будет использоваться для расчета вероятностей правдоподобия для алгоритма наивного Байеса. Для каждого твита подсчитайте частоту каждого уникального слова и отслеживайте его. В таблице должно быть указано, сколько раз каждое слово встречается в положительных и отрицательных твитах.

from collections import defaultdict

def calculate_word_counts(tweets):
    # Initialize a defaultdict to store word counts, defaulting to 0 for unseen words
    word_count = defaultdict(int)
    
    # Iterate through each tweet in the given list of tweets
    for tweet in tweets:
        # Tokenize and preprocess the tweet using the preprocess_tweet function
        tokens = preprocess_tweet(tweet)
        
        # Iterate through each token in the preprocessed tokens
        for token in tokens:
            # Increment the count for the current token in the word_count dictionary
            word_count[token] += 1
    
    # Return the word_count dictionary containing word frequencies
    return word_count

# Calculate word counts for tweets with positive sentiment
word_count_positive = calculate_word_counts(train_df[train_df['sentiment'] == 'positive']['text'])

# Calculate word counts for tweets with negative sentiment
word_count_negative = calculate_word_counts(train_df[train_df['sentiment'] == 'negative']['text'])

# Calculate word counts for tweets with neutral sentiment
word_count_neutral = calculate_word_counts(train_df[train_df['sentiment'] == 'neutral']['text'])

4. Рассчитайте вероятность каждого класса с помощью сглаживания Лапласа: Рассчитайте вероятности вероятности для каждого класса (положительного, отрицательного и нейтрального), используя таблицу подсчета слов. Чтобы избежать нулевых вероятностей для слов, которые появляются только в одном классе во время тестирования, примените сглаживание Лапласа. Лапласианское сглаживание добавляет небольшую константу (обычно 1) к числителю и умножает знаменатель на коэффициент количества уникальных слов в наборе данных. Это гарантирует, что любое слово, встречающееся во время тестирования, даже если оно не было замечено при обучении, имеет ненулевую вероятность.

def calculate_likelihood(word_count, total_words, laplacian_smoothing=1):
    # Create an empty dictionary to store the likelihood values
    likelihood = {}
    
    # Get the number of unique words in the vocabulary
    vocabulary_size = len(word_count)

    # Iterate through each word and its corresponding count in the word_count dictionary
    for word, count in word_count.items():
        # Calculate the likelihood using Laplacian smoothing formula
        # Laplacian smoothing is used to handle unseen words in training data
        # The formula is (count + smoothing) / (total_words + smoothing * vocabulary_size)
        likelihood[word] = (count + laplacian_smoothing) / (total_words + laplacian_smoothing * vocabulary_size)

    # Return the calculated likelihood dictionary
    return likelihood

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

import math

def calculate_log_prior(sentiment, data):
    # Calculate the natural logarithm of the ratio of tweets with the specified sentiment to the total number of tweets
    log_prior = math.log(len(data[data['sentiment'] == sentiment]) / len(data))
    
    # Return the calculated log prior
    return log_prior

# Calculate the log prior for tweets with positive sentiment
log_prior_positive = calculate_log_prior('positive', df)

# Calculate the log prior for tweets with negative sentiment
log_prior_negative = calculate_log_prior('negative', df)

# Calculate the log prior for tweets with neutral sentiment
log_prior_neutral = calculate_log_prior('neutral', df)

6. Возьмем логарифм вероятности: чтобы избежать проблем с недостаточным значением при умножении вероятностей, обычной практикой является логарифмирование вероятностей вероятности. Логарифм помогает преобразовать произведение вероятностей в сумму, что упрощает расчеты и повышает точность вычислений.

# Create a dictionary of log-likelihood values for positive sentiment
log_likelihood_positive = {word: math.log(prob) for word, prob in likelihood_positive.items()}

# Create a dictionary of log-likelihood values for negative sentiment
log_likelihood_negative = {word: math.log(prob) for word, prob in likelihood_negative.items()}

# Create a dictionary of log-likelihood values for neutral sentiment
log_likelihood_neutral = {word: math.log(prob) for word, prob in likelihood_neutral.items()}

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

def classify_tweet_with_scores(tweet, log_likelihood_positive, log_likelihood_negative, log_likelihood_neutral,
                               log_prior_positive, log_prior_negative, log_prior_neutral):
    # Tokenize and preprocess the input tweet
    tokens = preprocess_tweet(tweet)

    # Calculate the log scores for each sentiment category
    log_score_positive = log_prior_positive + sum([log_likelihood_positive.get(token, 0) for token in tokens])
    log_score_negative = log_prior_negative + sum([log_likelihood_negative.get(token, 0) for token in tokens])
    log_score_neutral = log_prior_neutral + sum([log_likelihood_neutral.get(token, 0) for token in tokens])

    # Store the sentiment scores in a dictionary
    sentiment_scores = {
        'positive': log_score_positive,
        'negative': log_score_negative,
        'neutral': log_score_neutral
    }

    # Determine the predicted sentiment based on the highest sentiment score
    predicted_sentiment = max(sentiment_scores, key=sentiment_scores.get)
    
    # Return the predicted sentiment and the sentiment scores
    return predicted_sentiment, sentiment_scores

8. Создание приложения Streamlit:

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

Заключение

Анализ тональности с алгоритмом наивного Байеса — это мощный подход, использующий вероятностный и лингвистический анализ для классификации тональности текста как положительной, отрицательной или нейтральной. Путем предварительной обработки текста, вычисления логарифмических априорных значений и получения логарифмических правдоподобий этот метод количественно определяет настроение, обеспечивая точную классификацию. Его адаптируемость к различным доменам и библиотека Python NLTK делают его доступным для различных приложений. Naive Bayes обогащает процесс принятия решений, предлагая информацию об удовлетворенности клиентов, восприятии бренда и тенденциях, что имеет решающее значение в эпоху обилия текстовых данных.

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