Введение

Добро пожаловать в следующий выпуск нашей серии блогов об анализе настроений! В нашем предыдущем сообщении в блоге Как извлечь данные из Твиттера для анализа настроений, где мы обсудили значение анализа настроений и рассмотрели процесс извлечения данных из Твиттера с помощью Python и snsscrape библиотека. Мы узнали, как определять параметры поиска, извлекать данные и сохранять их в файл CSV, закладывая основу для нашего путешествия по анализу тональности.

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

Данные доступны на kaggle.com. Скачать данные можно по этой ссылке

Импорт необходимой библиотеки и загрузка данных

import numpy as np
import pandas as pd
#reading
df= pd.read_csv('./tweets_extraction 2.csv')

Фрагмент кода импортирует библиотеки numpy и pandas для выполнения задач анализа и обработки данных в Python. Код считывает данные из CSV-файла с помощью функции read_csv() из библиотеки pandas.

Понимание данных

df.shape #gives number of rows and columns
df.info()  #provides datatype and respective data info null or not
df.head()  #gives first 5 rows by default

Этот фрейм данных содержит 10 тыс. записей с 5 столбцами.

Нулевые значения и повторяющиеся записи

#Checking Null values
null_cols = df.columns[df.isnull().any()]
null_df = df[null_cols].isnull().sum().to_frame(name='Null Count')\
          .merge(df[null_cols].isnull().mean().mul(100).to_frame(name='Null Percent'), left_index=True, right_index=True)
null_df_sorted = null_df.sort_values(by='Null Count', ascending=False)
print(null_df_sorted)

count_duplicates = df[df.duplicated()].shape[0]
print("Number of duplicate rows:", count_duplicates)

#delete the duplicate entries
df.drop_duplicates(inplace=True)

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

Предварительная обработка текста

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

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

  1. Нижний кожух
  2. Удаление URL
  3. Удаление тегов HTML
  4. Преобразование слов в чате
  5. Удаление знаков препинания
  6. Удаление номеров
  7. Удаление лишних пробелов
  8. Замена повторов знаков препинания
  9. Преобразование смайликов в слова
  10. Удаление специальных символов
  11. Удаление сжатия
  12. Удаление других языковых слов
  13. Токенизация
  14. Удаление стоп-слов
  15. лемматизация

Нижний корпус

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

# Lowercase the data
df['text_cleaned'] = df['text'].apply(lambda x: x.lower())

Удаление URL-адресов и тегов HTML

Давайте импортируем необходимые библиотеки. Мы будем использовать re для регулярных выражений и BeautifulSoup из библиотекиbs4 для удаления тега HTML.

import re
from bs4 import BeautifulSoup

# Removing URLs
df['text_cleaned'] = df['text_cleaned'].apply(lambda x: re.sub(r'http\S+|www.\S+', '', x))

# Removing HTML tags
df['text_cleaned'] = df['text_cleaned'].apply(lambda x: BeautifulSoup(x, "lxml").text)

URL-адреса обычно встречаются в текстовых данных и могут не предоставлять полезную информацию для анализа. В этом коде мы применяем лямбда-функцию к каждому значению в столбце 'text_cleaned', используя метод re. sub() для замены URL-адресов пустой строкой.

Текстовые данные, извлеченные из веб-источников, часто содержат теги HTML, которые необходимо удалить перед анализом. В этом коде мы используем библиотеку BeautifulSoup для создания объекта BeautifulSoup, передавая текстовое значение. Затем мы извлекаем текстовое содержимое с помощью атрибута .text.

Преобразование слов в чате

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

Шаг 1. Создание словаря слов для чата.

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

#convert chatwords 
chat_words_dict = {
    "imo": "in my opinion",
     "cyaa": "see you",
    "idk": "I don't know",
    "rn": "right now",
    "afaik": "as far as I know",
    #more chat words were added while doing text preprocessing. 
}

Шаг 2. Определение функции преобразования.

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

