Введение

Мы знаем, что большинство данных, генерируемых в нашей повседневной жизни, представляют собой неструктурированные данные. Мы используем WhatsApp, Facebook, Instagram и т. д. Мы отправляем сообщения, размещаем фотографии, видео и т. д. В этом свете анализ неструктурированных данных имеет первостепенное значение, поскольку он будет иметь ценность, и мы сможем извлечь из него полезную информацию. В этой статье мы возьмем текстовые данные предвыборной речи премьер-министра Индии Нарендры Моди в Западной Бенгалии в качестве примера и проанализируем важные показатели его речи.

Речь — зеркало души; Как человек говорит, таков и он.

- Публий Сир

Давай приступим к работе

Инициализация

Импортируем основные библиотеки для анализа.

#Import the requisite packages for analysis
import pandas as pd     
from urllib.request import Request,urlopen   
from bs4 import BeautifulSoup as soup
import nltk   #required library for text analytics
import operator  
from nltk.corpus import stopwords
from wordcloud import WordCloud
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline

Здесь основными библиотеками являются urllib и BeautifulSoup для доступа к данным в удобочитаемом формате. У нас есть библиотека nltk для базовой предварительной обработки текста и matplotlib, WordCloud для визуализации.

Доступ к данным

#store the web url in variable url
url = 'https://www.bjp.org/en/speechdetail/4542801/Salient-points-of-speech-of-Hon-ble-Prime-Minister-Shri-Narendra-Modi-addressing-public-meetings-in-West-Bengal-'
# Launch a formal request to the website server
req = Request(url,headers={'User-Agent':'Mozilla/5.0'})
#Read the webpage
webpage = urlopen(req).read()
#Use Beautiful Soup to parse the html webpage
Soup = soup(webpage,"html.parser")
# Get the text from the soup & store in data
data = Soup.getText()

Мы взяли речь, с которой премьер-министр Нарендра Моди выступил на предвыборном митинге 10 апреля 2021 года в Силигури. Вы можете посетить URL-адрес веб-сайта, чтобы прочитать всю речь. Обратите внимание: речь на хинди.

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

Теперь, когда у нас есть данные. Давайте посмотрим, что содержит переменная «данные».

print(data)

Мы видим, что метод Beautiful Soup извлек весь текст с сайта. Мы должны очистить извлеченный текст, чтобы у нас остались только те слова, которые нам нужны.

Здесь мы выполняем операции, как указано ниже,

  1. Токенизация и нормализация. Мы удалим из этого текста все знаки препинания и ненужные символы. При внимательном наблюдении мы заменяем текст, используя метод «replace» для следующих символов, и преобразуем предложение в список слов, используя «split».
#Remove garbage charachters, then, Tokenize & Normalize.
tokens = data.replace("\n"," ").replace('*'," ").replace(',',' ').replace('।'," ").lower().split()
print(tokens)

Токенизация: разделение предложения или абзаца на более мелкие части. В нашем случае слова.

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

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

#Defining the stopwords for Hindi.
sw_hi = pd.read_csv("sw.txt", sep="\t",names=['stopword'])
#dataframe of stop words indicating positive & negative sentiments. 
pos_hi = pd.read_csv("pos.txt", sep="\t", names=['positive'])
neg_hi = pd.read_csv("neg.txt", sep="\t", names=['negative'])
#source -> https://www.kaggle.com/ruchi798/hindi-stopwords
#Defining the stopwords for English using NLTK.
sw_en = set(stopwords.words('english'))

Сопоставление частоты слов и построение графиков

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

# Stopwords filtering
filtered_words =[] #stores words which are not in any stopword list
en_sw = []   #stores english stopwords
hi_sw = []   #stores hindi stopwords
hi_possw=[]  #stores hindi postive stopwords
hi_negsw=[]  #stores negative positive stopwords
    
    for w in tokens:
        if w in neg_hi:
            hi_negsw.append(w)
        elif w in sw_en:
            en_sw.append(w)
        elif w in sw_hi:
            hi_sw.append(w)
        elif w in pos_hi:
            hi_possw.append(w)
        else:
            filtered_words.append(w)

Далее мы создадим частотное распределение и отсортируем его в порядке убывания, чтобы получить данные о наиболее часто используемых словах.

