Persiapan

Packages and Libraries

packages=c('dplyr', 'tidyverse', 'tidytext', 'ggplot2', 'ggraph', 'knitr', 'quRan')
for (p in packages){
  if (! require (p,character.only = T)){
    install.packages(p)
  }
library(p,character.only = T)
}
## Loading required package: dplyr
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
## Loading required package: tidyverse
## -- Attaching packages --------------------------------------- tidyverse 1.3.1 --
## v ggplot2 3.3.5     v purrr   0.3.4
## v tibble  3.1.4     v stringr 1.4.0
## v tidyr   1.1.4     v forcats 0.5.1
## v readr   2.0.1
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
## Loading required package: tidytext
## Loading required package: ggraph
## Loading required package: knitr
## Loading required package: quRan

Fungsi unnest_token Sebelum memuat datanya, mulai dengan surah pertama dalam Al-Qur’an, Al-Fatihah. Kami terutama akan menggunakan terjemahan bahasa Indonesia. Bagian ini hanya memperkenalkan konsep token.

text <- c("Dengan nama Allah Yang Maha Pengasih, Maha Penyayang",
          "Segala puji bagi Allah, Tuhan seluruh alam",
          "Yang Maha Pengasih, Maha Penyayang",
          "Pemilik hari pembalasan",
          "Hanya kepada Engkaulah kami menyembah dan hanya kepada Engkaulah kami mohon pertolongan",
          "Tunjukilah kami jalan yang lurus",
          "(yaitu) jalan orang-orang yang telah Engkau beri nikmat kepadanya; bukan (jalan) mereka yang dimurkai, dan bukan (pula jalan) mereka yang sesat")

text
## [1] "Dengan nama Allah Yang Maha Pengasih, Maha Penyayang"                                                                                           
## [2] "Segala puji bagi Allah, Tuhan seluruh alam"                                                                                                     
## [3] "Yang Maha Pengasih, Maha Penyayang"                                                                                                             
## [4] "Pemilik hari pembalasan"                                                                                                                        
## [5] "Hanya kepada Engkaulah kami menyembah dan hanya kepada Engkaulah kami mohon pertolongan"                                                        
## [6] "Tunjukilah kami jalan yang lurus"                                                                                                               
## [7] "(yaitu) jalan orang-orang yang telah Engkau beri nikmat kepadanya; bukan (jalan) mereka yang dimurkai, dan bukan (pula jalan) mereka yang sesat"

Ini adalah vektor karakter yang khas. Pertama-tama perlu memasukkannya ke dalam bingkai data untuk membuatnya menjadi kumpulan data teks yang rapi

text_df <- tibble(line = 1:7, text = text)
text_df
## # A tibble: 7 x 2
##    line text                                                                    
##   <int> <chr>                                                                   
## 1     1 Dengan nama Allah Yang Maha Pengasih, Maha Penyayang                    
## 2     2 Segala puji bagi Allah, Tuhan seluruh alam                              
## 3     3 Yang Maha Pengasih, Maha Penyayang                                      
## 4     4 Pemilik hari pembalasan                                                 
## 5     5 Hanya kepada Engkaulah kami menyembah dan hanya kepada Engkaulah kami m~
## 6     6 Tunjukilah kami jalan yang lurus                                        
## 7     7 (yaitu) jalan orang-orang yang telah Engkau beri nikmat kepadanya; buka~

Tibble adalah kelas modern dari bingkai data dalam R, tersedia dalam paket dplyr dan tibble. Tibbles sangat bagus untuk digunakan dengan alat yang rapi. Perhatikan bahwa bingkai data yang berisi teks ini belum kompatibel dengan analisis teks yang rapi. Tidak dapat menyaring kata atau menghitung yang paling sering muncul, karena setiap baris terdiri dari beberapa kata gabungan. Perlu mengonversi ini sehingga memiliki satu-token-per-dokumen-per-baris. Token adalah unit teks yang bermakna, paling sering berupa kata, yang ingin kami gunakan untuk analisis lebih lanjut, dan tokenisasi adalah proses pemisahan teks menjadi token. Dalam contoh pertama ini, kita hanya memiliki satu dokumen (Al-Fatihah), tetapi kita akan mengeksplorasi contoh dengan banyak dokumen (Surat). Dalam kerangka teks rapi kita, kita perlu memecah teks menjadi token individu (proses yang disebut tokenization) dan mengubahnya menjadi struktur data yang rapi. * Gunakan fungsi tidytext’s unnest_tokens().