def convert_chat_words(text):
    words = text.split()
    converted_words = []
    for word in words:
        if word.lower() in chat_words_dict:
            converted_words.append(chat_words_dict[word.lower()])
        else:
            converted_words.append(word)
    converted_text = " ".join(converted_words)
    return converted_text

Шаг 3. Применение преобразования слов чата в DataFrame:

Теперь давайте применим функцию преобразования слов чата к столбцу text_cleaned в нашем DataFrame. Вот код для обновления столбца:

df['text_cleaned'] = df['text_cleaned'].apply(convert_chat_words)

Удаление знаков препинания, цифр, лишних пробелов и замена повторений знаков препинания

# Removing punctuation
import string
df['text_cleaned'] = df['text_cleaned'].apply(lambda x: x.translate(str.maketrans('', '', string.punctuation)))

# Removing numbers
df['text_cleaned'] = df['text_cleaned'].apply(lambda x: re.sub(r'\d+', '', x))

# Removing extra spaces
df['text_cleaned'] = df['text_cleaned'].apply(lambda x: ' '.join(x.split()))

# Replacing repetitions of punctuation
df['text_cleaned'] = df['text_cleaned'].apply(lambda x: re.sub(r'(\W)\1+', r'\1', x))

В приведенном выше коде мы используем модуль string.punctuation для удаления пунктуации из текста. Функция re.sub() используется для удаления чисел путем замены их пустой строкой. Затем мы удаляем лишние пробелы, разбивая текст на слова и соединяя их обратно одним пробелом. Наконец, мы заменяем повторения знаков препинания с помощью регулярных выражений.

Преобразование смайликов в слова

import emoji
import re

# Function to convert emojis to words using emoji library mapping
def convert_emojis_to_words(text):
    converted_text = emoji.demojize(text)
    return converted_text

# Apply the function to the 'text_cleaned' column in the DataFrame
df['text_cleaned'] = df['text_cleaned'].apply(convert_emojis_to_words)

В приведенном выше коде мы импортируем библиотеку emoji, которая обеспечивает функциональность для преобразования смайликов в соответствующие им слова с помощью функции demojize(). Мы определяем функцию convert_emojis_to_words(), которая принимает ввод текста, применяет функцию demojize() для преобразования смайликов в слова и возвращает преобразованный текст.

Применив эту функцию к столбцу text_cleaned с помощью метода apply(), смайлики в тексте будут преобразованы в соответствующие им слова, что улучшит читаемость и согласованность текста в нашем фрейме данных.

Удаление специальных символов

В приведенном ниже коде регулярное выражение [^\w\s] соответствует любому символу, который не является символом слова (буквенно-цифровым или символом подчеркивания) или пробелом. Функция re.sub() используется для замены этих специальных символов пустой строкой, эффективно удаляя их из текста.

# Removing special characters
df['text_cleaned'] = df['text_cleaned'].apply(lambda x: re.sub(r"[^\w\s]", '', x))

Удаление сокращений

Сокращение — это сокращенная форма двух слов, созданная путем их объединения с апострофом (‘), в результате чего получается одно слово. Сокращения также широко используются в Твиттере. Вот несколько примеров сокращений и их развернутых форм: «can’t» (не может), «won’t» (не будет)

# Removing contractions
import contractions
# Remove contractions from the 'text_cleaned' column
df['text_cleaned'] = df['text_cleaned'].apply(lambda x: contractions.fix(x))

Для этого мы импортируем библиотеку contractions, которая предоставляет функциональные возможности для расширения сокращений в тексте. Затем мы используем функцию contractions.fix() в лямбда-функции, чтобы применить ее к каждому элементу в столбце text_cleaned.

Удаление других языковых слов

Фрагмент кода ниже использует библиотеку langdetect для определения языка каждого текста в столбце text_cleaned и заменяет неанглийский текст пустой строкой. Если обнаруженный язык не английский («en»), мы заменяем соответствующее значение «text_cleaned» пустой строкой.

from langdetect import detect