Freq_dist_fil =nltk.FreqDist(filtered_words)
Freq_dist_pos =nltk.FreqDist(hi_possw)
Freq_dist_neg =nltk.FreqDist(hi_negsw)
sorted_fil = sorted(Freq_dist_fil.items(),key=operator.itemgetter(1),reverse=True)
sorted_pos = sorted(Freq_dist_pos.items(),key=operator.itemgetter(1),reverse=True)
sorted_neg = sorted(Freq_dist_neg.items(),key=operator.itemgetter(1),reverse=True)

Далее мы построим график частотной линии и облако слов для каждого из распределений слов.

# filtered words
print(sorted_fil[0:20])
fil= pd.DataFrame(filtered_words,columns=['fil_words'])        
filter_words = fil.groupby('fil_words').agg({'fil_words':'count'}).rename(columns={'fil_words':'Frequency'}).sort_values(by='Frequency',ascending=False)
# Generate a word cloud image
wordcloud = WordCloud(font_path='NirmalaB.ttf',stopwords = sw_hi,background_color='white')
data = dict(sorted_fil)
word = wordcloud.generate_from_frequencies(data)
    
    
plt.figure(figsize=(15,5))
plt.subplot(121)
plt.plot(filter_words[:20])
plt.xticks(fontname='Nirmala UI',rotation='vertical')
plt.title('Frequency of Words used in website')
plt.subplot(122)
plt.imshow(word.to_image())
plt.title('Wordcloud Frequency')
plt.show();

#positive words
print(sorted_pos[0:20])
pos= pd.DataFrame(hi_possw,columns=['pos_words'])        
pos_words = pos.groupby('pos_words').agg({'pos_words':'count'}).rename(columns={'pos_words':'Frequency'}).sort_values(by='Frequency',ascending=False)
data_pos = dict(sorted_pos)
word_pos = wordcloud.generate_from_frequencies(data_pos)
plt.figure(figsize=(15,5))
plt.subplot(121)
plt.plot(pos_words[:20])
plt.xticks(fontname='Nirmala UI',rotation='vertical')
plt.title('Frequency of postive words')
plt.subplot(122)
plt.imshow(word_pos.to_image())
plt.title('Postive words wordcloud')
plt.show();

#negative words
print(sorted_neg[0:20])
neg= pd.DataFrame(hi_negsw,columns=['neg_words'])        
neg_words = neg.groupby('neg_words').agg({'neg_words':'count'}).rename(columns={'neg_words':'Frequency'}).sort_values(by='Frequency',ascending=False)
data_neg = dict(sorted_neg)
word_neg = wordcloud.generate_from_frequencies(data_neg)
plt.figure(figsize=(15,5))
plt.subplot(121)
plt.plot(neg_words[:20])
plt.xticks(fontname='Nirmala UI',rotation='vertical')
plt.title('Frequency of negative words')
plt.subplot(122)
plt.imshow(word_neg.to_image())
plt.title('Negative words wordcloud')
plt.show();

Инсайты

Отфильтрованные слова:

(‘दीदी’, 76) , (‘टीएमसी’, 15): Его речь была сосредоточена на правящей партии и главном министре ВБ, широко известном как «диди».

(‘बंगाल’, 59) : Это очевидное слово, так как митинг был в WB.

('bjp', 30), ('भाजपा', 20): Эти слова в речи могут быть связаны с тем, что часть BJP может показать как правящая партия, которую он часто упоминает.

Положительные слова:

('सुरक्षा', 6),('सम्मान', 6) ,('मुक्त', 6),('संरक्षण', 4), ('लाभ', 4) ( 'परिवर्तन', 3), ('नया ', 3). Это слова, которые употребляются в речи, идентифицируются как положительные слова. Эти слова могут повлиять на общественное мнение, обещая гордость, безопасность, перемены и рассвет новой эры.

Минус-слова:

('समस्या', 8), ('सख्त', 5), ('भय', 5), ('गलत', 5), ('गुस्सा', 5), ('हार', 4), (' अत्याचार', 3), ('अपमान', 3), ('बुराई', 2), ('हिंसक', 2), ('खिलवाड़', 2), ('डराने', 2), ('डर' , 2), ('अन्याय', 2), ('बोझ', 2), ('हत्या', 2). Это слова в речи, которые могут указывать на зверства или несправедливость по отношению к народу Бенгалии.

Заключение:

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