Анализ данных для задач НЛП

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

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

Настройка среды

Первым шагом любого проекта является настройка среды, т.е. установка важных пакетов и импорт важных библиотек.

!pip install nltk
!pip install pandas
import pandas as pd
import nltk
from nltk.tokenize import sent_tokenize,word_tokenize
from nltk.stem import PorterStemmer
from nltk.corpus import stopwords
import re

Следующим этапом проекта будет загрузка датасета. В данном случае мы будем использовать набор данных твитов о катастрофах из Kaggle. 

Мы можем загрузить наш датасет с помощью библиотеки pandas. 

df = pd.read_csv("/train.csv")

Для того чтобы получить общее представление о данных, мы можем просмотреть верхние строки набора данных с помощью функции head в pandas:

df.head(10)
Анализ данных для задач НЛП

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

df.info()
Анализ данных для задач НЛП

Набор данных содержит четыре столбца, а именно: ключевое слово, местоположение, текст и цель, и около 7000 строк. Колонка “цель” имеет два значения: 0 – твиты без катастрофы и 1 – твиты с катастрофой. Для просмотра распределения столбца target мы можем построить график с помощью библиотеки seaborn. Поскольку значения столбца target дискретны, мы можем просто использовать countplot из библиотеки seaborn.

sns.countplot(x = df["target"])
Анализ данных для задач НЛП

Распределение на рис. 3 показывает, что данные сбалансированы между обоими целевыми значениями.

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

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

plt.figure(figsize=(10,70))
sns.countplot(data=df,y="keyword",hue="target",saturation=0.50)
plt.legend(bbox_to_anchor=(1.02, 1), loc='upper left', borderaxespad=0)
plt.show()
Анализ данных для задач НЛП
Рисунок 4. Распределение ключевых слов в твитах, посвященных катастрофам и не катастрофам

Колонка местоположения содержит данные, предоставленные пользователем, и поэтому имеет тенденцию быть неструктурированной и очень разнообразной. Многие слова, указанные в столбце, такие как ‘Live On Webcam’, ‘news’, ‘Milky Way’, ‘Somewhere’ и другие, не соответствуют какому-либо физическому местоположению. Чрезмерная уникальность данных о местоположении делает их непригодными для использования в качестве признака. В очередной раз мы можем построить график встречаемости местоположения для твитов, связанных и не связанных с бедствием, используя функцию countplot из библиотеки seaborn. Это можно наглядно представить на рис. 5.

plt.figure(figsize=(10,70))
sns.countplot(data=df,y="location",hue="target",saturation=0.50)
plt.legend(bbox_to_anchor=(1.02, 1), loc='upper left', borderaxespad=0)
plt.show()
Анализ данных для задач НЛП

Количество слов

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

df["Number of Words"] = df_train.apply(lambda n: len(n.split()))
sns.distplot(x=train_feature[train_feature['target'] == 0]['Number of Words'], label='Not Disaster', kde=True,color='orange')
sns.distplot(x=train_feature[train_feature['target'] == 1]['Number of Words'], label='Disaster', kde=True,color='blue')
plt.legend()
plt.show()
Анализ данных для задач НЛП

График на рис. 6 показывает распределение количества слов для твитов, посвященных катастрофе и не связанных с ней. Видно, что большое количество твитов, посвященных катастрофам и не катастрофам, имеют количество слов от 10 до 20.

Количество уникальных слов

Количество уникальных слов – это количество отдельных слов, присутствующих в тексте. Количество уникальных слов позволяет судить о разнообразии словарного запаса.

df["Number of unique Words"] = df.apply(lambda n: len(set(n.split())))

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

sns.distplot(x=train_feature[train_feature['target'] == 0]['Number of unique Words'], label='Not Disaster', kde=True,color='orange')
sns.distplot(x=train_feature[train_feature['target'] == 1]['Number of unique Words'], label='Disaster', kde=True,color='blue')
plt.legend()
plt.show()
Анализ данных для задач НЛП
Рисунок 7: Распределение количества уникальных слов для твитов, посвященных бедствиям и не связанных с бедствиями

Подсчет стоп-слов

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

df['Stopwords_Count'] = df.apply(lambda x: len(set(x.split()) & stop_words))

Для визуализации распределения стоп-слов можно построить график с помощью функции distplot библиотеки seaborn.