# Iterate through each row
for index, row in df.iterrows():
    text = row['text_cleaned']
    try:
        lang = detect(text)
    except:
        lang = 'unknown'
    if lang != 'en':
        df.at[index, 'text_cleaned'] = ''  # Replace non-English text with an empty string

Токенизация

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

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

from nltk.tokenize import word_tokenize
# Tokenization
df['tokens'] = df['text_cleaned'].apply(lambda x: word_tokenize(x))

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

Стоп-слова — это часто используемые слова, которые считаются незначительными или неинформативными в задачах обработки естественного языка (NLP). Эти слова часто отфильтровываются или удаляются из текстовых данных во время предварительной обработки. Стоп-слова обычно включают общеупотребительные слова, такие как артикли (например, «a», «an», «the»), местоимения (например, «я», «ты», «он», «она»), предлоги (например, «на», «в», «в»), союзы (например, «и», «но», «или») и другие часто встречающиеся слова, которые сами по себе не несут большого значения.

Цель удаления стоп-слов — уменьшить шум и сосредоточиться на более важных словах или терминах в тексте. Удаление этих общих и менее значимых слов помогает повысить эффективность и точность различных задач НЛП.

# Removing stop words
from nltk.corpus import stopwords
stop_words = set(stopwords.words('english'))
df['tokens'] = df['tokens'].apply(lambda x: [word for word in x if word not in stop_words])
# Print the updated 'tokens' column
df['tokens'].tail(20)

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

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

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

from nltk.stem import WordNetLemmatizer
from nltk.corpus import wordnet
import nltk
# Create an instance of WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
# POS tag mapping dictionary
wordnet_map = {"N": wordnet.NOUN, "V": wordnet.VERB, "J": wordnet.ADJ, "R": wordnet.ADV}

# Function to perform Lemmatization on a text
def lemmatize_text(text):
    # Get the POS tags for the words
    pos_tags = nltk.pos_tag(text)
    
    # Perform Lemmatization
    lemmatized_words = []
    for word, tag in pos_tags:
        # Map the POS tag to WordNet POS tag
        pos = wordnet_map.get(tag[0].upper(), wordnet.NOUN)
        # Lemmatize the word with the appropriate POS tag
        lemmatized_word = lemmatizer.lemmatize(word, pos=pos)
        # Add the lemmatized word to the list
        lemmatized_words.append(lemmatized_word)
    
    return lemmatized_words

# Apply Lemmatization to the 'tokens' column
df['tokens'] = df['tokens'].apply(lemmatize_text)

Визуализация

Облако слов

Облако слов обеспечивает визуальное представление наиболее часто встречающихся слов в тексте, при этом более крупные слова указывают на более высокие частоты. Создавая облако слов, вы можете быстро понять ключевые темы и важные термины, присутствующие в наборе данных или документе.

from wordcloud import WordCloud
import matplotlib.pyplot as plt
# Create a list of all tokens
all_tokens = [token for tokens_list in df['tokens'] for token in tokens_list]
# Create a WordCloud object
wordcloud = WordCloud(width=800, height=400, background_color='white').generate_from_frequencies(dict(nltk.FreqDist(all_tokens)))
# Plot the word cloud
plt.figure(figsize=(10, 5))
plt.imshow(wordcloud, interpolation='bilinear')
plt.axis('off')
plt.show()

Частота слов

import nltk
from nltk.probability import FreqDist
import matplotlib.pyplot as plt
# Calculate word frequency
freq_dist = FreqDist(all_tokens)
# Plot the most common words
plt.figure(figsize=(10, 5))
freq_dist.plot(30, cumulative=False)
plt.xlabel('Words')
plt.ylabel('Frequency')
plt.xticks(rotation=45)
plt.show()

Заключение

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

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

СЛЕДУЙТЕ ЗА МНОЙ и присоединяйтесь к моему Путешествию аналитика данных, чтобы открыть для себя потенциал анализа настроений для извлечения значимой информации из данных Twitter.

Пожалуйста, ознакомьтесь с моей предыдущей статьей о Как извлечь данные из Twitter.