text_df %>%
  unnest_tokens(word, text)
## # A tibble: 62 x 2
##     line word     
##    <int> <chr>    
##  1     1 dengan   
##  2     1 nama     
##  3     1 allah    
##  4     1 yang     
##  5     1 maha     
##  6     1 pengasih 
##  7     1 maha     
##  8     1 penyayang
##  9     2 segala   
## 10     2 puji     
## # ... with 52 more rows

Setelah menggunakan unnest_tokens, ada satu token (kata) di setiap baris dari bingkai data baru; tokenization default di unnest_tokens() adalah untuk kata tunggal. Kolom lain, seperti nomor baris dari setiap kata, dipertahankan. Tanda baca telah diambil. *Secara default, unnest_tokens() mengonversi token menjadi huruf kecil, yang membuatnya lebih mudah untuk dibandingkan atau digabungkan dengan kumpulan data lainnya. (Gunakan argumen to_lower = FALSE untuk mematikan fitur ini).

Sekarang kita dapat memanipulasi, memproses, dan memvisualisasikan teks menggunakan seperangkat alat standar rapi, yaitu dplyr, rapir, dan ggplot2

Fokus pada versi dan Variabel Quran yang Dipilih

Paket quran memiliki 4 versi quran. Ini memberikan ayat-ayat penuh Al-Qur’an, dalam bingkai data yang berisi satu baris per ayat, diformat agar nyaman untuk analisis teks: 1. quran_ar (Quran dalam bahasa Arab dengan vokal) 2. quran_ar_min (Quran dalam bahasa Arab tanpa vokal) 3. quran_en_sahih (Quran dalam bahasa Inggris, terjemahan Shahih Internasional) 4. quran_en_yusufali (Quran dalam bahasa Inggris, terjemahan Yusuf Ali)

Disini akan menganalisis variabel yang dipilih (kolom) dari quran_en_sahih

quranES <- quran_en_sahih %>% select(surah_id, 
                                   ayah_id,
                                   surah_title_en, 
                                   surah_title_en_trans, 
                                   revelation_type, 
                                   text, 
                                   surah, 
                                   ayah, 
                                   ayah_title)
tidyES <- quranES %>%
  unnest_tokens(word, text)
tidyES
## # A tibble: 158,065 x 9
##    surah_id ayah_id surah_title_en surah_title_en_t~ revelation_type surah  ayah
##       <int>   <int> <fct>          <fct>             <chr>           <int> <int>
##  1        1       1 Al-Faatiha     The Opening       Meccan              1     1
##  2        1       1 Al-Faatiha     The Opening       Meccan              1     1
##  3        1       1 Al-Faatiha     The Opening       Meccan              1     1
##  4        1       1 Al-Faatiha     The Opening       Meccan              1     1
##  5        1       1 Al-Faatiha     The Opening       Meccan              1     1
##  6        1       1 Al-Faatiha     The Opening       Meccan              1     1
##  7        1       1 Al-Faatiha     The Opening       Meccan              1     1
##  8        1       1 Al-Faatiha     The Opening       Meccan              1     1
##  9        1       1 Al-Faatiha     The Opening       Meccan              1     1
## 10        1       1 Al-Faatiha     The Opening       Meccan              1     1
## # ... with 158,055 more rows, and 2 more variables: ayah_title <chr>,
## #   word <chr>

Sekarang data dalam format satu kata per baris, kita dapat memanipulasinya dengan alat yang rapi seperti dplyr. Seringkali dalam analisis teks, kami menghapus kata-kata berhenti; stop words adalah kata-kata yang tidak berguna untuk analisis, biasanya kata-kata yang sangat umum seperti “the”, “of”, “to”, dan sebagainya dalam bahasa Inggris. Kita dapat menghapus stopwords (disimpan dalam dataset rapi stop_words) dengan anti_join().

data(stop_words)

tidyES <- tidyES %>%
  anti_join(stop_words)
## Joining, by = "word"

Dataset stop_words dalam paket cleantext berisi stopwords dari tiga leksikon. Disini dapat menggunakan semuanya bersama-sama, seperti yang dimiliki di sini, atau filter() untuk hanya menggunakan satu set stopword jika itu lebih sesuai untuk analisis tertentu.

Hitung dan Plot

