<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>NLP on Laminar Insight</title>
    <link>https://laminarinsight.com/tags/nlp/</link>
    <description>Recent content in NLP on Laminar Insight</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Tue, 30 Mar 2021 00:00:00 +0000</lastBuildDate>
    
        <atom:link href="https://laminarinsight.com/tags/nlp/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Text Analysis on Youtube Videos Posted About ‘Bangladesh’</title>
      <link>https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/</link>
      <pubDate>Tue, 30 Mar 2021 00:00:00 +0000</pubDate>
      
      <guid>https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/</guid>
      <description>
&lt;script src=&#34;https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/index_files/header-attrs/header-attrs.js&#34;&gt;&lt;/script&gt;

&lt;div id=&#34;TOC&#34;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#part-01-background-about-this-project&#34;&gt;Part 01: Background about this project&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#part-02-data-collection&#34;&gt;Part 02: Data collection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#part-03-data-cleaning&#34;&gt;Part 03: Data cleaning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#part-04-data-analysis&#34;&gt;Part 04: Data analysis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#part-05-ending&#34;&gt;Part 05: Ending&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;div id=&#34;part-01-background-about-this-project&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Part 01: Background about this project&lt;/h2&gt;
&lt;p&gt;This analysis is part of an ongoing exploratory study about the contents related to &lt;a href=&#34;https://en.wikipedia.org/wiki/Bangladesh&#34;&gt;Bangladesh&lt;/a&gt; in different online social media platforms. In the last &lt;a href=&#34;https://rpubs.com/arafath/twitter_analysis&#34;&gt;article&lt;/a&gt; tweets that containing &lt;em&gt;Bangladesh&lt;/em&gt; were analyzed to understand the most common areas that people tweeted about Bangladesh and how public sentiments were reflected. In this article a similar study will be conducted on the videos shared on Youtube that have &lt;em&gt;Bangladesh&lt;/em&gt; in their titles. To collect the data YouTube’s publicly available API will be used. Along with the video stats, comments posted by viewers will also be fetched and analyzed.&lt;/p&gt;
&lt;p&gt;The analysis is segmented broadly into two phases:&lt;/p&gt;
&lt;ol style=&#34;list-style-type: decimal&#34;&gt;
&lt;li&gt;Extracting insights from the overall statistics of the videos and&lt;/li&gt;
&lt;li&gt;Extracting insights from the unstructured data (e.g. comments) by applying different text analytics techniques.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Some of the key goals of this analysis are to see:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What kind of videos are posted?&lt;/li&gt;
&lt;li&gt;Is there any trend in the number of video posted with the time when they are posted?&lt;/li&gt;
&lt;li&gt;What kind of videos are mostly liked and disliked?&lt;/li&gt;
&lt;li&gt;Which videos get most traction with their viewers?&lt;/li&gt;
&lt;li&gt;Videos around which topics are mostly posted?&lt;/li&gt;
&lt;li&gt;Do the trend of video posting vary based on different types of videos?&lt;/li&gt;
&lt;li&gt;How do people react or express their sentiment in the comment section?&lt;/li&gt;
&lt;li&gt;Do sentiment change over the time?&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div id=&#34;part-02-data-collection&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Part 02: Data collection&lt;/h2&gt;
&lt;p&gt;The required data for this analysis has been scraped using public API provided by YouTube. Time line considered is the whole year (2017-2018). Scraping YouTube produced a pool of 585 unique videos which have &lt;em&gt;Bangladesh&lt;/em&gt; mentioned in their titles. These videos were posted from total 377 different channels. An easy to follow step by step process of how to connect with YouTube using &lt;strong&gt;tuber&lt;/strong&gt; package can be found in this link: &lt;a href=&#34;https://www.youtube.com/watch?v=NEh5N3OZCXc&#34; class=&#34;uri&#34;&gt;https://www.youtube.com/watch?v=NEh5N3OZCXc&lt;/a&gt; and the codes used to scrape data for this project can be seen by un-hiding the following code chunk.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# credentials 
app_id = &amp;#39;Your_app_id&amp;#39;
app_secret = &amp;#39;your_app_secret&amp;#39;
# establishing connecting with YouTube
yt_oauth(app_id = app_id, app_secret = app_secret)

# ---fetching YouTube videos with &amp;#39;bangladesh&amp;#39; in the title---
# searching for videos that have &amp;#39;Bangladesh&amp;#39; in the title
videos_year &amp;lt;- yt_search(&amp;quot;Bangladesh&amp;quot;, published_after = &amp;quot;2017-6-01T00:00:00Z&amp;quot;, published_before = &amp;quot;2018-1-1T00:00:00Z&amp;quot;)
# fetching video statistics for all videos (2017-2018)
videostats = lapply(as.character(videos_year$video_id), function(x){
  get_stats(video_id = x)
})
df = ldply(videostats, data.frame)

