Basic Text Mining

Loading libraries needed for text mining

suppressMessages(library(SnowballC)) 
suppressMessages(library(tm))
suppressMessages(library(RColorBrewer))
suppressMessages(library(ggplot2))
suppressMessages(library(Rcampdf))
suppressMessages(library(wordcloud))
suppressMessages(library(biclust))
suppressMessages(library(cluster))
suppressMessages(library(igraph))
suppressMessages(library(fpc))
suppressMessages(library(NLP))

Loading Texts

Saving the text files in a folder titled: “texts” This will be the “corpus” (body) of texts will be mining.

cname <- file.path("C:", "texts")   
cname   
## [1] "C:/texts"
dir(cname)   
## [1] "01.txt" "02.txt" "03.txt" "04.txt" "05.txt" "06.txt" "07.txt" "08.txt"

Load the R package for text mining and then load our texts into R.

docs <- VCorpus(DirSource(cname))   
summary(docs) 
##        Length Class             Mode
## 01.txt 2      PlainTextDocument list
## 02.txt 2      PlainTextDocument list
## 03.txt 2      PlainTextDocument list
## 04.txt 2      PlainTextDocument list
## 05.txt 2      PlainTextDocument list
## 06.txt 2      PlainTextDocument list
## 07.txt 2      PlainTextDocument list
## 08.txt 2      PlainTextDocument list

For details about documents in the corpus, use the inspect(docs) command.

inspect(docs[1])
## <<VCorpus>>
## Metadata:  corpus specific: 0, document level (indexed): 0
## Content:  documents: 1
## 
## [[1]]
## <<PlainTextDocument>>
## Metadata:  7
## Content:  chars: 7457

In this case, this is only showing the details on only the second document in the corpus. But this is not a lot of information. Essentially, all we got is the number of characters in each document in the corpus. Documents are identified by the number in which they are loaded.

We can read our documents in the R terminal using writeLines(as.character(docs)). Or, if we prefer to look at only one of the documents we loaded, then we can specify which one using something like:

writeLines(as.character(docs[1]))
## list(list(content = c("[SALAH] “Islam tdk boleh ditegakkan”", "March 2, 2019 Aribowo Sasmito Fitnah / Hasut / Hoax 0", "", "", "Pelintiran daur ulang, konfirmasi oleh Imam Besar Masjid di Angola tidak ada pelarangan agama Islam di Angola. Selengkapnya di bagian PENJELASAN dan REFERENSI.", "", "======", "", "KATEGORI", "", "Konten yang Salah.", "", "======", "", "SUMBER", "", "http://bit.ly/2IKhEHG http://archive.today/OI6xT, post oleh akun “Mutia Mutiah” (facebook.com/mutia.mutiah.980), sudah dibagikan 3.487 kali per tangkapan layar dibuat.", 
## "", "======", "", "NARASI", "", "“ANGOLA BYK UTANG MA CINA,", "Konsekuen nya Islam tdk boleh ditegakkan,byk mesjid ditutup,akhirnya pd sholat di jalanan &ditembaki oleh polisi.", "", "Hello Muslim Indonesia ,elo mau digituin??", "", "Jangan sampai indonesia seperti anggola.setelah tak boleh bayar hutang sama cina mk negara itu tidak bisa berbuat apa 2xkarna semua apa yang ada di anggola telah di kuasai cina,ummat muslim dkriminalisasi mesjid ditutup dan lain lainnya??", "Simak yg disampaikan ulama ??”.", 
## "", "======", "", "PENJELASAN", "", "(1) http://bit.ly/2rhTadC / http://bit.ly/2MxVN7S, First Draft News: “Konten yang Salah", "", "Ketika konten yang asli dipadankan dengan konteks informasi yang salah”.", "", "Post SUMBER membagikan foto dari http://bit.ly/2Img75z, akun “portalmuslim” (instagram.com/portalmuslim/).", "Post SUMBER menambahkan narasi untuk membangun premis pelintiran, menghubungkan antara hutang dengan isu yang berdasarkan konfirmasi oleh yang berada di lokasi dinyatakan tidak benar.", 
## "——", "", "(2) Beberapa artikel yang berhubungan:", "", "detikNews: “Pesan Berantai Islam Dilarang di Angola Tidak Benar”, selengkapnya di (1) bagian REFERENSI.", "BBC: “Mitos yang gigih bahwa Islam dilarang di Angola”, selengkapnya di (2) bagian REFERENSI.", "======", "", "REFERENSI", "", "(1) http://bit.ly/2H3j4bZ, “Kamis 28 Januari 2016, 12:24 WIB", "", "Hoax or Not", "", "Pesan Berantai Islam Dilarang di Angola Tidak Benar", "", "Salmah Muslimah – detikNews", "", "(foto)", "Ilustrator: Zaki Alfarabi", 
## "", "Jakarta – ", "Isu:", "", "Beredar pesan berantai yang berisi informasi tentang peristiwa di Angola, di mana agama Islam dilarang dan tidak diakui. Selain itu, banyak masjid yang dirubuhkan dan dibakar karena dianggap ilegal dan tak berizin. Pesan itu menyebar secara viral dan meminta umat Islam bereaksi.", "", "Pesan itu berupa poster bergambar seorang tokoh Angola, gambar masjid yang dirubuhkn dan sebuah artikel berbahasa Melayu. Isinya menyebutkan Angola mengharamkan agama Islam karena dianggap bertentangan dengan budaya.", 
## "", "Investigasi:", "", "detikcom menelusuri awal pesan tersebut, termasuk media asing yang menuliskan berita tentang pelarangan Islam di Angola. Hasilnya, memang ada sejumlah media asing seperti Al Jazeera, Daily Mail dan International Business Time yang memberitakan hal tersebut. Namun perlu dicatat, kabar tersebut diberitakan tahun 2013 lalu. Sementara untuk tahun 2016 atau 2015 pemberitaan itu hampir tidak ada, kecuali di media lokal Pakistan.", "", "detikcom juga mengontak KBRI di Windhoek, Namibia yang juga merangkap untuk Angola pada Rabu (28/1) malam. Di ujung telepon menjawab Konselur Pensosbud Pramudya Sulaksono. Dia mengaku juga mendapat kabar soal isu itu.", 
## "", "“Akhir 2015 lalu kami ke Angola dan melakukan konfirmasi,” jelas Pramudya.", "", "KBRI Windhoek mengontak Kemlu Angola juga imam besar masjid di Angola. Konfirmasi didapatkan, tidak ada pembakaran dan pelarangan Islam.", "", "Menurut Pramudya, isu yang berkembang ini sudah lama, sejak 2013 lalu. Tapi entah mengapa, isu ini muncul lagi di media di Indonesia dan Pakistan, serta beberapa negara Islam.", "", "“Di Angola ini memang sedang berkembang ekonominya. Minyak sedang booming di sini. Mayoritas penduduk di sini Katolik karena pernah menjadi jajahan Portugis, Islam juga ada di bagian utara, serta ekspatriat yang datang,” terang dia.", 
## "", "“Isu lama ini sedang diangkat kembali. Kami tegaskan, sudah kami konfirmasi tidak ada pelarangan Islam di sini, Imam Besar Masjid di Angola juga sudah memastikan,” tutur dia.", "", "Kesimpulan:", "", "Informasi yang beredar mengenai pelarangan Islam dan pembakaran serta pengrusakan masjid di Angola tidak benar atau hoax. Masalah itu memang pernah terjadi tahun 2013 lalu. Namun saat ini Islam sudah diterima di Angola. (slm/mad)”", "", "——", "", "(2) BBC: “Mitos yang gigih bahwa Islam dilarang di Angola", 
## "", "18 Oktober 2016", "", "(foto)", "", "Laporan palsu bahwa Angola telah menjadi negara pertama di dunia yang melarang Islam telah muncul kembali. Wartawan BBC Clare Spencer bertanya apakah ini terkait dengan pemilihan presiden AS.", "", "“Orang Muslim sangat gila sekarang,” tulis Frank Lea di Freedom Daily .", "", "“Otoritas Angola melarang Islam, yang mereka anggap sesat, BUKAN agama,” lanjut situs web Liberty Is Viral .", "", "Cerita ini memberikan rincian tentang sebuah masjid yang dirampok di permukiman Zango di ibu kota Angola, Luanda.", 
## "", "“Mereka melihat apa yang dilakukan Muslim untuk non-Muslim, khususnya di Afrika, dan mengambil langkah untuk mencegah hal itu terjadi di Angola,” cerita yang diterbitkan oleh ReaganCoalition.com mengatakan.", "", "“Mungkin AS bisa belajar satu atau dua hal dari Angola,” tambah situs Amerika First Patriots , yang mengatakan 80 masjid telah dilibas.", "", "Tapi cerita aslinya tidak benar.", "", "Kontak di Luanda mengambil foto ini bulan lalu dari sebuah masjid yang masih berfungsi:", "", "(foto)", 
## "", "Salah satu Muslim Angola, Adam Campos, mengatakan kepada BBC bahwa sebenarnya komunitas Muslim “bertumbuh setiap hari”.", "", "Tapi Mr Campos mengatakan masjidnya sendiri ditutup oleh pemerintah beberapa tahun yang lalu dan, pada periode yang sama, beberapa hancur.", "", "Di sinilah kesalahpahaman bahwa Islam telah dilarang tampaknya berasal.", "", "Dia menjelaskan bahwa masjid dihancurkan karena pemerintah mengatakan mereka tidak memiliki izin untuk dibangun.", "", "Dia menambahkan bahwa tidak semua dari mereka ditutup, dan dia pergi ke yang lain untuk berdoa, meskipun kadang-kadang orang memilih untuk beribadah di luar masjid tertutupnya.", 
## "", "Kemudian, setelah beberapa bulan, dan para pengacara terlibat, masjid tiga lantai di daerah Hoji-ya-Henda di Luanda dibuka kembali.", "", "“Islam tidak dilarang di Angola, kami menghadapi beberapa kesulitan seperti kelompok agama minoritas lainnya, karena kami tidak diakui oleh pemerintah.”", "", "Sekarang “semuanya tenang, dan saya berharap mereka terus seperti ini” katanya.", "", "Namun kembali pada tahun 2013 berita tentang larangan yang diduga menyebar dari surat kabar berbahasa Perancis , La Nouvelle Tribune ke Daily Mail Inggris dan sejauh India Today.", 
## "", "Sebuah kelompok di London begitu marah sehingga mereka melakukan protes di luar kedutaan Angola, yang fotografer Peter Marshall dokumentasikan .", "", "Hak cipta gambarPETER MARSHALL", "Surat kabar Afrika Selatan Daily Maverick memecahkan mitos itu tak lama setelah pertama kali muncul.", "", "“Tidak” katanya “Angola tidak ‘melarang Islam’. Ini sedikit lebih rumit dari itu”.", "", "Banyak, termasuk Daily Mail, mengutip Menteri Kebudayaan Angola Rosa Cruz e Silva yang mengatakan bahwa masjid akan ditutup sampai pemberitahuan lebih lanjut.", 
## "", "Satu detail, yang memberi cerita lebih banyak kepercayaan, adalah bahwa pemerintah telah menolak aplikasi kelompok Muslim untuk pengakuan hukum.", "", "Ini tampaknya benar.", "", "Ini adalah apa yang dimaksud Campos ketika dia mengatakan bahwa Islam tidak diakui oleh pemerintah.", "", "Namun, tampaknya tidak secara khusus anti-Muslim karena banyak kelompok agama lain juga tidak diakui.", "", "…”", "", "Google Translate dengan penyesuaian seperlunya, selengkapnya di http://bit.ly/2Erf0RS. Tautan ke artikel dengan bahasa asli (English): https://bbc.in/2H6HNfz.", 
## "", "——", "", "(3) [SALAH] “Angola Resmi Larang Islam di Negaranya”, post sebelumnya di http://bit.ly/2Uci7nq.", "", "——", "", "(4) Pertanyaan oleh salah satu anggota FAFHH.", "", "======", "", "Sumber: https://web.facebook.com/groups/fafhh/permalink/847591492240054/"), meta = list(author = character(0), datetimestamp = list(sec = 9.63289594650269, min = 5, hour = 2, mday = 5, mon = 2, year = 119, wday = 2, yday = 63, isdst = 0), description = character(0), heading = character(0), id = "01.txt", 
##     language = "en", origin = character(0))))
## list()
## list()