Juga dapat menggunakan dplyr’s count() untuk menemukan kata-kata yang paling umum di seluruh Quran secara keseluruhan. Karena telah menggunakan alat yang rapi, jumlah kata disimpan dalam bingkai data yang rapi. Ini memungkinkan untuk menyalurkan ini langsung ke paket ggplot2, misalnya untuk membuat visualisasi kata-kata yang paling umum dalam Terjemahan Internasional Sahih dari Quran. Dengan memplot kata-kata yang muncul lebih dari 150 kali.

tidyES %>% count(word, sort = TRUE)
## # A tibble: 4,783 x 2
##    word           n
##    <chr>      <int>
##  1 allah       2973
##  2 lord         971
##  3 people       732
##  4 day          497
##  5 earth        402
##  6 punishment   350
##  7 fear         281
##  8 muhammad     264
##  9 believed     262
## 10 messenger    242
## # ... with 4,773 more rows
tidyES %>%
  count(word, sort = TRUE) %>%
  filter(n > 150) %>%
  mutate(word = reorder(word, n)) %>%
  ggplot(aes(x = word, y = n)) +
  geom_col() +
  xlab(NULL) +
  coord_flip() +
  theme(axis.text = element_text( 
    angle = 0, 
    color="blue", 
    size=10)
  )

Ulangi hal yang sama untuk (Quran dalam bahasa Inggris, terjemahan Yusuf Ali)

quranEY <- quran_en_yusufali %>% select(surah_id, 
                                   ayah_id,
                                   surah_title_en, 
                                   surah_title_en_trans, 
                                   revelation_type, 
                                   text, 
                                   surah, 
                                   ayah, 
                                   ayah_title)
tidyEY <- quranEY %>%
  unnest_tokens(word, text)
tidyEY
## # A tibble: 167,859 x 9
##    surah_id ayah_id surah_title_en surah_title_en_t~ revelation_type surah  ayah
##       <int>   <int> <fct>          <fct>             <chr>           <int> <int>
##  1        1       1 Al-Faatiha     The Opening       Meccan              1     1
##  2        1       1 Al-Faatiha     The Opening       Meccan              1     1
##  3        1       1 Al-Faatiha     The Opening       Meccan              1     1
##  4        1       1 Al-Faatiha     The Opening       Meccan              1     1
##  5        1       1 Al-Faatiha     The Opening       Meccan              1     1
##  6        1       1 Al-Faatiha     The Opening       Meccan              1     1
##  7        1       1 Al-Faatiha     The Opening       Meccan              1     1
##  8        1       1 Al-Faatiha     The Opening       Meccan              1     1
##  9        1       1 Al-Faatiha     The Opening       Meccan              1     1
## 10        1       2 Al-Faatiha     The Opening       Meccan              1     2
## # ... with 167,849 more rows, and 2 more variables: ayah_title <chr>,
## #   word <chr>

Terjemahan ini menggunakan kata-kata seperti “kamu” dan “engkau” jadi kami ingin menyaringnya juga.

my_stopwords <- tibble(word = c('ye', 'verily', 'will', 'said', 'say', 'us', 
                                'thy', 'thee', 'thou', 'hath', 'doth'))
tidyEY <- tidyEY %>%
  anti_join(my_stopwords)
## Joining, by = "word"

Sekarang menghitung dan memplot kata-kata yang muncul lebih dari 150 kali.

Analisis sentimen dengan tidy data

Salah satu cara untuk menganalisis sentimen dari sebuah teks adalah dengan mempertimbangkan teks sebagai kombinasi dari kata-kata individualnya dan konten sentimen dari keseluruhan teks sebagai jumlah dari konten sentimen dari masing-masing kata. Ada pendekatan lain tetapi pendekatan ini dapat dengan mudah memanfaatkan alat yang rapi.

Dataset Sentimen tidytext menyediakan akses ke beberapa leksikon sentimen. Tiga leksikon tujuan umum adalah 1. AFINN dari Finn rup Nielsen, 2. bing dari Bing Liu dan kolaborator, dan 3. nrc dari Saif Mohammad dan Peter Turney.

Ketiga leksikon ini didasarkan pada unigram, yaitu kata tunggal. Leksikon ini mengandung banyak kata bahasa Inggris dan kata-kata tersebut diberi skor untuk sentimen positif/negatif, dan juga mungkin emosi seperti kegembiraan, kemarahan, kesedihan, dan sebagainya. Dalam posting ini, kita akan menggunakan bing leksikon yang mengkategorikan kata-kata secara biner ke dalam kategori positif dan negatif.

