Анализ данных для задач НЛП
Для успешного 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()
Колонка местоположения содержит данные, предоставленные пользователем, и поэтому имеет тенденцию быть неструктурированной и очень разнообразной. Многие слова, указанные в столбце, такие как ‘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()
Подсчет стоп-слов
Подсчет стоп-слов предполагает подсчет количества стоп-слов в каждой строке определенного столбца текста. Стоп-слова считаются шумом в данных. Кроме того, подсчет стоп-слов позволяет получить представление о данных. Если соотношение стоп-слов велико, то это свидетельствует о наличии некоторого расхождения в данных.
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()
Количество хэштегов
Подсчет хэштегов предполагает подсчет количества хэштегов в тексте. В большинстве случаев хэштеги удаляются, чтобы сохранить акцент на основной концепции исходного текста. Однако мы можем проверить их относительную важность в тексте, построив график их распределения.
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()
Подсчет 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()
Аналогичным образом может быть проведен и анализ метахарактеристик тестовых данных. Все метахарактеристики содержат информацию, связанную с целью, однако некоторые из них, такие как 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))
Заключение
В итоге анализ данных позволяет получить четкое представление о наборе данных. В статье показано распределение признаков между целевыми классами и применено это понимание как к обучающим, так и к тестовым данным. Анализ мета-функций позволяет выявить ключевые характеристики набора данных. После систематической очистки данных данные готовятся к получению точных результатов моделирования, что создает основу для успешной работы модели за счет всестороннего понимания данных.