In this case, we will have called up only the second document we loaded - as indicated by the ‘[2]’.

Preprocessing

Once we are sure that all documents loaded properly, we go on to preprocess the texts. This step will allow us to remove numbers, capitalization, common words, punctuation, and otherwise prepare our texts for analysis. This can be somewhat time consuming and picky, but it pays off in the end in terms of high quality analyses.

Removing punctuation: Punctuation and other special characters only look like more words to our computer and R. Use the following to methods to remove them from our text.

docs <- tm_map(docs,removePunctuation)   
# writeLines(as.character(docs[1])) 
    # The 'writeLines()' function is commented out to save space.

If necesasry, such as when working with standardized documents or emails, we can remove special characters. This list has been customized to remove punctuation that we commonly find in emails. we can customize what is removed by changing them as we see fit, to meet our own unique needs.

for (j in seq(docs)) {
    docs[[j]] <- gsub("/", " ", docs[[j]])
    docs[[j]] <- gsub("@", " ", docs[[j]])
    docs[[j]] <- gsub("\\|", " ", docs[[j]])
    docs[[j]] <- gsub("=", " ", docs[[j]])
    docs[[j]] <- gsub("\u2028", " ", docs[[j]])  
}
# writeLines(as.character(docs[1])) 

Removing numbers:

docs <- tm_map(docs, removeNumbers)   
#writeLines(as.character(docs[1])) 

Converting to lowercase: As before, we want a word to appear exactly the same every time it appears. We therefore change everything to lowercase.

docs <- tm_map(docs, tolower)   
docs <- tm_map(docs, PlainTextDocument)
DocsCopy <- docs
#writeLines(as.character(docs[1])) 

Stripping unnecesary whitespace from our documents: The above preprocessing will leave the documents with a lot of “white space”. White space is the result of all the left over spaces that were not removed along with the words that were deleted. The white space can, and should, be removed.

docs <- tm_map(docs, stripWhitespace)
#writeLines(as.character(docs[1])) 

To Finish

Be sure to use the following script once we have completed preprocessing. This tells R to treat our preprocessed documents as text documents.

docs <- tm_map(docs, PlainTextDocument)

This is the end of the preprocessing stage.

Stage the Data

To proceed, create a document term matrix. This is what we will be using from this point on.

dtm <- DocumentTermMatrix(docs)   
dtm 
## <<DocumentTermMatrix (documents: 8, terms: 2368)>>
## Non-/sparse entries: 3691/15253
## Sparsity           : 81%
## Maximal term length: 141
## Weighting          : term frequency (tf)

we’ll also need a transpose of this matrix. Create it using:

tdm <- TermDocumentMatrix(docs)   
tdm
## <<TermDocumentMatrix (terms: 2368, documents: 8)>>
## Non-/sparse entries: 3691/15253
## Sparsity           : 81%
## Maximal term length: 141
## Weighting          : term frequency (tf)

Explore our data

Organize terms by their frequency:

freq <- colSums(as.matrix(dtm))   
length(freq)
## [1] 2368
ord <- order(freq)

If we prefer to export the matrix to Excel:

m <- as.matrix(dtm)   
dim(m)   
## [1]    8 2368
write.csv(m, file="DocumentTermMatrix.csv")

Focus!

We can focus on just The ‘removeSparseTerms()’ function will remove the infrequently used words, leaving only the most well-used words in the corpus.