Fungsi get_sentiments() memungkinkan kita untuk mendapatkan leksikon sentimen tertentu. Misalnya, get_sentiments(“afinn”). Kami akan menggunakan

get_sentiments("bing")
## # A tibble: 6,786 x 2
##    word        sentiment
##    <chr>       <chr>    
##  1 2-faces     negative 
##  2 abnormal    negative 
##  3 abolish     negative 
##  4 abominable  negative 
##  5 abominably  negative 
##  6 abominate   negative 
##  7 abomination negative 
##  8 abort       negative 
##  9 aborted     negative 
## 10 aborts      negative 
## # ... with 6,776 more rows

Kata-kata positif dan negatif yang paling umum

Salah satu keuntungan memiliki bingkai data dengan sentimen dan kata adalah kita dapat menganalisis jumlah kata yang berkontribusi pada setiap sentimen.

Dengan menerapkan count() di sini dengan argumen kata dan sentimen, dengan mengetahui seberapa besar kontribusi setiap kata pada setiap sentimen. Ini dapat ditampilkan secara visual, dan dapat menyalurkan langsung ke ggplot2, jika kami suka, karena cara kami secara konsisten menggunakan alat yang dibuat untuk menangani bingkai tidy data

bing_word_counts <- tidyES %>%
  inner_join(get_sentiments("bing")) %>%
  count(word, sentiment, sort = TRUE) %>%
  ungroup()
