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))
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"
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
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]’.
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]))
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.
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
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)