#  Start by removing sparse terms:   
dtms <- removeSparseTerms(dtm, 0.2) # This makes a matrix that is 20% empty space, maximum.   
dtms
## <<DocumentTermMatrix (documents: 8, terms: 29)>>
## Non-/sparse entries: 224/8
## Sparsity           : 3%
## Maximal term length: 10
## Weighting          : term frequency (tf)

Word Frequency

There are a lot of terms, so for now, just check out some of the most and least frequently occurring words.

freq <- colSums(as.matrix(dtm))

Check out the frequency of frequencies.

The ‘colSums()’ function generates a table reporting how often each word frequency occurs. Using the ’head()" function, below, we can see the distribution of the least-frequently used words.

head(table(freq), 15) 
## freq
##    1    2    3    4    5    6    7    8    9   10   11   12   13   14   15 
## 1234  504  169  121   55   59   27   30   24   24   15   12   10    5    8

The resulting output is two rows of numbers. The top number is the frequency with which words appear and the bottom number reflects how many words appear that frequently. Here, considering only the 20 lowest word frequencies, we can see that 1602 terms appear only once. There are also a lot of others that appear very infrequently.

For a look at the most frequently used terms, we can use the ‘tail()’ function.

tail(table(freq), 15) 
## freq
##  39  42  43  49  51  52  57  60  61  67  68  89  97 143 236 
##   1   1   1   1   1   1   2   1   1   1   1   1   1   1   1

Considering only the 15 greatest frequencies, we can see that there is a huge disparity in how frequently some terms appear.

For a less, fine-grained look at term freqency we can view a table of the terms we selected when we removed sparse terms, above. (Look just under the word “Focus”.)

freq <- colSums(as.matrix(dtms))   
freq   
##       akun      bahwa        dan       dari     dengan     fitnah 
##         25         20        143         60         68          8 
##       foto      hasut       hoax        ini        itu   kategori 
##         49          8         11         52         67          8 
##     ketika      march     narasi       oleh       pada penjelasan 
##         11          8         16         57         26         17 
##  referensi      salah    sebagai   sejumlah     selain    seperti 
##         28         36         16          8         10         24 
##     sumber      telah   tersebut      tidak       yang 
##         36         20         28         89        236

The above matrix was created using a data transformation we made earlier. What follows is an alternative that will accomplish essentially the same thing.

freq <- sort(colSums(as.matrix(dtm)), decreasing=TRUE)   
head(freq, 14)
##   yang    dan aborsi  tidak dengan    itu  untuk   dari   atau   oleh 
##    236    143     97     89     68     67     61     60     57     57 
##    ini   aman   foto  dalam 
##     52     51     49     43
wf <- data.frame(word=names(freq), freq=freq)   
head(wf)  
##          word freq
## yang     yang  236
## dan       dan  143
## aborsi aborsi   97
## tidak   tidak   89
## dengan dengan   68
## itu       itu   67

Plot Word Frequencies

Plot words that appear at least 50 times.

library(ggplot2)
p <- ggplot(subset(wf, freq>50), aes(x = reorder(word, -freq), y = freq)) +
          geom_bar(stat = "identity") + 
          theme(axis.text.x=element_text(angle=45, hjust=1))
p   

Word Clouds!

Humans are generally strong at visual analytics. That is part of the reason that these have become so popular. What follows are a variety of alternatives for constructing word clouds with our text.

set.seed(142)   
wordcloud(names(freq), freq, min.freq=25)

Plot the 100 most frequently used words.

set.seed(142)   
wordcloud(names(freq), freq, max.words=100)   

Add some color and plot words occurring at least 20 times.

set.seed(142)   
wordcloud(names(freq), freq, min.freq=20, scale=c(5, .1), colors=brewer.pal(6, "Dark2")) 

Plot the 100 most frequently occurring words.

set.seed(142)   
dark2 <- brewer.pal(6, "Dark2")   
wordcloud(names(freq), freq, max.words=100, rot.per=0.2, colors=dark2) 

Source

Conclusion

  • The data could be really nice if I can stemmed the Indonesian words, so the “YANG” and “DAN” is not the top two in the list.