## Joining, by = "word"
bing_word_counts
## # A tibble: 972 x 3
##    word       sentiment     n
##    <chr>      <chr>     <int>
##  1 fear       negative    281
##  2 merciful   positive    183
##  3 righteous  positive    167
##  4 mercy      positive    146
##  5 exalted    positive    143
##  6 reward     positive    141
##  7 evil       negative    139
##  8 disbelieve negative    122
##  9 denied     negative    100
## 10 wise       positive     98
## # ... with 962 more rows
bing_word_counts %>%
  group_by(sentiment) %>%
  top_n(20) %>%
  ungroup() %>%
  mutate(word = reorder(word, n)) %>%
  ggplot(aes(word, n, fill = sentiment)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(~sentiment, scales = "free_y") +
  labs(y = "Contribution to sentiment",
       x = NULL) +
  coord_flip() +
  theme(axis.text = element_text( 
    angle = 0, 
    color="blue", 
    size=10))
## Selecting by n

Versi Yusuf Ali

bing_word_counts <- tidyEY %>%
  inner_join(get_sentiments("bing")) %>%
  count(word, sentiment, sort = TRUE) %>%
  ungroup()
## Joining, by = "word"
bing_word_counts
## # A tibble: 1,249 x 3
##    word    sentiment     n
##    <chr>   <chr>     <int>
##  1 good    positive    278
##  2 fear    negative    274
##  3 evil    negative    268
##  4 faith   positive    257
##  5 penalty negative    229
##  6 wrong   negative    206
##  7 reject  negative    177
##  8 well    positive    177
##  9 right   positive    176
## 10 mercy   positive    164
## # ... with 1,239 more rows
bing_word_counts %>%
  group_by(sentiment) %>%
  top_n(20) %>%
  ungroup() %>%
  mutate(word = reorder(word, n)) %>%
  ggplot(aes(word, n, fill = sentiment)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(~sentiment, scales = "free_y") +
  labs(y = "Contribution to sentiment",
       x = NULL) +
  coord_flip() +
  theme(axis.text = element_text( 
    angle = 0, 
    color="blue", 
    size=10))
## Selecting by n

Untuk kedua terjemahan bentuknya identik untuk 2 pasang graf. Banyak dari kata-katanya juga mirip.

Memperbesar ke dalam Surah

bingnegative <- get_sentiments("bing") %>% 
  filter(sentiment == "negative")

wordcounts <- tidyES %>%
  group_by(surah_title_en) %>%
  summarize(words = n())

tidyES %>%
  semi_join(bingnegative) %>%
  group_by(surah_title_en) %>%
  summarize(negativewords = n()) %>%
  left_join(wordcounts, by = c("surah_title_en")) %>%
  mutate(ratio = negativewords/words) %>%
  top_n(20) %>%
  ggplot(aes(x = surah_title_en, y = ratio)) +
  geom_col() +
  xlab(NULL) +
  coord_flip() +
  theme(axis.text = element_text( 
    angle = 0, 
    color="blue", 
    size=10))
## Joining, by = "word"
## Selecting by ratio

Ini adalah Surah atau bab dengan kata-kata yang paling sedih, dinormalisasi untuk jumlah kata dalam Surah. Diulangi untuk versi Yusufali.

bingnegative <- get_sentiments("bing") %>% 
  filter(sentiment == "negative")

wordcounts <- tidyEY %>%
  group_by(surah_title_en) %>%
  summarize(words = n())

tidyES %>%
  semi_join(bingnegative) %>%
  group_by(surah_title_en) %>%
  summarize(negativewords = n()) %>%
  left_join(wordcounts, by = c("surah_title_en")) %>%
  mutate(ratio = negativewords/words) %>%
  top_n(20) %>%
  ggplot(aes(x = surah_title_en, y = ratio)) +
  geom_col() +
  xlab(NULL) +
  coord_flip() +
  theme(axis.text = element_text( 
    angle = 0, 
    color="blue", 
    size=10))
## Joining, by = "word"
## Selecting by ratio

Wordclouds

Memiliki data dalam format tidy berguna untuk plot lain juga. Dengan menggunakan paket wordcloud, kita dapat melihat kata-kata yang paling umum dalam Quran bahasa Inggris lagi, tapi kali ini sebagai wordcloud.

library(wordcloud)
## Loading required package: RColorBrewer
tidyES %>%
  count(word) %>%
  with(wordcloud(word, n, max.words = 100))

Untuk versi Yusufali, wordcloud terlihat seperti ini,

library(wordcloud)
tidyEY %>%
  count(word) %>%
  with(wordcloud(word, n, max.words = 100))

Dalam fungsi lain, seperti perbandingan.cloud(), mungkin perlu mengubah bingkai data menjadi matriks dengan acast() reshape2. Banyak langkah semua bisa dilakukan dengan join, piping, dan dplyr karena data dalam format tidy.

library(reshape2)
## 
## Attaching package: 'reshape2'
## The following object is masked from 'package:tidyr':
## 
##     smiths
tidyES %>%
  inner_join(get_sentiments("bing")) %>%
  count(word, sentiment, sort = TRUE) %>%
  acast(word ~ sentiment, value.var = "n", fill = 0) %>%
  comparison.cloud(colors = c("#eb52a6", "#54f0b1"),
                   max.words = 50)
## Joining, by = "word"
## Warning in comparison.cloud(., colors = c("#eb52a6", "#54f0b1"), max.words =
## 50): righteousness could not be fit on page. It will not be plotted.
## Warning in comparison.cloud(., colors = c("#eb52a6", "#54f0b1"), max.words =
## 50): enjoyment could not be fit on page. It will not be plotted.

Ulangi hal yang sama untuk Yusufali.

library(reshape2)
tidyEY %>%
  inner_join(get_sentiments("bing")) %>%
  count(word, sentiment, sort = TRUE) %>%
  acast(word ~ sentiment, value.var = "n", fill = 0) %>%
  comparison.cloud(colors = c("#eb52a6", "#54f0b1"),
                   max.words = 50)
## Joining, by = "word"
## Warning in comparison.cloud(., colors = c("#eb52a6", "#54f0b1"), max.words =
## 50): righteous could not be fit on page. It will not be plotted.
## Warning in comparison.cloud(., colors = c("#eb52a6", "#54f0b1"), max.words =
## 50): righteousness could not be fit on page. It will not be plotted.

Daftar Pustaka :

  1. Text Mining with R - A Tidy Approach, by Julia Silge and David Robinson
  2. quRan: Complete Text of the Qur’an by Andrew Heiss
  3. Arnold, Taylor B. 2016. cleanNLP: A Tidy Data Model for Natural Language Processing. https://cran.r-project.org/package=cleanNLP.
  4. Arnold, Taylor, and Lauren Tilton. 2016. coreNLP: Wrappers Around Stanford Corenlp Tools. https://cran.r-project.org/package=coreNLP.
  5. Rinker, Tyler W. 2017. sentimentr: Calculate Text Polarity Sentiment. Buffalo, New York: University at Buffalo/SUNY. http://github.com/trinker/sentimentr.
  6. Pedersen, Thomas Lin. 2017. ggraph: An Implementation of Grammar of Graphics for Graphs and Networks. https://cran.r-project.org/package=ggraph.