# merging videos stats with the main file:  videos_year
colnames(df)[1] = &amp;#39;video_id&amp;#39; # renaming &amp;#39;id&amp;#39; as video_id so that it matches same coluimn in main table
videos_year = videos_year %&amp;gt;% left_join(df, by = &amp;#39;video_id&amp;#39;)

# correcting data type
videos_year[,c(&amp;#39;viewCount&amp;#39;, &amp;#39;likeCount&amp;#39;, &amp;#39;dislikeCount&amp;#39;, &amp;#39;favoriteCount&amp;#39;, &amp;#39;commentCount&amp;#39;)]=apply(videos_year[,c(&amp;#39;viewCount&amp;#39;, &amp;#39;likeCount&amp;#39;, &amp;#39;dislikeCount&amp;#39;, &amp;#39;favoriteCount&amp;#39;, &amp;#39;commentCount&amp;#39;)],2,as.numeric)
# write.csv(videos_year,&amp;#39;youtube_video_raw+stat_2017-2018.csv&amp;#39;, row.names = FALSE)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div id=&#34;part-03-data-cleaning&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Part 03: Data cleaning&lt;/h2&gt;
&lt;p&gt;In the last part we have collected video specific statistics and compiled all in a single file named &lt;strong&gt;videos_year&lt;/strong&gt;. A look into the file reveals that it contains 589 observations/rows and 21 variables/columns. Or in other words we have 21 different attributes collected for each of the videos. To look at the variables some basic summary codes have been run and the results are shown below:&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;videos_year = read.csv(&amp;#39;../../../source_files/youtube_video_raw+stat_2017-2018.csv&amp;#39;)
dim(videos_year)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## [1] 589  21&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;names(videos_year)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##  [1] &amp;quot;video_id&amp;quot;                  &amp;quot;publishedAt&amp;quot;              
##  [3] &amp;quot;channelId&amp;quot;                 &amp;quot;title&amp;quot;                    
##  [5] &amp;quot;description&amp;quot;               &amp;quot;thumbnails.default.url&amp;quot;   
##  [7] &amp;quot;thumbnails.default.width&amp;quot;  &amp;quot;thumbnails.default.height&amp;quot;
##  [9] &amp;quot;thumbnails.medium.url&amp;quot;     &amp;quot;thumbnails.medium.width&amp;quot;  
## [11] &amp;quot;thumbnails.medium.height&amp;quot;  &amp;quot;thumbnails.high.url&amp;quot;      
## [13] &amp;quot;thumbnails.high.width&amp;quot;     &amp;quot;thumbnails.high.height&amp;quot;   
## [15] &amp;quot;channelTitle&amp;quot;              &amp;quot;liveBroadcastContent&amp;quot;     
## [17] &amp;quot;viewCount&amp;quot;                 &amp;quot;likeCount&amp;quot;                
## [19] &amp;quot;dislikeCount&amp;quot;              &amp;quot;favoriteCount&amp;quot;            
## [21] &amp;quot;commentCount&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From the variable names we can see that there are data (e.g. thumbnails related data) that are out of scope of this analysis. We can take a look at the summary statistics of the other variables to have an idea about the necessary data cleaning.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;str(videos_year[c(&amp;#39;publishedAt&amp;#39;,&amp;#39;channelId&amp;#39;,&amp;#39;title&amp;#39;,&amp;#39;description&amp;#39;,&amp;#39;channelTitle&amp;#39;,
                  &amp;#39;liveBroadcastContent&amp;#39;,&amp;#39;viewCount&amp;#39;,&amp;#39;likeCount&amp;#39;,&amp;#39;dislikeCount&amp;#39;, &amp;#39;favoriteCount&amp;#39;,&amp;#39;commentCount&amp;#39;)])&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## &amp;#39;data.frame&amp;#39;:    589 obs. of  11 variables:
##  $ publishedAt         : chr  &amp;quot;2017-07-27T22:21:56.000Z&amp;quot; &amp;quot;2017-10-27T15:37:33.000Z&amp;quot; &amp;quot;2017-11-22T14:59:50.000Z&amp;quot; &amp;quot;2017-07-04T06:18:32.000Z&amp;quot; ...
##  $ channelId           : chr  &amp;quot;UCNye-wNBqNL5ZzHSJj3l8Bg&amp;quot; &amp;quot;UCXulruMI7BHj3kGyosNa0jA&amp;quot; &amp;quot;UCXulruMI7BHj3kGyosNa0jA&amp;quot; &amp;quot;UCqlc8Q5Rixjp_zTePTI_mRg&amp;quot; ...
##  $ title               : chr  &amp;quot;&amp;lt;f0&amp;gt;&amp;lt;U+009F&amp;gt;&amp;lt;U+0087&amp;gt;&amp;lt;U+00A7&amp;gt;&amp;lt;f0&amp;gt;&amp;lt;U+009F&amp;gt;&amp;lt;U+0087&amp;gt;&amp;lt;U+00A9&amp;gt; Bangladesh&amp;#39;s Biggest Brothel | 101 East | &amp;lt;U+092C&amp;gt;&amp;lt;U+0&amp;quot;| __truncated__ &amp;quot;HELLO BANGLADESH. DHAKA IS CRAZY.&amp;quot; &amp;quot;HOW EXPENSIVE IS BANGLADESH? &amp;lt;f0&amp;gt;&amp;lt;U+009F&amp;gt;&amp;lt;U+0092&amp;gt;&amp;lt;U+00B0&amp;gt;&amp;lt;f0&amp;gt;&amp;lt;U+009F&amp;gt;&amp;lt;U+0087&amp;gt;&amp;lt;U+00A7&amp;gt;&amp;lt;f0&amp;gt;&amp;lt;U+009F&amp;gt;&amp;lt;U+0087&amp;gt;&amp;lt;U+00A9&amp;gt;&amp;quot; &amp;quot;Bangladesh Biman With  CG For Sefty&amp;quot; ...
##  $ description         : chr  &amp;quot;The biggest brothel in Bangladesh - and possibly the world. The town of Daulatdia is home to 1500 prostitutes, &amp;quot;| __truncated__ &amp;quot;VLOG #146. Let me know your thoughts in the comments section PATREON: https://www.patreon.com/indigotraveller o&amp;quot;| __truncated__ &amp;quot;INSTAGRAM - https://www.goo.gl/hvrnHZ FACEBOOK - https://www.goo.gl/98tqkZ VLOG #156. Let me know your thoughts&amp;quot;| __truncated__ &amp;quot;&amp;quot; ...
##  $ channelTitle        : chr  &amp;quot;Al Jazeera English&amp;quot; &amp;quot;Indigo Traveller&amp;quot; &amp;quot;Indigo Traveller&amp;quot; &amp;quot;Bhaishob Media&amp;quot; ...
##  $ liveBroadcastContent: chr  &amp;quot;none&amp;quot; &amp;quot;none&amp;quot; &amp;quot;none&amp;quot; &amp;quot;none&amp;quot; ...
##  $ viewCount           : int  10456088 297082 400570 2867726 1098161 745213 901613 586726 17040399 249231 ...
##  $ likeCount           : int  21569 6862 12307 13686 7964 16885 6824 2551 67524 2696 ...
##  $ dislikeCount        : int  5862 463 361 1553 732 521 747 560 10818 482 ...
##  $ favoriteCount       : int  0 0 0 0 0 0 0 0 0 0 ...
##  $ commentCount        : int  5478 3530 3446 432 342 4243 2024 133 2978 392 ...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Looking at summary stat of other variabes we can identify these issues:
1. Variable &lt;em&gt;publishedA&lt;/em&gt;’ contains date data in a wrong format. Which needs to be changed into date format for convenience of future analysis.
2. Variables containing text data ( &lt;em&gt;title&lt;/em&gt; and &lt;em&gt;description&lt;/em&gt;) need text cleaning since they have HTML codes which don’t have any value in terms of generating meaningful insight
In the next three code chunks, these two issues will be fixed.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# converting into data type &amp;#39;date&amp;#39;
videos_year$publishedAt = as.Date(videos_year$publishedAt)
str(videos_year$publishedAt)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##  Date[1:589], format: &amp;quot;2017-07-27&amp;quot; &amp;quot;2017-10-27&amp;quot; &amp;quot;2017-11-22&amp;quot; &amp;quot;2017-07-04&amp;quot; &amp;quot;2017-08-24&amp;quot; ...&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# creating new variables &amp;#39;year&amp;#39; and &amp;#39;month&amp;#39;
videos_year = videos_year %&amp;gt;% mutate(month = month(publishedAt)) %&amp;gt;% mutate(year = year(publishedAt))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From above results we can see that data type of variabled named &lt;em&gt;publishedAt&lt;/em&gt; has been converted to ‘date’. Two new variables named &lt;em&gt;year&lt;/em&gt; and &lt;em&gt;month&lt;/em&gt; have been created from the &lt;em&gt;publishedAt&lt;/em&gt; variable to use in future analysis. Now we will move on to cleaning the text values in &lt;em&gt;title&lt;/em&gt; variable.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;head(videos_year$title,5)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## [1] &amp;quot;&amp;lt;f0&amp;gt;&amp;lt;U+009F&amp;gt;&amp;lt;U+0087&amp;gt;&amp;lt;U+00A7&amp;gt;&amp;lt;f0&amp;gt;&amp;lt;U+009F&amp;gt;&amp;lt;U+0087&amp;gt;&amp;lt;U+00A9&amp;gt; Bangladesh&amp;#39;s Biggest Brothel | 101 East | &amp;lt;U+092C&amp;gt;&amp;lt;U+093E&amp;gt;&amp;lt;U+0902&amp;gt;&amp;lt;U+0917&amp;gt;&amp;lt;U+094D&amp;gt;&amp;lt;U+0932&amp;gt;&amp;lt;U+093E&amp;gt;&amp;lt;U+0926&amp;gt;&amp;lt;U+0947&amp;gt;&amp;lt;U+0936&amp;gt; &amp;lt;U+0915&amp;gt;&amp;lt;U+0940&amp;gt; &amp;lt;U+0938&amp;gt;&amp;lt;U+092C&amp;gt;&amp;lt;U+0938&amp;gt;&amp;lt;U+0947&amp;gt; &amp;lt;U+092C&amp;gt;&amp;lt;U+0921&amp;gt;&amp;lt;U+093C&amp;gt;&amp;lt;U+0940&amp;gt; &amp;lt;U+0935&amp;gt;&amp;lt;U+0947&amp;gt;&amp;lt;U+0936&amp;gt;&amp;lt;U+094D&amp;gt;&amp;lt;U+092F&amp;gt;&amp;lt;U+093E&amp;gt;&amp;lt;U+0932&amp;gt;&amp;lt;U+092F&amp;gt;&amp;quot;
## [2] &amp;quot;HELLO BANGLADESH. DHAKA IS CRAZY.&amp;quot;                                                                                                                                                                                                                                                                                                      
## [3] &amp;quot;HOW EXPENSIVE IS BANGLADESH? &amp;lt;f0&amp;gt;&amp;lt;U+009F&amp;gt;&amp;lt;U+0092&amp;gt;&amp;lt;U+00B0&amp;gt;&amp;lt;f0&amp;gt;&amp;lt;U+009F&amp;gt;&amp;lt;U+0087&amp;gt;&amp;lt;U+00A7&amp;gt;&amp;lt;f0&amp;gt;&amp;lt;U+009F&amp;gt;&amp;lt;U+0087&amp;gt;&amp;lt;U+00A9&amp;gt;&amp;quot;                                                                                                                                                                                                                      
## [4] &amp;quot;Bangladesh Biman With  CG For Sefty&amp;quot;                                                                                                                                                                                                                                                                                                    
## [5] &amp;quot;Bangladesh Beats West Indies all out for 61 runs (Lowest Score ever)&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first 10 titles shown above show the uncleaned raw labels or video titles that exist now in the dataset. And the 5 titles shown below are the cleaned titles after cleaning the raw titles using different regular expressions.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# cleaning video titles
videos_year$title= gsub(&amp;quot;&amp;lt;.*?&amp;gt;&amp;quot;,&amp;quot;&amp;quot;, videos_year$title) #removing html tags
videos_year$title= gsub(&amp;quot;[[:punct:]]&amp;quot;, &amp;quot; &amp;quot;, videos_year$title) #removing html tags
videos_year$title = gsub(&amp;quot;[ |\t]{2,}&amp;quot;, &amp;quot; &amp;quot;, videos_year$title)  # Remove tabs
videos_year$title = gsub(&amp;quot;^ &amp;quot;, &amp;quot;&amp;quot;, videos_year$title)  # Leading blanks
videos_year$title = gsub(&amp;quot; $&amp;quot;, &amp;quot;&amp;quot;, videos_year$title)  # Lagging blanks
videos_year$title = gsub(&amp;quot; +&amp;quot;, &amp;quot; &amp;quot;, videos_year$title) # General spaces 
videos_year$title = tolower(videos_year$title) # lowering all letters
head(videos_year$title,5)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## [1] &amp;quot;bangladesh s biggest brothel 101 east&amp;quot;                             
## [2] &amp;quot;hello bangladesh dhaka is crazy&amp;quot;                                   
## [3] &amp;quot;how expensive is bangladesh&amp;quot;                                       
## [4] &amp;quot;bangladesh biman with cg for sefty&amp;quot;                                
## [5] &amp;quot;bangladesh beats west indies all out for 61 runs lowest score ever&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this stage, before enterign into the data analysis we’ll create three more variables that contain the ratios of likes, dislikes and comments against the total views of respective video. Having this ratios will help us in future to extract insights without bias by considering ratios rather than the absolute numbers.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# creating like, dislike, comment ratio
videos_year = videos_year %&amp;gt;%
  mutate(like_ratio = likeCount/viewCount) %&amp;gt;% 
  mutate(dislike_ratio = dislikeCount/viewCount) %&amp;gt;%
  mutate(comment_ratio = commentCount/viewCount) %&amp;gt;% 
  mutate(ratio_to_total = viewCount/sum(viewCount, na.rm = TRUE))

# names(videos_year)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div id=&#34;part-04-data-analysis&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Part 04: Data analysis&lt;/h2&gt;
&lt;p&gt;To start off, we can look at some basic statistics such as monthly video posting frequency, most viewed, liked, disliked and commented videos and so on.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;#month wise video posting (data = videos_year)
videos_year %&amp;gt;%
  group_by(factor(month)) %&amp;gt;%
  mutate(total = n()) %&amp;gt;%
  ungroup() %&amp;gt;%
  ggplot(aes(x = month, y = total)) + 
  geom_line(color = &amp;quot;#27408b&amp;quot;) + 
  geom_point(shape=21,fill=&amp;quot;white&amp;quot;,color=&amp;quot;#27408b&amp;quot;,size=3,stroke=1.1) + 
  scale_x_continuous(breaks = seq(1,12,1), labels = c(&amp;quot;Jan&amp;quot;,&amp;quot;Feb&amp;quot;,&amp;quot;Mar&amp;quot;,&amp;quot;Apr&amp;quot;,&amp;quot;May&amp;quot;,
                                                      &amp;quot;Jun&amp;quot;,&amp;quot;Jul&amp;quot;,&amp;quot;Aug&amp;quot;,&amp;quot;Sep&amp;quot;,&amp;quot;Oct&amp;quot;,
                                                      &amp;quot;Nov&amp;quot;,&amp;quot;Dec&amp;quot;)) +
  labs(x=&amp;quot;Month&amp;quot;,y=&amp;quot;Number of videos&amp;quot;,
       title=&amp;quot;Month wise frequency of video posting&amp;quot;,
       subtitle=&amp;quot;subtitle = &amp;#39;Year 2017 to 2018&amp;#39;&amp;quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/index_files/figure-html/unnamed-chunk-7-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;From above chart we can see that there was a growing trend starting from August which reached at its peak in October and then again gradually fell. Other than August the other two months with unusual spikes are March and June. Now let’s look at the most viewed videos and also see in which month they were posted.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# most viewed videos
videos_year %&amp;gt;% arrange(desc(viewCount)) %&amp;gt;% head(20) %&amp;gt;%
  mutate(title = strtrim(title, 25)) %&amp;gt;%
  mutate(title = reorder(title,viewCount)) %&amp;gt;% top_n(20) %&amp;gt;% 
  ggplot(aes(as.factor(title), (viewCount/1000000), fill = factor(month))) + 
  geom_col()  + 
  scale_x_discrete() +
  coord_flip() +
  ggtitle(label = &amp;#39;Top 20 most viewed videos&amp;#39;) + 
  xlab(label = &amp;#39;Video title&amp;#39;) + 
  ylab(label = &amp;#39;Number of views (in millions)&amp;#39;) +
  labs(fill = &amp;#39;Month&amp;#39;, caption = &amp;#39;* Video titles have been truncated&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/index_files/figure-html/unnamed-chunk-8-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;From the abundance of paste and green color in the above plot we can immediately tell that most of the most viewed viewed videos were posted during the month of June and July. In addition to that some other observations can also be made from this plot:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There is a wide dispersion among the videos in terms of count ofviews. The highest viewed video has a quite a large gap from the second most viewed video. And a similar gap is observed between the other videos too. Which means the ratio variables created earlier during data cleaning and feature engineering stage will come handy in further analysis by helping us overcome the imbalance in the absolute numbers.&lt;/li&gt;
&lt;li&gt;Similar to what we have seen during the analysis of tweets regarding Bangladesh, there are multiple videos related to Cricket in this list of top 20 most viewed videos.&lt;/li&gt;
&lt;li&gt;But unlike the last analysis there are multiple videos, including two out of the top five, about brothel in Bangladesh. To understand the reason a manual inspection of the related videos reveals that all the three videos in the top 20 videos are about a specific brothel situated in a small town called &lt;em&gt;Doulatdia&lt;/em&gt; in the southern part of Bangladesh. But why would that brothel be a center of attraction for YouTubes? The answer can be found from a closer look at the top three viewed videos. &lt;a href=&#34;https://www.aljazeera.com/&#34;&gt;Aljazeera&lt;/a&gt;, a middle eastern news channel published a documentary in June, which is the fifth most viewed video on this brothel. The rest of the two videos were posted from another channel with no credible record like Aljazeera.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So what are the other videos about? We already have got a basic understanding on what the top viewed videos were about. Now to have a deeper understanding about the common discussion areas of all the videos, we will use different key word extraction techniques for this purpose.&lt;/p&gt;
&lt;p&gt;As a first step, let’s transform our text data into a matrix, more precisely a ‘Document Term Matrix’. Where each word in the text corpus is separated and columns are created for each of these words. Then each sentence is plotted as a row and the columns containing words that are in each docs/sentece get a score of 1 and others 0. Which eventually creates a sparse matrix with lots of zeros. In our case the sparsity is really high (very close to 100%) meaning that there are lots of zeros or in other words there is a wide variety in the titles of the videos.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;videos_year$title = removeWords(as.character(videos_year$title), stopwords(&amp;#39;english&amp;#39;))
videos_year_title &amp;lt;- enc2utf8(videos_year$title)
corpus = Corpus(VectorSource(videos_year_title))

dtm = DocumentTermMatrix(corpus)
dtm&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## &amp;lt;&amp;lt;DocumentTermMatrix (documents: 589, terms: 1552)&amp;gt;&amp;gt;
## Non-/sparse entries: 3715/910413
## Sparsity           : 100%
## Maximal term length: 23
## Weighting          : term frequency (tf)&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;doc.length = apply(dtm, 1, sum)
dtm = dtm[doc.length &amp;gt; 0,]
inspect(dtm[10:11,])&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## &amp;lt;&amp;lt;DocumentTermMatrix (documents: 2, terms: 1552)&amp;gt;&amp;gt;
## Non-/sparse entries: 13/3091
## Sparsity           : 100%
## Maximal term length: 23
## Weighting          : term frequency (tf)
## Sample             :
##     Terms
## Docs aprilia bangladesh bikes border dhaka eskaton expensive ktm new road
##   10       1          1     1      0     1       1         1   1   1    1
##   11       0          1     0      1     0       0         0   0   0    0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From above we can see a summary of our document term matrix. Which shows sparsity of 100% (which should be very close to 100 not exactly 100). We can take a look at some of the sentences in from the matrix. Above 10th and 11th sentences have been fetched as example. We can see that 10th sentence contains all the words except ‘border’ while 11th sentence contains only two words ‘bangladesh’ and ‘border’ from the columns that were fetched as an example.&lt;/p&gt;
&lt;p&gt;Now let’s take a look at the most frequently used words.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;freq = colSums(as.matrix(dtm))
length(freq)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## [1] 1552&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;ord = order(freq, decreasing = TRUE)
freq[head(ord, n = 20)]&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##  bangladesh        2017       dhaka       india         top     company 
##         614         106          45          44          39          39 
##    skydance       dance    rohingya performance     wedding       match 
##          38          36          34          32          30          29 
##       world         new      bangla        army     myanmar        news 
##          25          23          19          19          18          17 
##       price       video 
##          15          14&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Bangladesh and 2017 are the top two most frequent words for obvious reason. The third most frequent word is Dhaka, the capital of Bangladesh. Interestingly we see a similar trend here as we have seen in the our last analysis about tweets, there are quite an interest about the neighboring countries. In this case we see videos that have mentions of India and Myanmar. Also we see &lt;em&gt;rohingya&lt;/em&gt; is one of the most frequent words here too. There is a seemingly unusual prevalence of dance related words can be observed among the most frequent words. Looking at the words correlation may give us a better understanding.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;#library &amp;#39;tibble&amp;#39; provides the rowname_to_columns to name row names column
df1=as.data.frame(findAssocs(dtm,&amp;#39;rohingya&amp;#39;,.24)) %&amp;gt;% rownames_to_column(&amp;quot;words&amp;quot;)
df2=as.data.frame(findAssocs(dtm,&amp;#39;dhaka&amp;#39;,.24)) %&amp;gt;% rownames_to_column(&amp;quot;words&amp;quot;)
df3=as.data.frame(findAssocs(dtm,&amp;#39;dance&amp;#39;,.30)) %&amp;gt;% rownames_to_column(&amp;quot;words&amp;quot;)
df4=as.data.frame(findAssocs(dtm,&amp;#39;india&amp;#39;,.28)) %&amp;gt;% rownames_to_column(&amp;quot;words&amp;quot;)
df5=as.data.frame(findAssocs(dtm,&amp;#39;myanmar&amp;#39;,.24)) %&amp;gt;% rownames_to_column(&amp;quot;words&amp;quot;)
df6=as.data.frame(findAssocs(dtm,&amp;#39;match&amp;#39;,.40)) %&amp;gt;% rownames_to_column(&amp;quot;words&amp;quot;)

#correlation values have been varied intentionally to restrict the number of outputs

df = df1 %&amp;gt;% full_join(df2, by = &amp;#39;words&amp;#39;) %&amp;gt;% full_join(df3, by = &amp;#39;words&amp;#39;) %&amp;gt;% full_join(df4, by = &amp;#39;words&amp;#39;) %&amp;gt;% full_join(df5, by = &amp;#39;words&amp;#39;)  %&amp;gt;% full_join(df6, by = &amp;#39;words&amp;#39;)
df = gather(df, &amp;quot;key&amp;quot;,&amp;#39;n&amp;#39;,2:7)
df %&amp;gt;% ggplot(aes(words, n, fill = factor(key))) + geom_col() + coord_flip() + 
  labs(x = &amp;quot;Counts&amp;quot;, y = &amp;quot;Words&amp;quot;, fill = &amp;quot;Topic&amp;quot;, title = &amp;quot;Topic wise most frequent words&amp;quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/index_files/figure-html/unnamed-chunk-11-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;We have used different levels of correlations randing from 0.24 to 0.40 to restrict our correlated words less than 10 for each key word. Now we have a clearer picture of how our most frequent words relate with other words. Myanmar has come into the scenario mostly because of the issue of &lt;a href=&#34;https://www.cnn.com/specials/asia/rohingya&#34;&gt;Rohingya crisis&lt;/a&gt; and discussions related to India were related to border issues and cricket. Dhaka’s, the capital of Bangladesh, correlation with words relatd to area and parks may mean that the videos are mostly about the rcreational areas around Dhaka.&lt;/p&gt;
&lt;p&gt;We can also see that these words: &lt;em&gt;skydance&lt;/em&gt;, &lt;em&gt;company&lt;/em&gt;, &lt;em&gt;wedding&lt;/em&gt;, &lt;em&gt;performance&lt;/em&gt; very highly correlate (above 0.90) with &lt;em&gt;dance&lt;/em&gt;. Which reveals that the videos are most likely about wedding dance from some group called Skydance. Let’s look at the names of the channels that have posted most numbers of videos which may give us some new insight.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;videos_year %&amp;gt;% count(channelTitle) %&amp;gt;% arrange(desc(n)) %&amp;gt;%
  mutate(channelTitle = reorder(channelTitle, n)) %&amp;gt;% head(10) %&amp;gt;%
  ggplot(aes(channelTitle, n)) + 
  geom_col()  + 
  scale_x_discrete() +
  coord_flip() +
  ggtitle(label = &amp;#39;Top 10 chennels with most video uploads&amp;#39;) + 
  xlab(label = &amp;#39;Channel name&amp;#39;) + 
  ylab(label = &amp;#39;Number of videos&amp;#39;) +
  labs(fill = &amp;#39;Ratio to the total video posted&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/index_files/figure-html/unnamed-chunk-12-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;As we have assumed before, we can see that the channel named ‘Skydance company’ posted the highest number of videos (more than 30) and their high number of videos on wedding program has pushed the the words ‘dancing’, ‘wedding’, ‘performance’ to the list of most frequent words.&lt;/p&gt;
&lt;p&gt;Among the other top video posters, presence of two news channels (Al Jazeera and Daily Star, a local one) shows that Bangladesh has got quite a good coverage from the news agencies. It would have been nice to see how Bangladesh is represented in these news videos but in this analysis we won’t focus on news. Maybe this can be a future project to work on!
But before moving further into the text mining area we will take a look into the numbers of likes, dislikes and comments to find answers to some of the questions that we asked at the beginning of our analysis:
- What are the most liked videos?
- What are the most disliked videos?
- And which videos got most traction with the viewers through comments?&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;library(grid)
library(gridExtra)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## Warning: package &amp;#39;gridExtra&amp;#39; was built under R version 4.0.3&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;p1=videos_year %&amp;gt;% arrange(desc(likeCount)) %&amp;gt;% head(10) %&amp;gt;%
    mutate(title = strtrim(title, 25)) %&amp;gt;%
  mutate(title = reorder(title,likeCount)) %&amp;gt;%
  ggplot(aes(title, likeCount)) + geom_col()+ xlab(label=&amp;quot;&amp;quot;)+ ggtitle(label = &amp;#39;Top 10 most liked videos&amp;#39;) +  theme(axis.text.x=element_text(angle=45,hjust=1))

p2=videos_year %&amp;gt;% arrange(desc(dislikeCount)) %&amp;gt;% head(10) %&amp;gt;% 
    mutate(title = strtrim(title, 25)) %&amp;gt;%
  mutate(title = reorder(title,dislikeCount)) %&amp;gt;%
  ggplot(aes(title, dislikeCount)) + geom_col()  +  xlab(label = &amp;quot;&amp;quot;)+ ggtitle(label = &amp;#39;Top 10 most disliked videos&amp;#39;) + theme(axis.text.x=element_text(angle=45,hjust=1)) + 
  labs(caption = &amp;#39;* Video titles have been truncated&amp;#39;)
  
grid.arrange(p1,p2, ncol = 2)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/index_files/figure-html/unnamed-chunk-13-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Interrestingly enough, looking at the lists of 10 most liked and disliked videos we can see some common names! Four out of the ten videos are in the both list of highest liked and disliked videos. Another interesting finding is that the videos with most likes and disliked in the list are made in language other than &lt;em&gt;Bangla&lt;/em&gt;, national language of Bangladesh. From that it can be safely assumed that the videos were created by non-Bangladeshi people.&lt;/p&gt;
&lt;p&gt;Let’s dig deeper into the relationship between likes and dislikes. We can look at the correlationship between likes and dislikes from a scatter plot.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;p1=videos_year %&amp;gt;%
  ggplot(aes(likeCount,dislikeCount)) +
  geom_jitter(alpha = 0.4, shape = 1) + 
  labs(subtitle = &amp;#39;All records&amp;#39;) +  
  xlab(label = &amp;#39;Count of likes&amp;#39;) + ylab(label = &amp;#39;Count of dislikes&amp;#39;)

quantile(videos_year$likeCount, na.rm = TRUE)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##      0%     25%     50%     75%    100% 
##     0.0    43.5   268.0  1241.0 78914.0&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;quantile(videos_year$dislikeCount, na.rm = TRUE)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##      0%     25%     50%     75%    100% 
##     0.0     4.0    32.0   136.5 11703.0&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;p2=videos_year %&amp;gt;% filter(likeCount &amp;lt;= 1241 &amp;amp; likeCount &amp;gt;= 44 &amp;amp; dislikeCount &amp;lt;= 137  &amp;amp; dislikeCount &amp;gt;= 4) %&amp;gt;%
  ggplot(aes(likeCount,dislikeCount)) +
  geom_jitter(alpha = 0.4, shape = 1) + 
  labs(subtitle = &amp;#39;Both lowest and highest quantile values removed&amp;#39;) +  
  xlab(label = &amp;#39;Count of likes&amp;#39;) + ylab(label = &amp;#39;Count of dislikes&amp;#39;)

grid.arrange(p1,p2, ncol = 2, top = &amp;#39;Likes vs Dislikes&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/index_files/figure-html/unnamed-chunk-14-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;The left chart above represents all the videos. From the high density in the bottom left corner, we can clearly see the high degree of skewness in the data. Which means that there is high level of disparity among the videos in terms of the number of likes and dislikes. Which is similar to what we have observed in case of number of views.&lt;/p&gt;
&lt;p&gt;So to overcome this clutter and derive more meaningful insight extreme values from both the lowest and highest extremes (lowest and highest quantile values) were considered only. Looking at the scatter plot in right now we can observe a somewhat linearity can assumed between number of likes and dislikes.Statistically which can be seen from their correlation of 0.64. Which means in 64% of the cases high number of likes co-occur with the high number of dislikes and vice versa.&lt;/p&gt;
&lt;p&gt;Now let’s look at the number of comments.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;videos_year %&amp;gt;% arrange(desc(commentCount)) %&amp;gt;% head(10) %&amp;gt;%
    mutate(title = strtrim(title, 25)) %&amp;gt;%
  mutate(title = reorder(title, commentCount)) %&amp;gt;%
  ggplot(aes(title, commentCount)) + geom_col()+ ggtitle(label = &amp;#39;Top 10 most commented videos&amp;#39;) +xlab(label=&amp;quot;&amp;quot;)+ coord_flip() + 
   theme(plot.title = element_text(hjust = -0.45, vjust=2.12)) +
  labs(caption = &amp;#39;* Video titles have been truncated&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/index_files/figure-html/unnamed-chunk-15-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Looking at the most commented videos, as expected we can see some common names from the previous charts on most viewed, liked and disliked videos. But how does the relationship between comments and like or dislike look like? Do people comment more when they like the video or it’s opposite? To get an idea we will create consider ratio of like versus dislike and plot it on top of comment chart.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;videos_year = videos_year %&amp;gt;% mutate(like_dislike = round(likeCount/dislikeCount),2) 
videos_year %&amp;gt;% arrange(desc(commentCount)) %&amp;gt;% head(10) %&amp;gt;%
    mutate(title = strtrim(title, 25)) %&amp;gt;%
  mutate(title = reorder(title, commentCount)) %&amp;gt;%
  ggplot(aes(title, commentCount, fill = like_dislike)) + geom_col()+ xlab(label=&amp;quot;&amp;quot;)+ coord_flip() + ggtitle(label = &amp;#39;Top 10 most commented videos with likes/dislike ratio&amp;#39;) + 
  scale_fill_continuous(&amp;quot;Likes to Dislikes&amp;quot;) + 
  labs(caption = &amp;#39;* Video titles have been truncated&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/index_files/figure-html/unnamed-chunk-16-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;We can now immediately see the prevalence of extreme colors from both end (dark or very light blue). Which means that majority of the top most commented videos are either highly liked or extremely disliked (extremely dark or extremely light blue color).&lt;/p&gt;
&lt;p&gt;Let’s now check both likes and dislikes and their relationship with the number of comments. To do that we will plot like and dislikes on a scatter plot and color code count of comments categorized.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;videos_year %&amp;gt;% filter(dislikeCount &amp;lt;3000 &amp;amp; likeCount &amp;lt;20000) %&amp;gt;%
  mutate(comment_cat = ifelse(commentCount &amp;lt;= 1000, &amp;#39;&amp;lt; or = 1000&amp;#39;, 
                              ifelse(commentCount &amp;lt;= 2000, &amp;#39;1000 to 2000&amp;#39;,
                                     ifelse(commentCount &amp;lt;= 3000, &amp;#39;2000 to 3000&amp;#39;, &amp;#39;above 3000&amp;#39;)))) %&amp;gt;% drop_na() %&amp;gt;%
  ggplot(aes(likeCount, dislikeCount, color = comment_cat)) + 
  geom_point(size = 3,alpha = 0.4)  + 
  ggtitle(label = &amp;#39;Likes vs Dislikes&amp;#39;, subtitle = &amp;#39;Videos with upper extreme values in likes and dislikes not considered&amp;#39;) + 
  scale_fill_discrete(name = &amp;#39;Comment count category&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/index_files/figure-html/unnamed-chunk-17-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;From the abundance of light red color on the above plot, we can immediately see that there are not a lot of videos that could generate more than 1000 comments. Anone take away from the plot is that videos with higher likes compared to dislikes generates most number of comments, above 3,000 (violet clor), while the videos with higher dislikes compared to likes have total comments of no more than 1000. Moreover, videos with both higher likes and dislikes generate moderately high number of comments, 1,000 to 2,000 (light green). Higher correlation between likes count and comment count (0.73) versus the lower correlation between dislike count and comment count (0.58) also reflects the possibility that video with higher likes tend to have higher number of comments too.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;cor(videos_year$likeCount, videos_year$commentCount, use = &amp;#39;complete&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## [1] 0.7320702&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;cor(videos_year$dislikeCount, videos_year$commentCount, use = &amp;#39;complete&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## [1] 0.5827611&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this stage of our analysis we can move onto analyzing the comments a bit further. But due to restriction of the Youtube API on number of records that can be collected, the comments will be collected for only the selective videos. From our initial study on the video titles we have already seen some common areas topics or areas were frequntly presented such as &lt;em&gt;dhaka&lt;/em&gt;, &lt;em&gt;india&lt;/em&gt;, &lt;em&gt;rohingya&lt;/em&gt;, &lt;em&gt;cricket&lt;/em&gt; and &lt;em&gt;dance&lt;/em&gt;. In the next phase of our analysis we’ll look into these areas except the videos related to &lt;em&gt;dance&lt;/em&gt;, since we have already seen that these videos were mostly posted by one channel with insignificant and also didn’t gather much view.&lt;/p&gt;
&lt;p&gt;To fetch comments of these selected topics, first of all all the videos in our list have been classified under these four cateogories: cricket, india, regugee, dhaka and dance. To do that total dataset has been subseted using words those have high correlation with the ‘key words’ which are rohingya, india, dhaka, cricket and dance in this case. In the next phase comments will be collected for the videos under these categoris and sentiment analysis will be conducted to draw insight about general sentiments expressed by the audiences around those topics.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;videos_year=videos_year %&amp;gt;% 
  mutate(labels = ifelse(grepl(paste(c(&amp;quot;rohingya&amp;quot;,&amp;#39;refugee&amp;#39;,&amp;#39;flee&amp;#39;,&amp;#39;myanmar&amp;#39;), collapse = &amp;#39;|&amp;#39;),title), &amp;#39;rohingya&amp;#39;,
                         (ifelse(grepl(&amp;quot;dhaka&amp;quot;,title), &amp;#39;dhaka&amp;#39;,
                                 (ifelse(grepl(&amp;#39;skydance&amp;#39;,title), &amp;#39;dance&amp;#39;,
                                      (ifelse(grepl(paste(c(&amp;quot;india&amp;quot;,&amp;#39;border&amp;#39;,&amp;#39;kolkata&amp;#39;),collapse = &amp;#39;|&amp;#39;),title), &amp;#39;india&amp;#39;,
                                              ifelse(grepl(paste(c(&amp;#39;cricket&amp;#39;,&amp;#39;press&amp;#39;,&amp;#39;post&amp;#39;,&amp;#39;conference&amp;#39;), collapse = &amp;quot;|&amp;quot;), title),&amp;#39;cricket&amp;#39;,NA )))))))))

videos_year=videos_year %&amp;gt;% 
  mutate(labels = ifelse(grepl(paste(df1$words, collapse = &amp;#39;|&amp;#39;),title), &amp;#39;rohingya&amp;#39;,
                         (ifelse(grepl(paste(df2$words, collapse = &amp;#39;|&amp;#39;),title), &amp;#39;dhaka&amp;#39;,
                                 (ifelse(grepl(&amp;#39;skydance&amp;#39;,title), &amp;#39;dance&amp;#39;,
                                      (ifelse(grepl(paste(df4$words,collapse = &amp;#39;|&amp;#39;),title), &amp;#39;india&amp;#39;,
                                              ifelse(grepl(paste(df6$words, collapse = &amp;quot;|&amp;quot;), title),&amp;#39;cricket&amp;#39;,NA )))))))))

summary(factor(videos_year$labels))&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##  cricket    dance    dhaka    india rohingya     NA&amp;#39;s 
##       23       38       15       22       36      455&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Among our total 589 videos from our initial videos, we could make a rough classification of 56 videos. We will further restrict the number of videos to be considered for analysis by taking only the top 10 commented videos from each topic. So that we can still be within the quota of the Youtube API.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# function to fetch comments of specific cateogry of video
fetchComments = function(dataset, keyword){
  df = dataset %&amp;gt;% filter(labels == keyword) %&amp;gt;% 
    arrange(desc(commentCount)) %&amp;gt;% head(10)
  comments = lapply(as.character(df$video_id), function(x){
    get_comment_threads(c(video_id = x), text_format = &amp;#39;plainText&amp;#39;)
  })
  comments = ldply(comments, data.frame) %&amp;gt;% select(videoId, textDisplay, likeCount, publishedAt)
  comments$textDisplay = as.character(comments$textDisplay)
  comments$label = keyword

  return(comments)
  
}


comment_rohingya = fetchComments(videos_year, &amp;#39;rohingya&amp;#39;)
comment_cricket = fetchComments(videos_year, &amp;#39;cricket&amp;#39;)
comment_dhaka = fetchComments(videos_year, &amp;#39;dhaka&amp;#39;)
comment_india = fetchComments(videos_year, &amp;#39;india&amp;#39;)

video_comments = rbind(comment_rohingya,comment_india,comment_dhaka,comment_cricket)
# write.csv(video_comments,&amp;#39;video_comments_top10videos_four_categories.csv&amp;#39;, row.names = FALSE)&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;video_comments=read.csv(&amp;#39;../../../source_files/video_comments_top10videos_four_categories.csv&amp;#39;)
summary(video_comments$label)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##    Length     Class      Mode 
##      1990 character character&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can see that there are total 1,990 comments collected where most comment generating video topics are rohingya, dhaka, cricket and india in descending order. As we did with our previous dataset of &lt;strong&gt;videos_year&lt;/strong&gt;, we will follow similar steps to clean the date and text variables.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;video_comments$publishedAt = as.Date(video_comments$publishedAt) 
video_comments= video_comments %&amp;gt;% mutate(tidy_date = floor_date(publishedAt, unit = &amp;quot;month&amp;quot;))
summary(video_comments$tidy_date)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##         Min.      1st Qu.       Median         Mean      3rd Qu.         Max. 
## &amp;quot;2017-02-01&amp;quot; &amp;quot;2017-09-01&amp;quot; &amp;quot;2017-11-01&amp;quot; &amp;quot;2017-11-25&amp;quot; &amp;quot;2018-03-01&amp;quot; &amp;quot;2018-07-01&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case in addition to converting the date column, &lt;em&gt;publishedAt&lt;/em&gt;, into proper date category, a new column of date has also been creted by converting the date values in &lt;em&gt;publisheAt&lt;/em&gt;. The new column &lt;strong&gt;tidy_date&lt;/strong&gt; contains date values grouped into 12 groups containing all dates clubbed under their respective month. For example, videos posted on Feb-01, Feb-19 have been clubbed under Feb-01 and so on. From the summary of this new variable above, we can see that we have records from as early as February 2017 and as late as July 2018.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# cleaning comments
head(video_comments$textDisplay,5)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## [1] &amp;quot;Thank god for Aung San Suu Kyi for doing this.  I live in Yangon and I am so fed up with muslims acting like they own the world.  They are cowards who need to stop their terrorist attacks, or else more of this will happen.&amp;quot;
## [2] &amp;quot;You know west is weak, when even the budhists show more balls dealing with islam.&amp;quot;                                                                                                                                             
## [3] &amp;quot;Look out people. Evil George soros is using canadian government bob ray to make sure the slaughter continues&amp;quot;                                                                                                                  
## [4] &amp;quot;Humanity has no religion! Bhutanese cruel king n Indian Govt. sent more then 6 hundred thousand refugees to nepal in during 90s they r still in nepal . \nWelcome to nepal rohingya brothers n sister!!&amp;quot;                       
## [5] &amp;quot;George Soros is involved somewhere,i can smell his MO.  If you want real news go to UK Column news.(yt)&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;video_comments$textDisplay &amp;lt;- iconv(video_comments$textDisplay, to = &amp;quot;ASCII&amp;quot;, sub = &amp;quot; &amp;quot;) # convert to ASCII characters to remove any text written using anything other than plain english letter e.g. bengali words
video_comments$textDisplay= gsub(&amp;quot;&amp;lt;.*?&amp;gt;&amp;quot;,&amp;quot;&amp;quot;, video_comments$textDisplay) #removing html tags
video_comments$textDisplay= gsub(&amp;quot;[[:punct:]]&amp;quot;, &amp;quot; &amp;quot;, video_comments$textDisplay) #removing html tags
video_comments$textDisplay = gsub(&amp;quot;[ |\t]{2,}&amp;quot;, &amp;quot; &amp;quot;, video_comments$textDisplay)  # Remove tabs
video_comments$textDisplay = gsub(&amp;quot;^ &amp;quot;, &amp;quot;&amp;quot;, video_comments$textDisplay)  # Leading blanks
video_comments$textDisplay = gsub(&amp;quot; $&amp;quot;, &amp;quot;&amp;quot;, video_comments$textDisplay)  # Lagging blanks
video_comments$textDisplay = gsub(&amp;quot; +&amp;quot;, &amp;quot; &amp;quot;, video_comments$textDisplay) # General spaces 
video_comments$textDisplay = tolower(video_comments$textDisplay) # lowering all letters
head(video_comments$textDisplay,5)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## [1] &amp;quot;thank god for aung san suu kyi for doing this i live in yangon and i am so fed up with muslims acting like they own the world they are cowards who need to stop their terrorist attacks or else more of this will happen&amp;quot;
## [2] &amp;quot;you know west is weak when even the budhists show more balls dealing with islam&amp;quot;                                                                                                                                         
## [3] &amp;quot;look out people evil george soros is using canadian government bob ray to make sure the slaughter continues&amp;quot;                                                                                                             
## [4] &amp;quot;humanity has no religion bhutanese cruel king n indian govt sent more then 6 hundred thousand refugees to nepal in during 90s they r still in nepal \nwelcome to nepal rohingya brothers n sister&amp;quot;                       
## [5] &amp;quot;george soros is involved somewhere i can smell his mo if you want real news go to uk column news yt&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# write.csv(video_comments,&amp;#39;cleaned_video_comments_top10videos_four_categories.csv&amp;#39;, row.names = FALSE)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now moving onto the text cleaning step for the &lt;em&gt;textDisplay&lt;/em&gt; column we have cleaned the html tags, lowered all letters, removed punctuation marks. Above we can see sample of texts before the transformation and after the transformation. The first five sentences in the above list shows the text before cleaning steps applied and last five shows the transforemd text after cleaning. Now we’ll calculate sentiment score for each of the sentences using different lexicon libraries. For the purpose, &lt;em&gt;tidytext&lt;/em&gt; package will be used which offers the commonly used lexicon libraries (bing, afinn, nrc).&lt;/p&gt;
&lt;p&gt;Before moving into the analysis of sentiment scores we’ll take a look at the trend of video posting. Naturally we expect to see videos in different topics being posted at different rate over the period of months.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# calculating labelwise trend of video posting
video_comments %&amp;gt;%
  group_by(tidy_date) %&amp;gt;%
  mutate(total_videos_month = n()) %&amp;gt;%
  ungroup() %&amp;gt;%
  count(tidy_date, label, total_videos_month) %&amp;gt;% 
  mutate(percent_video_label = n/total_videos_month) %&amp;gt;%
  ggplot(aes(tidy_date, percent_video_label, color = label, group = 1)) +         facet_wrap(~label)+ geom_line(size = 1) +
  scale_x_date(date_labels=&amp;quot;%b %y&amp;quot;,date_breaks  =&amp;quot;2 month&amp;quot;) +    
  theme(axis.text.x=element_text(angle=45,hjust=1))+
  ggtitle(label = &amp;#39;Month wise frequency of comments&amp;#39;) + 
  xlab(label = &amp;#39;Month&amp;#39;) + 
  ylab(label = &amp;#39;Percentage&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/index_files/figure-html/unnamed-chunk-24-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;video_comments %&amp;gt;%
  group_by(tidy_date) %&amp;gt;%
  mutate(total_videos_month = n()) %&amp;gt;% # each row of video represent a single comment
  ungroup() %&amp;gt;%
  count(tidy_date, label, total_videos_month) %&amp;gt;% 
  mutate(percent_video_label = n/total_videos_month) %&amp;gt;%
  ggplot(aes(tidy_date, percent_video_label, color = label)) +         facet_wrap(~label)+ 
  geom_point(shape = 21, fill = &amp;quot;white&amp;quot;, color = &amp;quot;#27408b&amp;quot;, size = 2, stroke = 1.1)+
  geom_line(color=&amp;quot;#27408b&amp;quot;) +
  scale_x_date(date_labels=&amp;quot;%b %y&amp;quot;,date_breaks  =&amp;quot;2 month&amp;quot;) +    
  theme(axis.text.x=element_text(angle=45,hjust=1))+
  ggtitle(label = &amp;#39;Month wise frequency of comments&amp;#39;) + 
  xlab(label = &amp;#39;Month&amp;#39;) + 
  ylab(label = &amp;#39;Percentage&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/index_files/figure-html/unnamed-chunk-24-2.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# video_comments %&amp;gt;% filter(tidy_date == &amp;#39;2017-06-01&amp;#39; &amp;amp; label == &amp;#39;india&amp;#39;) %&amp;gt;% select(videoId) %&amp;gt;% unique()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;One nice thing about the plot above is that, it captures the trend how social media activities spikes and then flattens with the time. For example, the videos posted about &lt;em&gt;rohingya&lt;/em&gt; topic had the highest traction on September 2017 around the time when the crisis started. But gradually comments have slowed down since November 2017. On the other hand comments on videos about &lt;em&gt;cricket&lt;/em&gt; and &lt;em&gt;india&lt;/em&gt; show somewhat resemblance. Till September 2017 both the topics experienced spikes or in other words higher number of comments posted. Later on, the trend has slowed down. We may now look at the trend from the perspective of age of the videos. How did the sentiment of audiences of these videos changed over the life time of the videos? Or does sentiment change as the videos grow old?&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# fetching video poblishing date from the old dataset
video_comments = video_comments %&amp;gt;% left_join(videos_year[,c(&amp;#39;video_id&amp;#39;,&amp;#39;publishedAt&amp;#39;)], by = c(&amp;#39;videoId&amp;#39; = &amp;#39;video_id&amp;#39;), suffix = c(&amp;#39;_comment&amp;#39;,&amp;#39;_video&amp;#39;)) 
# creating new variable with the difference between video posting date and comment posting date
video_comments = video_comments %&amp;gt;% 
  mutate(post_comm_gap = publishedAt_comment - publishedAt_video)

p1=video_comments %&amp;gt;%
  group_by(post_comm_gap) %&amp;gt;%
  mutate(total_videos = n()) %&amp;gt;%
  ungroup() %&amp;gt;% 
  ggplot(aes(post_comm_gap, total_videos)) +         
  facet_wrap(~label)+ geom_jitter() +
  theme(axis.text.x=element_text(angle=45,hjust=1))+
  labs(subtitle = &amp;#39;All comments&amp;#39;) + 
  xlab(label = &amp;#39;Age of comment&amp;#39;) + 
  ylab(label = &amp;#39;Count&amp;#39;)

p2=video_comments %&amp;gt;%
  group_by(post_comm_gap) %&amp;gt;%
  mutate(total_videos = n()) %&amp;gt;%
  ungroup() %&amp;gt;% 
  filter(total_videos &amp;lt; 20) %&amp;gt;%
  ggplot(aes(post_comm_gap, total_videos)) +         
  facet_wrap(~label)+ geom_jitter() +
  theme(axis.text.x=element_text(angle=45,hjust=1))+
  labs(subtitle = &amp;#39;Less than 20 total comments&amp;#39;) + 
  xlab(label = &amp;#39;Age of comment&amp;#39;) + 
  ylab(label = &amp;#39;Count&amp;#39;)

library(gridExtra)
grid.arrange(p1,p2, ncol = 2, top = &amp;#39;Count of comments vs when they are posted&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/index_files/figure-html/unnamed-chunk-25-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;From left plot above, we can see that the highest number of comments are posted right after videos are posted (where age of video is ‘zero’ meaning video posted and comment posted dates are same). But since we can’t really make much sense out of the graphs because of the extremely skewed data on y axis, we can consider only the lower values to check if there is any specific trend. Doing that we ended up with the plot on right. Where y axis with less than 20 values were considered.&lt;/p&gt;
&lt;p&gt;From the right plot above, we can see that on an average number of comments tend to slow down after 350 days from the date video posted but comments on videos about &lt;em&gt;India&lt;/em&gt; seemingly can keep this traction going on further. While the videos about &lt;em&gt;Rohingya&lt;/em&gt; issue doesn’t have any comments after 300th days. Which largely because that the oldest video considered here about &lt;em&gt;Rohingya&lt;/em&gt; was posted on August 2017. Which barely gives a life span of slightly more than 300 days While in other topics there are videos from the very first month of 2007. But from the trend of comments in other topics we can assume that the comments under the existing videos about rohingya crisis may also take a gradual down turn soon!&lt;/p&gt;
&lt;p&gt;Now moving on to the sentiment analysis, we’ll use lexicon based approach. To do that we will look at the comments that viweres left below these videos. We will calculate sentiment score using lexicon library &lt;a href=&#34;http://saifmohammad.com/WebPages/NRC-Emotion-Lexicon.htm&#34;&gt;&lt;em&gt;NRC&lt;/em&gt;&lt;/a&gt;. To explain briefly what a lexicon is, lexicon libraries are stock of words that are prelabeled with the sentiment that they carry. For example: &lt;em&gt;happy&lt;/em&gt; would be labeled as positive sentiment while &lt;em&gt;cry&lt;/em&gt; as negative sentiment. In The bing lexicon categorizes words in a binary fashion into positive and negative categories.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# creating a new column with the words
video_comments$textDisplay = as.character(video_comments$textDisplay)
token = video_comments %&amp;gt;% 
  unnest_tokens(word, textDisplay, token = &amp;#39;words&amp;#39;, drop = FALSE) 

token %&amp;gt;% select(label, tidy_date, word) %&amp;gt;%
  inner_join(get_sentiments(&amp;#39;nrc&amp;#39;), by = &amp;#39;word&amp;#39;) %&amp;gt;% 
  group_by(label,tidy_date) %&amp;gt;% 
  mutate(label_month_total = n()) %&amp;gt;%
  ungroup() %&amp;gt;%
  group_by(label,sentiment,tidy_date) %&amp;gt;%
  mutate(label_month_senti_total = n()) %&amp;gt;%
  ungroup() %&amp;gt;%
  mutate(percent_sentiment = label_month_senti_total/label_month_total) %&amp;gt;% select(label, tidy_date, sentiment, percent_sentiment) %&amp;gt;% unique() %&amp;gt;% 
  ggplot(aes(tidy_date, percent_sentiment, color = factor(sentiment))) + geom_line(size = 1) + facet_wrap(~label) + theme(axis.text.x=element_text(angle=45,hjust=1)) + 
  labs(title = &amp;#39;Different sentiment trending over the time&amp;#39;, x = &amp;#39;Date&amp;#39;, y = &amp;#39;Percentage&amp;#39;, colour = &amp;quot;Sentiments&amp;quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/index_files/figure-html/unnamed-chunk-26-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# nrc = get_sentiments(&amp;#39;nrc&amp;#39;)
# summary(factor(nrc$sentiment))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The plots above shows all the sentiments available in the &lt;em&gt;NRC lexicon&lt;/em&gt;, which presents an immediate challenge: too cluttered lines to interprete. To make it legible we can club the negative and positive sentiments and plot separtely. But before we do that, if we look back to the plot and try to interprete the lines, we immediately see that there is a prevalence of positive sentiment. Which is because of the nature of the lexicon library. Majority of the words are classified or labeled as positive words which is reflected in the above plot too.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;p1 = token %&amp;gt;% select(label, tidy_date, word) %&amp;gt;%
  inner_join(get_sentiments(&amp;#39;nrc&amp;#39;), by = &amp;#39;word&amp;#39;) %&amp;gt;% 
  filter(sentiment %in% c(&amp;#39;anger&amp;#39;,&amp;#39;disgust&amp;#39;,&amp;#39;fear&amp;#39;,&amp;#39;sadness&amp;#39;,&amp;#39;negative&amp;#39;)) %&amp;gt;%
  group_by(label,tidy_date) %&amp;gt;% 
  mutate(label_month_total = n()) %&amp;gt;%
  ungroup() %&amp;gt;%
  group_by(label,sentiment,tidy_date) %&amp;gt;%
  mutate(label_month_senti_total = n()) %&amp;gt;%
  ungroup() %&amp;gt;%
  mutate(percent_sentiment = label_month_senti_total/label_month_total) %&amp;gt;% select(label, tidy_date, sentiment, percent_sentiment) %&amp;gt;% unique() %&amp;gt;% 
  ggplot(aes(tidy_date, percent_sentiment, color = factor(sentiment))) + geom_line(size = 1) + facet_wrap(~label) + theme(axis.text.x=element_text(angle=45,hjust=1)) + 
  labs(title = &amp;#39;Negative sentiments trending over the time&amp;#39;, x = &amp;#39;Date&amp;#39;, y = &amp;#39;Percentage&amp;#39;, colour = &amp;quot;Sentiments&amp;quot;) +
  scale_x_date(date_labels=&amp;quot;%b %y&amp;quot;,date_breaks  =&amp;quot;2 month&amp;quot;) 

p2 = token %&amp;gt;% select(label, tidy_date, word) %&amp;gt;%
  inner_join(get_sentiments(&amp;#39;nrc&amp;#39;), by = &amp;#39;word&amp;#39;) %&amp;gt;% 
  filter(!sentiment %in% c(&amp;#39;anger&amp;#39;,&amp;#39;disgust&amp;#39;,&amp;#39;fear&amp;#39;,&amp;#39;sadness&amp;#39;,&amp;#39;negative&amp;#39;)) %&amp;gt;%
  group_by(label,tidy_date) %&amp;gt;% 
  mutate(label_month_total = n()) %&amp;gt;%
  ungroup() %&amp;gt;%
  group_by(label,sentiment,tidy_date) %&amp;gt;%
  mutate(label_month_senti_total = n()) %&amp;gt;%
  ungroup() %&amp;gt;%
  mutate(percent_sentiment = label_month_senti_total/label_month_total) %&amp;gt;% select(label, tidy_date, sentiment, percent_sentiment) %&amp;gt;% unique() %&amp;gt;% 
  ggplot(aes(tidy_date, percent_sentiment, color = factor(sentiment))) + geom_line(size = 1) + facet_wrap(~label) + theme(axis.text.x=element_text(angle=45,hjust=1)) + 
  labs(title = &amp;#39;Positive sentiments trending over the time&amp;#39;, x = &amp;#39;Date&amp;#39;, y = &amp;#39;Percentage&amp;#39;, colour = &amp;quot;Sentiments&amp;quot;)+
  scale_x_date(date_labels=&amp;quot;%b %y&amp;quot;,date_breaks  =&amp;quot;2 month&amp;quot;) 

grid.arrange(p1,p2, ncol = 2)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/index_files/figure-html/unnamed-chunk-27-1.png&#34; width=&#34;960&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Looking at the left plot two interesting trends can be spotted:
* About India there has been a sudden growth of &lt;em&gt;anger&lt;/em&gt; during the months of June and July 2018.
* On the other hand surprisingly negative sentiment about the Rohingya issue is growing on the months of June and July 2018.&lt;/p&gt;
&lt;p&gt;Plot on the right kind of reflects the sentiments expressed on the left plot. Where we see a hightened positivity about Dhaka and Rohingya on April 2018.&lt;/p&gt;
&lt;p&gt;We are at the very end of our analysis. We will wrap it up with network charts, created with the most frequent words (noun and adjectives), on the comments about India and Rohingya in recent times (after June 2018). From these plots we will try to make a sense about the areas where the unusual spike of negative sentiments were expressed.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;#key words extraction from the advising notes
ud_model = udpipe_download_model(language = &amp;#39;english&amp;#39;)
ud_model = udpipe_load_model(ud_model$file_model)

net_plot = function(dataset,label_name,sg) {
  text = dataset %&amp;gt;% filter(label == label_name)
  text = text %&amp;gt;% filter(publishedAt_comment &amp;gt; &amp;quot;2018-06-01&amp;quot;)
  text = udpipe_annotate(ud_model, x = text$textDisplay)
  text = as.data.frame(text)
  text$lemma = removeWords(text$lemma, stopwords(&amp;#39;english&amp;#39;)) 
  text$lemma = removePunctuation(text$lemma) 
  text = text %&amp;gt;% filter(lemma != &amp;quot;&amp;quot;)
  stat = cooccurrence(x = subset(text, upos %in% c(&amp;#39;NOUN&amp;#39;,&amp;#39;ADJ&amp;#39;)), term = &amp;#39;lemma&amp;#39;,
                      group = c(&amp;quot;doc_id&amp;quot;, &amp;quot;paragraph_id&amp;quot;, &amp;quot;sentence_id&amp;quot;), skipgram = sg)
  wordnetwork &amp;lt;- head(stat,50)
  wordnetwork &amp;lt;- graph_from_data_frame(wordnetwork)
  plot = ggraph(wordnetwork, layout = &amp;quot;fr&amp;quot;) +
    geom_edge_link(aes(width = cooc, edge_alpha = cooc), edge_colour = &amp;#39;red&amp;#39;) +
    geom_node_text(aes(label = name), col = &amp;quot;darkgreen&amp;quot;, size = 4) +
    theme_graph(base_family = &amp;quot;Arial Narrow&amp;quot;) +
    theme(legend.position = &amp;quot;none&amp;quot;) +
    labs(title = &amp;#39;Cooccurrent Nouns and Adjectives&amp;#39;, 
         subtitle = label_name)
  return(plot)
}

# net_plot(video_comments, &amp;#39;dhaka&amp;#39;,2)
# net_plot(video_comments, &amp;#39;cricket&amp;#39;,2)
 
p1=net_plot(video_comments, &amp;#39;rohingya&amp;#39;,2)
p2=net_plot(video_comments, &amp;#39;india&amp;#39;,1)

grid.arrange(p1,p2,ncol = 2, top = &amp;#39;Word networks&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2021-03-30-text-analysis-on-youtube-videos-posted-about-bangladesh/index_files/figure-html/unnamed-chunk-28-1.png&#34; width=&#34;1152&#34; /&gt;&lt;/p&gt;
&lt;p&gt;From the word network on left we observe that some most frequent phrases are related to muslim such as muslim criminal, muslim burmese and so on. From which it can be assumed that the negativity related to rohingya issue is mostly about the plight of them which may have been triggered by their muslim majority. On the other hand, most frequent phrases around the topic of India are bangladesh border, bangladesh people and so on. Where aparently no specific indication is present from which we can make any assumption about the sudden increase of anger.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;part-05-ending&#34; class=&#34;section level1&#34;&gt;
&lt;h1&gt;Part 05: Ending&lt;/h1&gt;
&lt;p&gt;From our overall analysis, we have seen that videos with high number of views tend to be about issues that evoke some sort of controverysy (e.g. prank video and videos about brothel in top 20 videos). Interestingly videos that generates higher number of likes also generates higher shares of dislikes too (correlation of 0.6). And when we consider comments as a matrix of viewer traction, most commented videos tend to be on the extremes of likes or dislikes. But most liked videos tend to have higher number of comments compared to the videos with higher number of dislikes. Further we have observed that the videos posted were mostly about some specific areas. From which we picked four topics to explore further. The number of comments vary following different trends in each of the topic areas. Where we have seen that videos realted to &lt;em&gt;India&lt;/em&gt; had the longest traction or kept generating comments over a longer period of time. But overall videos seem to reach their end of customer traction at around 350 to 400 days from the day when they are first posted. In the end we looked at the sentiment expressed in the comments by the viewers. Overall, we saw uneven distribution of sentiments over the time. But for some reason we have seen a prevalence of &lt;em&gt;anger&lt;/em&gt; about the topic India and &lt;em&gt;negativity&lt;/em&gt; about the topic Rohingya in comments in recent time. And as a possible source of recent increase in negative sentiment aroun rohingya topic we indentified the plight of rohingya muslims.&lt;/p&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Topic Modeling and Sentiment Analysis on Tweets</title>
      <link>https://laminarinsight.com/post/twitter-topic-modeling-sentiment-analysis/</link>
      <pubDate>Thu, 10 May 2018 00:00:00 +0000</pubDate>
      
      <guid>https://laminarinsight.com/post/twitter-topic-modeling-sentiment-analysis/</guid>
      <description>

&lt;div id=&#34;TOC&#34;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#objective&#34;&gt;Objective&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#data-collection&#34;&gt;Data collection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#discussion-of-the-methodology&#34;&gt;Discussion of the methodology&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#data-processing&#34;&gt;Data processing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#topic-modeling-using-lda&#34;&gt;Topic modeling using LDA&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;#additional-analysis-sentiment-analysis-on-rohingya-topic&#34;&gt;Additional analysis: Sentiment analysis on Rohingya topic&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;#overall-finding-and-discussion&#34;&gt;Overall finding and discussion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;Twitter is a popular source for minning social media posts. In this article I harvested tweets that had mention of ‘Bangladesh’, my home country and ran two specific text analysis: topic modeling and sentiment analysis. The overall goal was to understand which topics related to Bangladesh are popular among the Twitter users and derive some understanding about the sentiments that they expressed through their tweets.&lt;/p&gt;
&lt;div id=&#34;objective&#34; class=&#34;section level1&#34;&gt;
&lt;h1&gt;Objective&lt;/h1&gt;
&lt;p&gt;Breaking down the objective for clear analysis gives us three specific goals:&lt;/p&gt;
&lt;ol style=&#34;list-style-type: decimal&#34;&gt;
&lt;li&gt;Around which topics twitter discussions usually circle around,&lt;/li&gt;
&lt;li&gt;What is the overall sentiment about Bangladesh that is conveyed by the tweets,&lt;/li&gt;
&lt;li&gt;As an extension of the previous two steps: A topic wise sentiment analysis to reveal what kind of sentiments(s) carried by the generally discussed topics.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div id=&#34;data-collection&#34; class=&#34;section level1&#34;&gt;
&lt;h1&gt;Data collection&lt;/h1&gt;
&lt;p&gt;For that study I used public API that is provided from Twitter for twitter analysis. I fetched total 20,000 random twitter posts that were in English and had a mention of ‘Bangladesh’. So I used ‘Bangladesh’ as the search term and collected total 20,000 twitters using R through the public API of Twitter.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;discussion-of-the-methodology&#34; class=&#34;section level1&#34;&gt;
&lt;h1&gt;Discussion of the methodology&lt;/h1&gt;
&lt;p&gt;To achieve this objective I applied Latent Dirichlet allocation (LDA) model from topicmodels package in R. LDA model is an unsupervised machine learning algorithm which was first presented as a topic discovery model by David Blei, Andrew Ng, and Michael I. Jordan in 2003.
LDA considers a document as a collection of topics. So each word in the document is considered as part of one or more topics. LDA clusters the words under their respective topics. As a statistical model, LDA provides probability of each word to be belonging to a topic and again a probability of each topic to be belonging to each document.&lt;br /&gt;
To run LDA, we have to pick number of topics. Since, based on this number LDA breaks down a document and words, in this study, I will try two different total numbers of topics. In LDA model, what could be the total number of topics to be looked for is a balance between granularity versus generalization. More number of topics can provide granularity but may become difficult to divide in clearly segregated topics. On the other hand, less number of topics can be overly generalized and may combine different topics into one.
On the later part for sentiment analysis lexicon based sentiment analysis approach was followed. The lexicon used was NRC Emotion Lexicon (EmoLex) which is a crowd-sourced lexicon created by Dr. Saif Mohammad, senior research officer at the National Research Council, Canada. NRC lexicon has a division of words based on 8 prototypical emotions namely: trust, surprise, sadness, joy, fear, disgust, anticipation, and anger and two sentiments: positive and negative. This NRC lexicon was used from the ‘tidytext’ package in R.&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;data-processing&#34; class=&#34;section level1&#34;&gt;
&lt;h1&gt;Data processing&lt;/h1&gt;
&lt;p&gt;I have already harvested the tweets and fetched texts from the tweets into text file: ‘bd_tweets_20k.Rds’. So I will skip the initial part of coding showing fetching tweets. Rather I will start by reading the already saved file and then will show the data cleaning and processing step by step.&lt;/p&gt;
&lt;p&gt;Reading text file of the tweets:&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;tweets = readRDS(&amp;#39;../../source_files/bd_tweets_20k.Rds&amp;#39;)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Before going into the data cleaning step couple of things are to be cleared:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It’s very important to maintain logical order in executing the cleaning commands. Other wise some information can be missed unintentionally. For example, if we convert all the tweets and later on apply ‘gsub’ command to remove retweets with ‘rt’ pattern we may lose part of words that contain ‘rt’. Retweets are marked as RT in the begining but since we converted everything into lower case using ‘tolower’ function, lateron our programs would not be able to detect difference of ‘rt’ for retweet and any other use of ‘rt’ as part of a word. Let’s say there’s a word ‘Part’, after the transormation we’ll only see ‘Pa’ and ‘rt’ part will be replaced by blank.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Throughout the cleaning step it’s a good practice to randomly check the text file to make sure no unexpected transformation takes place. For example, I will view 500th tweet from my file as a benchmark. That tweet I picked arbitrarilly. I will check text of that tweet before starting the data cleaning process and also will view at different points during the cleaning steps.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here’s our sample tweets:&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;writeLines(as.character(tweets[[1500]]))&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## Half a million Rohingya refugee children at risk in overcrowded camps in Bangladesh with cyclone and… https://t.co/jrp3yEvMJN #Bangladesh&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We will revisit our sample tweet at different points during the next data cleaning process.&lt;/p&gt;
&lt;p&gt;In the following section I start data cleaning process by converting the text to ASCII format to get rid of the funny characters usually used in Twitter messages. Here is one thing can be noted that these funny characters may contain significant subtle information about sentiment carried by the messages but since it will extend the area covered by this report, it has been skipped here. But it could definitely be a future research area! Before going any further&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;# Convert to basic ASCII text to avoid silly characters
tweets &amp;lt;- iconv(tweets, to = &amp;quot;ASCII&amp;quot;, sub = &amp;quot; &amp;quot;)  &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the following code section, I will apply bunch of codes to remove special characters, hyperlink, usernames, tabs, punctuations and unnecessary white spaces. Because all these are not don’t have any relation to the topic modeling. I have mentioned specific use of each code along with the codes below.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;tweets &amp;lt;- gsub(&amp;quot;(RT|via)((?:\\b\\W*@\\w+)+)&amp;quot;, &amp;quot;&amp;quot;, tweets)  # Remove the &amp;quot;RT&amp;quot; (retweet) and usernames 
tweets = gsub(&amp;quot;http.+ |http.+$&amp;quot;, &amp;quot; &amp;quot;, tweets)  # Remove html links
tweets = gsub(&amp;quot;http[[:alnum:]]*&amp;quot;, &amp;quot;&amp;quot;, tweets)
tweets = gsub(&amp;quot;[[:punct:]]&amp;quot;, &amp;quot; &amp;quot;, tweets)  # Remove punctuation
tweets = gsub(&amp;quot;[ |\t]{2,}&amp;quot;, &amp;quot; &amp;quot;, tweets)  # Remove tabs
tweets = gsub(&amp;quot;^ &amp;quot;, &amp;quot;&amp;quot;, tweets)  # Leading blanks
tweets = gsub(&amp;quot; $&amp;quot;, &amp;quot;&amp;quot;, tweets)  # Lagging blanks
tweets = gsub(&amp;quot; +&amp;quot;, &amp;quot; &amp;quot;, tweets) # General spaces &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the above bunch of cleaning codes we have removed html, username and so on. We saw our sample tweet had a html link in it. Let’s check if the transoformation worked properly or not:&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;writeLines(as.character(tweets[[1500]]))&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## Half a million Rohingya refugee children at risk in overcrowded camps in Bangladesh with cyclone and&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We see that the punchtuations (.) and website link have been removed from our sample tweet as intended.&lt;/p&gt;
&lt;p&gt;I will convert all the tweets in lower case since in R words are case sensitive. For example: ‘Tweets’ and ‘tweets’ are considered as two different words. Moreover, I will remove the duplecate tweets. Among the tweets downloaded using twitter public API there duplicate tweets also exist. To make sure the tweets that are used here are not duplicated now I will remove the duplicated tweets.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;tweets = tolower(tweets)
tweets = unique(tweets)
writeLines(as.character(tweets[[1500]]))&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## best quality underground metal detector in bangladesh&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To check I have extracted the 1500th tweet. But this time I have got a different tweet. Because after removing duplecate tweets I had left with 5,561 tweets out of 20,000 tweets which I started with. So the serial number of tweets have also changed.&lt;/p&gt;
&lt;p&gt;As the next step of data processing I will convert this tweets file, which is a character vector, into a corpus. In general term, corpus in linguistic means a structured set of texts that can be used for statistical analysis, hypothesis testing, occurance checking and validating linguistic rules. To To achive this goal I will use ‘corpus’ and ‘VectorSource’ commands from ‘tm’ library in R. While ‘VectorSource’ will interpret each element of our character vector file ‘tweets’ as a document and feed that input into ‘corpus’ command. Which eventually will convert that into corpus suitable for statistical analysis.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;library(tm)
corpus &amp;lt;- Corpus(VectorSource(tweets))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I will do some more cleaning on the corpus by removing stop words and numbers because both these have very little value, if there is any, towards our goal of sentiment analylsis and topic modeling. For clarity I will explain a bit more on stop words here before going into coding. Stop words are some extremely common words used in a language which may carry very little value for a particular analysis. In this case I will use the stop words list comes along with ‘tm’ package. To get an idea of the list here are some example of stop words: a, about, above and so on. The exhaustive list can be found in this Github link: &lt;a href=&#34;https://github.com/arc12/Text-Mining-Weak-Signals/wiki/Standard-set-of-english-stopwords&#34; class=&#34;uri&#34;&gt;https://github.com/arc12/Text-Mining-Weak-Signals/wiki/Standard-set-of-english-stopwords&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;corpus &amp;lt;- tm_map(corpus, removeWords, stopwords(&amp;quot;english&amp;quot;))  
corpus &amp;lt;- tm_map(corpus, removeNumbers)
writeLines(as.character(corpus[[1500]]))&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## best quality underground metal detector  bangladesh&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can see from our sample tweet that a bunch of stop words (in) is removed.&lt;/p&gt;
&lt;p&gt;At this step I will convert the words in the corpus into stem words. In general terms, word stemming means the process of reducing a word to its base form which may or may not be the same as the morphological root of the word or may or may not bear meaning by the stem word itself. For example, all these words: ‘fishing’, ‘fisheries’ can be reduced to ‘fish’ by a stemming algorithm. Here ‘fish’ bears a meaning. But on the other hand this bunch of words: ‘argue’, ‘argued’ can be reduced to ‘argu’ in this case the stem doesn’t bear any particular meaning. Stemming a document makes it easier to cluster words and make analysis since. In addition to the stemming I will also delete my search key ‘Bangladesh’ from the tweets. Since I am analyzing tweets containing Bangaldesh and ‘amp’, it’s illogical to keep the term ‘bangladesh’ since that’s the search term and ‘amp’is abbrebiation of ’Accelerated Mobile Page’ which is a part of html link that improved web surfing experience from mobile devices.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;corpus &amp;lt;- tm_map(corpus, stemDocument)
corpus = tm_map(corpus, removeWords, c(&amp;quot;bangladesh&amp;quot;,&amp;quot;amp&amp;quot;, &amp;quot;will&amp;quot;, &amp;#39;get&amp;#39;, &amp;#39;can&amp;#39;))

writeLines(as.character(corpus[[1500]]))&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## best qualiti underground metal detector&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Again a recheck of our sample tweet we can see ‘quality’ has been tranformed into their stem form: ‘qualiti’ and ‘bangladesh’ has been removed.&lt;/p&gt;
&lt;p&gt;I am finally done with our first step of data cleaning and pre-processing. On the next step I will start data processing to create our topic model. But before diving into model creation I decided to crate a word cloud to get a feel about the data.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;library(wordcloud)
set.seed(1234)
palet  = brewer.pal(8, &amp;#39;Dark2&amp;#39;)
wordcloud(corpus, min.freq = 50, scale = c(4, 0.2) , random.order = TRUE, col = palet)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2020-06-23-twitter-sentiment-analysis-on-bangladesh_files/figure-html/unnamed-chunk-10-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;p&gt;From the resulting word cloud we can see that the words are colored differently, which is based on the frequencies of the words appearing in the tweets. Looking at the most largest two fonts (black and green) we can find these words: rohingya, refuge, today, india, cricket, live. To interpret anything from such word cluster subject knowledge comes handy. Sinice I am from Bangladesh, I know that influx of Rohingya refugee from Myanmar is one of the most recent most discussed issue. Intuitively enough, Rohingya, refuge can be classified as related to the Rohingya crisis. On the other hand Cricket is the most popular game in Bangladesh along with other countries from south asian region. Cricket and Live can be thought to be related to Cricket. India and Today don’t have a general strong association with either of the two primary topics that we have sorted out. We will see how it goes in our further analysis in topic modeling.&lt;/p&gt;
&lt;p&gt;As a next processing step now I will convert our corpus in a Document Term Matrix (DTM). DTM creates a matrix that consists all words or terms as an individual column and each document, in our case each tweet, as a row. Numeric value of 1 is assigned to the words that apprear in the document from the corresponding row and value of 0 is assigned to the rest of the words in that row. Thus the resulting DTM file is a sparse which is a large matrix containing a lot of 0.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;dtm = DocumentTermMatrix(corpus)
dtm&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## &amp;lt;&amp;lt;DocumentTermMatrix (documents: 5561, terms: 8561)&amp;gt;&amp;gt;
## Non-/sparse entries: 44969/47562752
## Sparsity           : 100%
## Maximal term length: 30
## Weighting          : term frequency (tf)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From the file summary of ‘dtm’ file we can see that it contains total 5,561 document, which is the total number of tweets that we have, and total 8,565 term, which shows we have total 8,565 unique words in our tweets. From the non/sparse entries ratio and the percentage of Sparsity we can see that the sparsity of the file, which is not exactly 100 but very close to 100, is very very high which is means lot of words appeard only in few tweets. Let’s inspect the ‘dtm’ file to have a feel about the data.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;doc.length = apply(dtm, 1, sum)
dtm = dtm[doc.length &amp;gt; 0,]
dtm&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## &amp;lt;&amp;lt;DocumentTermMatrix (documents: 5552, terms: 8561)&amp;gt;&amp;gt;
## Non-/sparse entries: 44969/47485703
## Sparsity           : 100%
## Maximal term length: 30
## Weighting          : term frequency (tf)&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;inspect(dtm[1:2,10:15])&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## &amp;lt;&amp;lt;DocumentTermMatrix (documents: 2, terms: 6)&amp;gt;&amp;gt;
## Non-/sparse entries: 6/6
## Sparsity           : 50%
## Maximal term length: 6
## Weighting          : term frequency (tf)
## Sample             :
##     Terms
## Docs dinesh india injur jan within year
##    1      0     0     0   0      1    1
##    2      1     1     1   1      0    0&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can see that out of the five terms first four terms were present in doc 2 and rest 2 terms were present in the doc 1. And accordingly the value of 1 and 0 have been distributed in the cells. Now let’s look at some of the most frequent words in our DTM.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;library(dplyr)
freq = colSums(as.matrix(dtm))
length(freq)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## [1] 8561&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;ord = order(freq, decreasing = TRUE)
freq[head(ord, n = 20)]&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## rohingya     news  zimbabw    india   refuge     live  cricket    today 
##      590      509      465      324      308      299      297      296 
##      tri      new     camp     seri pakistan  myanmar    match   nation 
##      266      248      245      239      238      236      221      203 
##   bangla   wicket      odi    peopl 
##      201      187      182      182&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From the list of 20 most frequent words we can see that Rohingya crisis and Cricket related terms are the most frequntly used terms. Which shows resemblance with what we saw in our wordcloud. We can now see how different words are associated. Since we see that Cricket and Rohingy are two frequntly used topics, we can try to see which words associate with these two words. For this we will use ‘findAssocs’ command from ‘tm’ package. To run this command we need to provde the benchmark term and then a minimum value of correlation, which can range from 0 to 1.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;findAssocs(dtm, &amp;quot;cricket&amp;quot;,0.2)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## $cricket
##     cup zimbabw   score    team 
##    0.23    0.22    0.20    0.20&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;findAssocs(dtm, &amp;#39;rohingya&amp;#39;, 0.2)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## $rohingya
##   refuge     camp  myanmar  repatri    crisi     hous children 
##     0.51     0.46     0.41     0.33     0.25     0.25     0.24&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;findAssocs(dtm, &amp;#39;news&amp;#39;, 0.2 )&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## $news
##   today  latest  bangla   updat januari     atn  decemb ekattor  jamuna ekushey 
##    0.77    0.77    0.76    0.68    0.56    0.53    0.34    0.33    0.28    0.26 
##    post channel 
##    0.21    0.21&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From our resulting associations for both the words, we can see Cricket is associated with the words cup, zimbabwe, score and team. Which makes proper sense because every other words except Zimbabwe are related to game and Zimbabwe is one of the common team with whom Bangladesh have had quite a lot of cricket matches (such insights come from subject matter knowledge!). On the other hand, with the word Rohingya we can see assiciated words camp, refugee, myanmar, repatriation etc. evolve around the crisis created by the Rohingya refugees coming from Bangladesh’s neighboring country Myanmar.&lt;/p&gt;
&lt;p&gt;I will plot the most frequest 100 words now in a barplot to visually see how their frequencies are distributed. Checking the list of frequent words in list and graphically has two benefits: firstly, it gives a feeling about the analysis and secondly, it puts some sort of control on the quality of data cleaning done in previous steps. For example, after generating the most frequent words I found some of the words such as: amp, will, can, get are not removed. So I went back and added these words in the word remove step of data cleaning.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;plot = data.frame(words = names(freq), count = freq)
library(ggplot2)
plot = subset(plot, plot$count &amp;gt; 150) #creating a subset of words having more than 100 frequency
str(plot)
ggplot(data = plot, aes(words, count)) + geom_bar(stat = &amp;#39;identity&amp;#39;) + ggtitle(&amp;#39;Words used more than 150 times&amp;#39;)+coord_flip()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2020-06-23-twitter-sentiment-analysis-on-bangladesh_files/figure-html/unnamed-chunk-15-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div id=&#34;topic-modeling-using-lda&#34; class=&#34;section level1&#34;&gt;
&lt;h1&gt;Topic modeling using LDA&lt;/h1&gt;
&lt;p&gt;I have used ‘topicmodel’ package available in R for topic modeling.
As discussed earlier, in LDA model number of topics are to be selected. Based on which LDA model creates the probability of each topic in each document and also distributes the words under each topic. Selecting more number of topics may result in more grannular segregation but at the same time the differences among different topics may get blurred. While on the other hand selecting very small number of topic can lead to losing possible topic. So to minimze this error I tried three different K or number of topics to create my LDA model. I used 2, 5, 10 as the number of topics and created three different LDA models based on these K values.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;library(topicmodels)
#LDA model with 5 topics selected
lda_5 = LDA(dtm, k = 5, method = &amp;#39;Gibbs&amp;#39;, 
          control = list(nstart = 5, seed = list(1505,99,36,56,88), best = TRUE, 
                         thin = 500, burnin = 4000, iter = 2000))

#LDA model with 2 topics selected
lda_2 = LDA(dtm, k = 2, method = &amp;#39;Gibbs&amp;#39;, 
          control = list(nstart = 5, seed = list(1505,99,36,56,88), best = TRUE, 
                         thin = 500, burnin = 4000, iter = 2000))

#LDA model with 10 topics selected
lda_10 = LDA(dtm, k = 10, method = &amp;#39;Gibbs&amp;#39;, 
          control = list(nstart = 5, seed = list(1505,99,36,56,88), best = TRUE, 
                         thin = 500, burnin = 4000, iter = 2000))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;LDA model produces a good bulk of information. But getting the most frequent words under each topic and document wise probability of each topic are the two most important pieces of information that I can use for my analysis purpose. First of all I will fetch top 10 terms in each topic:&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;#Top 10 terms or words under each topic
top10terms_5 = as.matrix(terms(lda_5,10))
top10terms_2 = as.matrix(terms(lda_2,10))
top10terms_10 = as.matrix(terms(lda_10,10))

top10terms_5&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##       Topic 1   Topic 2    Topic 3   Topic 4    Topic 5 
##  [1,] &amp;quot;news&amp;quot;    &amp;quot;rohingya&amp;quot; &amp;quot;zimbabw&amp;quot; &amp;quot;india&amp;quot;    &amp;quot;new&amp;quot;   
##  [2,] &amp;quot;live&amp;quot;    &amp;quot;refuge&amp;quot;   &amp;quot;cricket&amp;quot; &amp;quot;pakistan&amp;quot; &amp;quot;one&amp;quot;   
##  [3,] &amp;quot;today&amp;quot;   &amp;quot;camp&amp;quot;     &amp;quot;tri&amp;quot;     &amp;quot;peopl&amp;quot;    &amp;quot;year&amp;quot;  
##  [4,] &amp;quot;bangla&amp;quot;  &amp;quot;myanmar&amp;quot;  &amp;quot;seri&amp;quot;    &amp;quot;countri&amp;quot;  &amp;quot;day&amp;quot;   
##  [5,] &amp;quot;dhaka&amp;quot;   &amp;quot;girl&amp;quot;     &amp;quot;match&amp;quot;   &amp;quot;like&amp;quot;     &amp;quot;see&amp;quot;   
##  [6,] &amp;quot;januari&amp;quot; &amp;quot;children&amp;quot; &amp;quot;nation&amp;quot;  &amp;quot;time&amp;quot;     &amp;quot;just&amp;quot;  
##  [7,] &amp;quot;now&amp;quot;     &amp;quot;muslim&amp;quot;   &amp;quot;wicket&amp;quot;  &amp;quot;indian&amp;quot;   &amp;quot;work&amp;quot;  
##  [8,] &amp;quot;latest&amp;quot;  &amp;quot;say&amp;quot;      &amp;quot;odi&amp;quot;     &amp;quot;take&amp;quot;     &amp;quot;week&amp;quot;  
##  [9,] &amp;quot;updat&amp;quot;   &amp;quot;sex&amp;quot;      &amp;quot;banvzim&amp;quot; &amp;quot;don&amp;quot;      &amp;quot;follow&amp;quot;
## [10,] &amp;quot;love&amp;quot;    &amp;quot;million&amp;quot;  &amp;quot;world&amp;quot;   &amp;quot;nepal&amp;quot;    &amp;quot;last&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;top10terms_2&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##       Topic 1    Topic 2   
##  [1,] &amp;quot;rohingya&amp;quot; &amp;quot;news&amp;quot;    
##  [2,] &amp;quot;refuge&amp;quot;   &amp;quot;zimbabw&amp;quot; 
##  [3,] &amp;quot;camp&amp;quot;     &amp;quot;india&amp;quot;   
##  [4,] &amp;quot;myanmar&amp;quot;  &amp;quot;live&amp;quot;    
##  [5,] &amp;quot;peopl&amp;quot;    &amp;quot;cricket&amp;quot; 
##  [6,] &amp;quot;girl&amp;quot;     &amp;quot;today&amp;quot;   
##  [7,] &amp;quot;countri&amp;quot;  &amp;quot;tri&amp;quot;     
##  [8,] &amp;quot;children&amp;quot; &amp;quot;new&amp;quot;     
##  [9,] &amp;quot;like&amp;quot;     &amp;quot;seri&amp;quot;    
## [10,] &amp;quot;one&amp;quot;      &amp;quot;pakistan&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;top10terms_10&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##       Topic 1       Topic 2           Topic 3    Topic 4   Topic 5   Topic 6
##  [1,] &amp;quot;time&amp;quot;        &amp;quot;now&amp;quot;             &amp;quot;india&amp;quot;    &amp;quot;cricket&amp;quot; &amp;quot;zimbabw&amp;quot; &amp;quot;girl&amp;quot; 
##  [2,] &amp;quot;dhaka&amp;quot;       &amp;quot;one&amp;quot;             &amp;quot;pakistan&amp;quot; &amp;quot;world&amp;quot;   &amp;quot;tri&amp;quot;     &amp;quot;sex&amp;quot;  
##  [3,] &amp;quot;bangladeshi&amp;quot; &amp;quot;report&amp;quot;          &amp;quot;like&amp;quot;     &amp;quot;team&amp;quot;    &amp;quot;seri&amp;quot;    &amp;quot;love&amp;quot; 
##  [4,] &amp;quot;make&amp;quot;        &amp;quot;work&amp;quot;            &amp;quot;nepal&amp;quot;    &amp;quot;run&amp;quot;     &amp;quot;match&amp;quot;   &amp;quot;women&amp;quot;
##  [5,] &amp;quot;two&amp;quot;         &amp;quot;watch&amp;quot;           &amp;quot;hindus&amp;quot;   &amp;quot;canada&amp;quot;  &amp;quot;nation&amp;quot;  &amp;quot;nude&amp;quot; 
##  [6,] &amp;quot;islam&amp;quot;       &amp;quot;just&amp;quot;            &amp;quot;south&amp;quot;    &amp;quot;start&amp;quot;   &amp;quot;wicket&amp;quot;  &amp;quot;video&amp;quot;
##  [7,] &amp;quot;high&amp;quot;        &amp;quot;right&amp;quot;           &amp;quot;want&amp;quot;     &amp;quot;day&amp;quot;     &amp;quot;odi&amp;quot;     &amp;quot;kill&amp;quot; 
##  [8,] &amp;quot;state&amp;quot;       &amp;quot;indian&amp;quot;          &amp;quot;think&amp;quot;    &amp;quot;cup&amp;quot;     &amp;quot;first&amp;quot;   &amp;quot;fuck&amp;quot; 
##  [9,] &amp;quot;also&amp;quot;        &amp;quot;mishalhusainbbc&amp;quot; &amp;quot;back&amp;quot;     &amp;quot;score&amp;quot;   &amp;quot;banvzim&amp;quot; &amp;quot;porn&amp;quot; 
## [10,] &amp;quot;much&amp;quot;        &amp;quot;visit&amp;quot;           &amp;quot;take&amp;quot;     &amp;quot;play&amp;quot;    &amp;quot;win&amp;quot;     &amp;quot;dhaka&amp;quot;
##       Topic 7   Topic 8    Topic 9 Topic 10   
##  [1,] &amp;quot;news&amp;quot;    &amp;quot;rohingya&amp;quot; &amp;quot;peopl&amp;quot; &amp;quot;new&amp;quot;      
##  [2,] &amp;quot;today&amp;quot;   &amp;quot;refuge&amp;quot;   &amp;quot;year&amp;quot;  &amp;quot;countri&amp;quot;  
##  [3,] &amp;quot;live&amp;quot;    &amp;quot;camp&amp;quot;     &amp;quot;help&amp;quot;  &amp;quot;see&amp;quot;      
##  [4,] &amp;quot;bangla&amp;quot;  &amp;quot;myanmar&amp;quot;  &amp;quot;need&amp;quot;  &amp;quot;week&amp;quot;     
##  [5,] &amp;quot;januari&amp;quot; &amp;quot;children&amp;quot; &amp;quot;home&amp;quot;  &amp;quot;follow&amp;quot;   
##  [6,] &amp;quot;latest&amp;quot;  &amp;quot;muslim&amp;quot;   &amp;quot;give&amp;quot;  &amp;quot;last&amp;quot;     
##  [7,] &amp;quot;updat&amp;quot;   &amp;quot;say&amp;quot;      &amp;quot;look&amp;quot;  &amp;quot;england&amp;quot;  
##  [8,] &amp;quot;sri&amp;quot;     &amp;quot;million&amp;quot;  &amp;quot;babi&amp;quot;  &amp;quot;australia&amp;quot;
##  [9,] &amp;quot;lanka&amp;quot;   &amp;quot;support&amp;quot;  &amp;quot;sinc&amp;quot;  &amp;quot;bts&amp;quot;      
## [10,] &amp;quot;post&amp;quot;    &amp;quot;repatri&amp;quot;  &amp;quot;even&amp;quot;  &amp;quot;set&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can see that all three models picked the topics of Cricket and Rohingiya. But models with 5 and 10 topics also picked some other topics anlong with these two. From which we can see the application of the previous discussion about grannularity vs generalization. If we look at the top words from all the topics created from model with 10 topics, we can see that overall there is a lack of coherence among the words inside each topic. Similar observation can be made for the model with 5 topics. While the model with 2 topics provide two topics with a compact coherence among the topics. Another important thing to notice is that how the model with 10 topic picked some topic that were ignored by the model with 2 and 5 topics. Such as nudity (topic-6)!&lt;/p&gt;
&lt;p&gt;Since we can clearly see that the topics of ‘Rohingya Crisis’ and ‘Cricket’ are two most common topics, I will move with these topic for further analysis.&lt;/p&gt;
&lt;p&gt;Topics found out by our model:&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;lda.topics_5 = as.matrix(topics(lda_5))
lda.topics_2 = as.matrix(topics(lda_2))
lda.topics_10 = as.matrix(topics(lda_10))
#write.csv(lda.topics_5,file = paste(&amp;#39;LDAGibbs&amp;#39;,5,&amp;#39;DocsToTopics.csv&amp;#39;))
#write.csv(lda.topics_2,file = paste(&amp;#39;LDAGibbs&amp;#39;,2,&amp;#39;DocsToTopics.csv&amp;#39;))
#write.csv(lda.topics_10,file = paste(&amp;#39;LDAGibbs&amp;#39;,10,&amp;#39;DocsToTopics.csv&amp;#39;))

summary(as.factor(lda.topics_5[,1]))&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##    1    2    3    4    5 
## 1208 1293 1230 1003  818&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;summary(as.factor(lda.topics_2[,1]))&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##    1    2 
## 3151 2401&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;summary(as.factor(lda.topics_10[,1]))&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##   1   2   3   4   5   6   7   8   9  10 
## 755 659 607 577 708 546 385 593 364 358&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can also get document wise probability of each topic. I have created three files for each of my model and also saved the output for future use. Probability of each topic:&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;topicprob_5 = as.matrix(lda_5@gamma)
topicprob_2 = as.matrix(lda_2@gamma)
topicprob_10 = as.matrix(lda_10@gamma)

#write.csv(topicprob_5, file = paste(&amp;#39;LDAGibbs&amp;#39;, 5, &amp;#39;DoctToTopicProb.csv&amp;#39;))
#write.csv(topicprob_2, file = paste(&amp;#39;LDAGibbs&amp;#39;, 2, &amp;#39;DoctToTopicProb.csv&amp;#39;))
#write.csv(topicprob_10, file = paste(&amp;#39;LDAGibbs&amp;#39;, 10, &amp;#39;DoctToTopicProb.csv&amp;#39;))

head(topicprob_2,1)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;##           [,1]      [,2]
## [1,] 0.5409836 0.4590164&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a sample we can see that according to my model with 5 topics, how document 1 has different probabilities of containing each topic. The highest probability from topic-2. Accordingly the model classified as representing topic-2.&lt;/p&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;library(tidytext)
library(dplyr)
library(ggplot2)

#Tokenizing character vector file &amp;#39;tweets&amp;#39;.
token = data.frame(text=tweets, stringsAsFactors = FALSE) %&amp;gt;% unnest_tokens(word, text)

#Matching sentiment words from the &amp;#39;NRC&amp;#39; sentiment lexicon
senti = inner_join(token, get_sentiments(&amp;quot;nrc&amp;quot;)) %&amp;gt;%
  count(sentiment)
senti$percent = (senti$n/sum(senti$n))*100

#Plotting the sentiment summary 
ggplot(senti, aes(sentiment, percent)) +   
        geom_bar(aes(fill = sentiment), position = &amp;#39;dodge&amp;#39;, stat = &amp;#39;identity&amp;#39;)+ 
        ggtitle(&amp;quot;Sentiment analysis based on lexicon: &amp;#39;NRC&amp;#39;&amp;quot;)+
  coord_flip() +
        theme(legend.position = &amp;#39;none&amp;#39;, plot.title = element_text(size=18, face = &amp;#39;bold&amp;#39;),
              axis.text=element_text(size=16),
              axis.title=element_text(size=14,face=&amp;quot;bold&amp;quot;))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2020-06-23-twitter-sentiment-analysis-on-bangladesh_files/figure-html/unnamed-chunk-20-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;div id=&#34;additional-analysis-sentiment-analysis-on-rohingya-topic&#34; class=&#34;section level2&#34;&gt;
&lt;h2&gt;Additional analysis: Sentiment analysis on Rohingya topic&lt;/h2&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;library(tm)
library(quanteda)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## Package version: 2.0.1&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## Parallel computing: 2 of 4 threads used.&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## See https://quanteda.io for tutorials and examples.&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## 
## Attaching package: &amp;#39;quanteda&amp;#39;&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## The following objects are masked from &amp;#39;package:tm&amp;#39;:
## 
##     as.DocumentTermMatrix, stopwords&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## The following objects are masked from &amp;#39;package:NLP&amp;#39;:
## 
##     meta, meta&amp;lt;-&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## The following object is masked from &amp;#39;package:utils&amp;#39;:
## 
##     View&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;corpus_roh = corpus(tweets)
corpus_roh = (corpus_roh = subset(corpus_roh, grepl(&amp;#39;rohingya&amp;#39;, texts(corpus_roh))))
writeLines(as.character(corpus_roh[[150]]))&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## the suffering in the rohingya refugee camp in bangladesh is indescribable&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;#Tokenizing character vector file &amp;#39;tweets&amp;#39;.
library(tidytext)
token_roh = tibble(text=corpus_roh)  %&amp;gt;% unnest_tokens(word, text, format = &amp;quot;text&amp;quot;)
 
#Matching sentiment words from the &amp;#39;NRC&amp;#39; sentiment lexicon
library(dplyr)
senti_roh = inner_join(token_roh, get_sentiments(&amp;quot;nrc&amp;quot;)) %&amp;gt;%
  count(sentiment)&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;## Joining, by = &amp;quot;word&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&#34;r&#34;&gt;&lt;code&gt;senti_roh$percent = (senti_roh$n/sum(senti_roh$n))*100

#Plotting the sentiment summary 
library(ggplot2)
ggplot(senti_roh, aes(sentiment, percent)) +   
        geom_bar(aes(fill = sentiment), position = &amp;#39;dodge&amp;#39;, stat = &amp;#39;identity&amp;#39;)+ 
        ggtitle(&amp;quot;Sentiment analysis based on lexicon: &amp;#39;NRC&amp;#39;&amp;quot;)+
  coord_flip() +
        theme(legend.position = &amp;#39;none&amp;#39;, plot.title = element_text(size=18, face = &amp;#39;bold&amp;#39;),
              axis.text=element_text(size=16),
              axis.title=element_text(size=14,face=&amp;quot;bold&amp;quot;))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;https://laminarinsight.com/post/2020-06-23-twitter-sentiment-analysis-on-bangladesh_files/figure-html/unnamed-chunk-21-1.png&#34; width=&#34;672&#34; /&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&#34;overall-finding-and-discussion&#34; class=&#34;section level1&#34;&gt;
&lt;h1&gt;Overall finding and discussion&lt;/h1&gt;
&lt;p&gt;From our random walk on the tweets related to Bangladesh, we have seen ‘cricket’ and ‘Rohingya’ were the two areas that people cared most. Overall, people exuded a positive sentiment along with emotions of trust and anticipation. But in case of Rohingya crisis, we showed a mixed sentiment. About Rohingya issue both the positive and negative sentiments were high. Moreover, the emotions also seemed to be mixed. People felt sorry for the Rohingya people but they also expressed fear. So, what could that mean? Were people sympathetic to the plight of Rohingya but also had some share of fear related to the issue? This study doesn’t allow us to conclude on any such conclusion. But it gives us an idea of what we may achieve by having such a walk. Maybe we need to go for a walk with Bangladesh on the online social media sites more often to get a clearer image on what people talk about Bangladesh and what may needs to be improved to leave a better digital footprint for the country.&lt;/p&gt;
&lt;/div&gt;
</description>
    </item>
    
  </channel>
</rss>
