Проверка настроения твита с помощью машинного обучения
Давайте посмотрим несколько твитов и классифицируем их как положительные или отрицательные.
Когда мы слышим слово Twitter, что оно вызывает у нас в ушах? Что ж, для некоторых это источник информации, где люди мгновенно получают новости, для некоторых это место, где можно высказать свое мнение. а для некоторых это просто приложение на телефоне.
С появлением смартфонов в последнее десятилетие Twitter постепенно превратился из сайта микроблогов, который изначально был запущен как замена SMS, и теперь поставляется как встроенное приложение для наших телефонов. Теперь у всех нас есть это приложение в пределах досягаемости, где мы используем его, чтобы проверять новости, следить за публикациями, следить за личностями и знаменитостями, которые сделали его обычной частью своего пиара наряду с Instagram и Facebook для обновления в Twitter.
Короче говоря, если вы любитель, обновления в Twitter - это новости.
Теперь, поскольку все крупные и мелкие компании, тресты, учреждения, премьеры фильмов, арт-компании или бутики, киностудии, рестораны, список можно продолжить, имеют свои собственные учетные записи в Твиттере, они часто держат своих подписчиков в курсе всего, что они считают необходимым, чтобы они знали через свой дескриптор.
И как только они это делают, люди часто склонны высказывать свое мнение, чувства, тирады, отвращение и все, что им хочется, чтобы выразить это на платформе.
Компании знают об этом, поэтому они используют Twitter, чтобы оценить настроения широкой публики, чтобы узнать о выпуске их продуктов и о том, как они могут улучшить свои продукты, чтобы они доходили до более широких слоев общества, что, в свою очередь, повлияло бы на их бизнес, приносящий доход.
На графике ниже видно, что все содержимое твитов в мире Twitter подразделяется на различные категории.
В моей предыдущей статье мы видели, как мы проверяем продажи товара в конкретном магазине с помощью машинного обучения.
В этой статье мы увидим, как с помощью машинного обучения определить тональность конкретного твита.
Анализ тональности остается одной из ключевых проблем, в которой широко применяется обработка естественного языка. Мы получаем твиты от клиентов о различных технических фирмах, которые производят и продают мобильные телефоны, компьютеры, ноутбуки и т. Д., Задача состоит в том, чтобы определить, имеют ли твиты негативное отношение к таким компаниям или продуктам. Мы будем работать над этой проблемой, а затем классифицируем твиты как положительные или отрицательные.
Для этого мы проведем хакатон, доступный на платформе AV, и увидим, как мы можем классифицировать твиты по различным настроениям.
Полный код для этого можно найти в моем репозитории GitHub.
Итак, приступим.
Мы разделим коды на 3 категории.
- EDA (исследовательский анализ данных): некоторый исследовательский анализ поездов и тестовых данных в целом путем их объединения.
- Разработка функций: использование функций для более точного прогнозирования настроений.
- Моделирование: часть, в которой машинное обучение выходит на первый план, и мы видим результаты прогнозов.
Хватит разговоров. Покажи мне код .. !!
# importing the libraries for data processing and analysis import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import warnings %matplotlib inline plt.style.use('fivethirtyeight') warnings.filterwarnings('ignore')
Как только это будет сделано, мы продолжим загрузку поезда и тестовых данных.
train = pd.read_csv('train_sentiment.csv') test = pd.read_csv('test_sentiment.csv')
- EDA (исследовательский анализ данных)
Мы можем проверить распределение количества твитов в поезде и тестовых данных.
# checking the distribution of label of tweets in the dataset train[train['label'] == 0].head(10) train[train['label'] == 1].head(10)
Затем мы переходим к векторизации подсчета данных твита. Счетная векторизация - это процесс подсчета количества вхождений каждого слова, которое появляется в документе (т. Е. Отдельном тексте, таком как статья, книга или даже абзац!).
# count vectorization for the text from sklearn.feature_extraction.text import CountVectorizer cv = CountVectorizer(stop_words = 'english') words = cv.fit_transform(train.tweet) sum_words = words.sum(axis=0) words_freq = [(word, sum_words[0, i]) for word, i in cv.vocabulary_.items()] words_freq = sorted(words_freq, key = lambda x: x[1], reverse = True) frequency = pd.DataFrame(words_freq, columns=['word', 'freq']) frequency.head(30).plot(x='word', y='freq', kind='bar', figsize=(15, 7), color = 'brown') plt.title("Most Frequently Occuring Words - Top 30")
Еще один важный шаг EDA, который следует выполнить, - это проверка наиболее важных слов, присутствующих в данных. Итак, создание облака слов для наиболее часто встречающихся слов, присутствующих в данных поезда.
# generating word cloud for the most common occuring words in the train data from wordcloud import WordCloud wordcloud = WordCloud(background_color = 'white', width = 1000, height = 1000).generate_from_frequencies(dict(words_freq)) plt.figure(figsize=(10,8)) plt.imshow(wordcloud) plt.title("WordCloud - Vocabulary from Reviews", fontsize = 22)
Давайте также проверим наличие нейтральных слов в данных твита.
# wordcloud for words that are neutral normal_words =' '.join([text for text in train['tweet'][train['label'] == 0]]) wordcloud = WordCloud(width=800, height=500, random_state = 0, max_font_size = 110).generate(normal_words) plt.figure(figsize=(10, 7)) plt.imshow(wordcloud, interpolation="bilinear") plt.axis('off') plt.title('The Neutral Words') plt.show()
Чтобы проверить наличие хэштегов в данных, я создал функцию, которая проверяет и собирает хэштеги, присутствующие в данных, и сохраняет их в списке.
- Мы также можем видеть самые важные хэштеги, присутствующие в данных твита.
- Мы также можем проверить тип твитов и сохранить их в списке.
# defining a function to collect the hashtags from the train data def hashtags_extract(x): hashtags = [] for i in x: ht = re.findall(r"#(\w+)", i) hashtags.append(ht) return hashtags #extracting hashtags from racist/sexist tweet ht_normal = hashtags_extract(train['tweet'][train['label'] == 0]) #extracting hashtags from normal tweet ht_negetive = hashtags_extract(train['tweet'][train['label'] == 1]) #unnesting list ht_normal = sum(ht_normal , []) ht_negetive = sum(ht_negetive , [])
Как только об этом позаботятся, мы приступаем к токенизации слов, присутствующих в данных. Токенизация - важный шаг в НЛП, поскольку она помогает разбить слова до их корневой формы.
После токенизации мы создаем слово-векторную модель, используя популярную библиотеку Gensim, сохраняя размер контекстного окна 5 и размер окна 1 для модели skip-gram.
#tokenizing the words present in the training set tokenized_tweet = train['tweet'].apply(lambda x: x.split()) # importing gensim import gensim # creating a word to vector model model_w2v = gensim.models.Word2Vec( tokenized_tweet, size=200, # desired no. of features/independent variables window=5, # context window size min_count=2, sg = 1, # 1 for skip-gram model hs = 0, negative = 10, # for negative sampling workers= 2, # no.of cores seed = 34) model_w2v.train(tokenized_tweet, total_examples= len(train['tweet']), epochs=20)
Как только это будет сделано, мы сможем увидеть слова, которые; имеют значение, подобное словам, присутствующим в наборе данных. Например: - Sony ».
from tqdm import tqdm tqdm.pandas(desc="progress-bar") from gensim.models.doc2vec import LabeledSentence # Adding a label to the tweets def add_label(twt): output = [] for i, s in zip(twt.index, twt): output.append(LabeledSentence(s, ["tweet_" + str(i)])) return output # label all the tweets labeled_tweets = add_label(tokenized_tweet) labeled_tweets[:6]
Мы также должны удалить нежелательные шаблоны из данных, поскольку их сохранение добавляет шум в наш набор данных, и мы должны стараться, чтобы наша модель была максимально свободной от шума для лучшего прогнозирования.
# removing unwanted patterns from the data import re import nltk nltk.download('stopwords') from nltk.corpus import stopwords from nltk.stem.porter import PorterStemmer # collecting the train data and forming a corpus train_corpus = [] for i in range(0, 7920): review = re.sub('[^a-zA-Z]', ' ', train['tweet'][i]) review = review.lower() review = review.split() ps = PorterStemmer() # stemming review = [ps.stem(word) for word in review if not word in set(stopwords.words('english'))] # joining them back with space review = ' '.join(review) train_corpus.append(review) from sklearn.feature_extraction.text import CountVectorizer cv = CountVectorizer(max_features = 1500) x = cv.fit_transform(train_corpus).toarray() y = train.iloc[:, 1] print(x.shape) print(y.shape) # creating bag of words for test from sklearn.feature_extraction.text import CountVectorizer cv = CountVectorizer(max_features = 1500) x_test = cv.fit_transform(test_corpus).toarray() y = train.iloc[:, 1] print(x_test.shape)
Теперь проделаем то же самое с тестовыми данными.
test_corpus = [] for i in range(0, 1953): review = re.sub('[^a-zA-Z]', ' ', test['tweet'][i]) review = review.lower() review = review.split() ps = PorterStemmer() # stemming review = [ps.stem(word) for word in review if not word in set(stopwords.words('english'))] # joining them back with space review = ' '.join(review) test_corpus.append(review)
Удаление стоп-слов и лемматизация (Лемматизация, в отличие от Stemming, сокращает изменяемые слова должным образом, гарантируя, что корневое слово принадлежит языку. В лемматизации корневое слово называется леммой. Лемма (леммы множественного числа) - это лемма каноническая форма, словарная форма или форма цитирования набора слов.) также является важным шагом, когда дело доходит до обработки Естественного языка.
# removing unwanted patterns from the data import re import nltk nltk.download('stopwords') from nltk.corpus import stopwords from nltk.stem.porter import PorterStemmer # for train data train_corpus = [] for i in range(0, 7920): review = re.sub('[^a-zA-Z]', ' ', train['tweet'][i]) review = review.lower() review = review.split() ps = PorterStemmer() # stemming review = [ps.stem(word) for word in review if not word in set(stopwords.words('english'))] # joining them back with space review = ' '.join(review) train_corpus.append(review) # for test data test_corpus = [] for i in range(0, 1953): review = re.sub('[^a-zA-Z]', ' ', test['tweet'][i]) review = review.lower() review = review.split() ps = PorterStemmer() # stemming review = [ps.stem(word) for word in review if not word in set(stopwords.words('english'))] # joining them back with space review = ' '.join(review) test_corpus.append(review)
Теперь мы почти закончили с очисткой данных, а затем мы создадим пакет слов, преобразовав слова, присутствующие в корпусе, в массив, чтобы машина могла понять и обработать данные.
# creating bag of words for train # creating bag of words from sklearn.feature_extraction.text import CountVectorizer cv = CountVectorizer(max_features = 1500) x = cv.fit_transform(train_corpus).toarray() y = train.iloc[:, 1] print(x.shape) print(y.shape) ------- (7920, 1500) (7920,) # creating bag of words for test from sklearn.feature_extraction.text import CountVectorizer cv = CountVectorizer(max_features = 1500) x_test = cv.fit_transform(test_corpus).toarray() y = train.iloc[:, 1] print(x_test.shape) ------- (1953, 1500) # standardization from sklearn.preprocessing import StandardScaler sc = StandardScaler() x_train = sc.fit_transform(x_train) x_valid = sc.transform(x_valid)
Стандартизация также является важным шагом перед тем, как мы продолжим процесс моделирования.
После стандартизации мы разделяем данные для обучающих и тестовых целей.
from sklearn.model_selection import train_test_split x_train, x_valid, y_train, y_valid = train_test_split(x, y, test_size = 0.25, random_state = 42) print(x_train.shape) print(x_valid.shape) print(y_train.shape) print(y_valid.shape) --------------- (5940, 1500) (1980, 1500) (5940,) (1980,)
Метрика оценки, используемая для этого соревнования, - это оценка F1, которая формулируется как 2 * ((точность * отзыв) / (точность + отзыв)).
Когда мы закончим с этим, мы приступим к моделированию машинного обучения.
Давайте попробуем несколько методов моделирования на данных и сами увидим результат.
- Случайный лес
from sklearn.ensemble import RandomForestClassifier from sklearn.metrics import confusion_matrix from sklearn.metrics import f1_score model = RandomForestClassifier() model.fit(x_train, y_train) y_pred = model.predict(x_valid) print("Training Accuracy :", model.score(x_train, y_train)) print("Validation Accuracy :", model.score(x_valid, y_valid)) # calculating the f1 score for the validation set print("F1 score :", f1_score(y_valid, y_pred)) --------------- Training Accuracy : 0.9994949494949495 Validation Accuracy : 0.8853535353535353 F1 score : 0.7926940639269406 --------------- # confusion matrix cm = confusion_matrix(y_valid, y_pred) print(cm) --------------- [[1319 120] [ 107 434]]
2. Классификатор дерева решений
from sklearn.tree import DecisionTreeClassifier model = DecisionTreeClassifier() model.fit(x_train, y_train) y_pred = model.predict(x_valid) print("Training Accuracy :", model.score(x_train, y_train)) print("Validation Accuracy :", model.score(x_valid, y_valid)) # calculating the f1 score for the validation set print("f1 score :", f1_score(y_valid, y_pred)) # confusion matrix cm = confusion_matrix(y_valid, y_pred) print(cm) ---------------- Training Accuracy : 0.9994949494949495 Validation Accuracy : 0.8378787878787879 f1 score : 0.700280112044818 [[1284 155] [ 166 375]]
3. Моделирование SVM
# trying SVC algorithm on the data from sklearn.svm import SVC model = SVC() model.fit(x_train, y_train) y_pred = model.predict(x_valid) print("Training Accuracy :", model.score(x_train, y_train)) print("Validation Accuracy :", model.score(x_valid, y_valid)) # calculating the f1 score for the validation set print("f1 score :", f1_score(y_valid, y_pred)) # confusion matrix cm = confusion_matrix(y_valid, y_pred) print(cm) ---------------- Training Accuracy : 0.9644781144781145 Validation Accuracy : 0.8621212121212121 f1 score : 0.7222787385554426 [[1352 87] [ 186 355]]
4. Классификатор XG Boost
# trying xgboost classifier on the data from xgboost import XGBClassifier model = XGBClassifier() model.fit(x_train, y_train) y_pred = model.predict(x_valid) print("Training Accuracy :", model.score(x_train, y_train)) print("Validation Accuracy :", model.score(x_valid, y_valid)) # calculating the f1 score for the validation set print("f1 score :", f1_score(y_valid, y_pred)) # confusion matrix cm = confusion_matrix(y_valid, y_pred) print(cm) ------------------- Training Accuracy : 0.8882154882154882 Validation Accuracy : 0.8792929292929293 f1 score : 0.7912663755458514 [[1288 151] [ 88 453]]
5. Логистическая регрессия
from sklearn.linear_model import LogisticRegression model = LogisticRegression() model.fit(x_train, y_train) y_pred = model.predict(x_valid) print("Training Accuracy :", model.score(x_train, y_train)) print("Validation Accuracy :", model.score(x_valid, y_valid)) # calculating the f1 score for the validation set print("f1 score :", f1_score(y_valid, y_pred)) # confusion matrix cm = confusion_matrix(y_valid, y_pred) print(cm) ---------------- Training Accuracy : 0.9757575757575757 Validation Accuracy : 0.8323232323232324 f1 score : 0.6897196261682242 [[1279 160] [ 172 369]]
Итак, после использования 5 алгоритмов на данных поезда и тестирования того же на тестовых данных, мы можем справедливо прийти к выводу, что алгоритм случайного леса показал самую высокую точность среди всех остальных алгоритмов, которые успешно классифицировали твиты как положительные и отрицательные. с точностью 79,2%.
Заключение
Twitter стал неотъемлемой частью нашей жизни для большинства из нас. Один твит может повлиять на продажи продукта компании или нанести ущерб сообществу твиттера, если твит становится вирусным, я имею в виду, и люди каждый раз продолжают публиковать всевозможные твиты, полные различных настроений. Итак, как специалисты по анализу данных, мы должны уметь расшифровывать негативные настроения, связанные с твитом, на позитивные, которые, в свою очередь, используются компаниями для оценки эффективности запуска продукта или маркетинговой рекламы.
В будущем потребность в классификации настроений значительно возрастет, поскольку все больше и больше людей становятся технически подкованными.
И это возможность для компаний опередить своих конкурентов, оценивая отзывы о своих обзорах продуктов, чтобы получить дополнительные доходы на постоянно растущем конкурентном рынке.
Итак, вот и все в этом. До скорого. Чао..!!!