sns.distplot(x=train_feature[train_feature['target'] == 0]['Stopwords_Count'], label='Not Disaster', kde=True,color='orange')
sns.distplot(x=train_feature[train_feature['target'] == 1]['Stopwords_Count'], label='Disaster', kde=True,color='blue')
plt.legend()
plt.show()
Анализ данных для задач НЛП
Рисунок 8: Распределение количества стоп-слов для твитов, посвященных бедствиям и не связанных с ними

Количество хэштегов

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

df['hashtag_count'] = df.apply(lambda x: len([c for c in str(x) if c == '#']))
sns.distplot(x=train_feature[train_feature['target'] == 0]['hashtag_count'], label='Not Disaster', kde=True,color='orange')
sns.distplot(x=train_feature[train_feature['target'] == 1]['hashtag_count'], label='Disaster', kde=True,color='blue')
plt.legend()
plt.show()
Анализ данных для задач НЛП
Рисунок 9: Распределение хэштегов в твитах, посвященных стихийным бедствиям и не связанных с ними

Подсчет URL

Подсчет URL предполагает подсчет URL-адресов в тексте. Чаще всего URL в тексте представляют собой ссылку на какой-либо сайт.

df['url_count'] = df.apply(lambda x: len([w for w in str(x).lower().split() if 'http' in w or 'https' in w]))
sns.distplot(x=train_feature[train_feature['target'] == 0]['url_count'], label='Not Disaster', kde=True,color='orange')
sns.distplot(x=train_feature[train_feature['target'] == 1]['url_count'], label='Disaster', kde=True,color='blue')
plt.legend()
plt.show()
Анализ данных для задач НЛП
Рисунок 10: Распределение количества URL-адресов в твитах, посвященных катастрофе и не подверженных катастрофе

Аналогичным образом может быть проведен и анализ метахарактеристик тестовых данных. Все метахарактеристики содержат информацию, связанную с целью, однако некоторые из них, такие как url_count и hashtag_count, не обладают достаточной эффективностью. Напротив, word_count, unique_word_count, stop_word_count демонстрируют различные распределения между твитами с катастрофами и твитами без катастроф. Эти характеристики перспективны для повышения эффективности модели.

Очистка данных

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

Токенизация слов

Токенизация слов – это процесс разбиения текста на более мелкие единицы, называемые лексемами. Например, в предложении “Я люблю свою страну.” слово токенизируется на “я”, “люблю”, “моя”, “страна”. Если мы хотим токенизировать столбец нашего массива данных, мы можем использовать word_tokenize из NLTK в лямбда-функции.

def tokenizing(self,text):
        return word_tokenize(text)

df['text'] = df['text'].apply(lambda x: word_tokenize(x))

Выявление и удаление стоп-слов

Стоп-слова – это набор слов, которые чаще всего встречаются в языке. Например, в английском языке “a”, “an”, “the”, “is”, “am” и т.д. являются стоп-словами. Они в большинстве случаев не имеют значения, когда мы пытаемся понять контекст текста. Поэтому стоп-слова необходимо удалять из текста, чтобы уменьшить его объем и сосредоточиться на важных и значимых словах.

def remove_stopwords(text):
        words = text.split()
        filtered_words = [word for word in words if word not in stop_words] 
        return ' '.join(filtered_words)

df['text'] = df['text'].apply(lambda x: remove_stopwords(x))

Удаление пунктуации

Пунктуация – это такие символы, как запятые, вопросительные и восклицательные знаки и т.д., используемые в языке для поддержания смысла текста. Пунктуация должна быть удалена из текста, чтобы каждое слово воспринималось одинаково.

 def cleaning_punctuations(text):
        return re.sub(r"[()!$?:;.]","",str(text))

df['text'] = df['text'].apply(lambda x: cleaning_punctuations(x))

Удаление символов, ссылок на сайты и хэштегов

Для уменьшения шума в тексте необходимо удалить символы типа “@”, текст, содержащий “#”, и ссылки на сайты, начинающиеся с “www” и “http”.

def cleaning_ats(text):
    return re.sub("@[A-Za-z0-9_]+","",text) 
def cleaning_httpss(text):
    return re.sub(r"http.\S+","",text)
def cleaning_hashs(text):
    return re.sub("#[A-Za-z0-9_]+","",text)
def cleaning_www(text):
    return re.sub("www.\S+", "",text)

df['text'] = df['text'].apply(lambda x: cleaning_ats(x))
df['text'] = df['text'].apply(lambda x: cleaning_httpss(x))
df['text'] = df['text'].apply(lambda x: cleaning_hashs(x))
df['text'] = df['text'].apply(lambda x: cleaning_www(x))

Заключение

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

+1
2
+1
1
+1
0
+1
0
+1
0

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *