Membuat Word Cloud dari Hasil Crawling Twitter dengan R Tidak seperti data biasanya, data teks memiliki teknik khusus dalam penggalian informasinya (text mining). Salah satu metode text mining yang populer adalah memvisualisasikan data teks dengan word cloud (disebut juga text cloud atau tag cloud). Setiap kata yang terdapat pada teks disusun sedemikian rupa dengan ukuran yang bervariasi sesuai frekuensi kemunculannya dalam data. Semakin sering kata digunakan semakin besar ukuran kata tersebut dalam Word Cloud
Artikel ini bertujuan untuk membuat Word Cloud yang bersumber dari data cuitan (tweets) pengguna twitter yang mengandung kata kunci tertentu. Kata kunci tersebut dapat berupa nama produk, brand, tokoh terkenal, isu viral, dsb. Dalam hal ini, Word Cloud berfungsi untuk menyoroti isu apa saja yang sering dikaitkan dengan kata kunci yang dimasukan pada proses crawling. Word Cloud dapat menjadi fondasi utama dalam analisis sentimen untuk mengetahui arah opini masyarakat terhadap suatu kata kunci.
Cleaning merupakan proses pre-processing untuk memperoleh data yang benar-benar mengandung informasi penting sesuai dengan yang dikehendaki. Proses cleaning pada data teks tentunya memiliki teknik yang berbeda dengan data angka, R telah menyediakan package khusus untuk hal ini, yaitu textclean dan tm
library(wordcloud)
## Loading required package: RColorBrewer
library(tm)
## Loading required package: NLP
library(textclean)
library(tidytext)
library(ggplot2)
##
## Attaching package: 'ggplot2'
## The following object is masked from 'package:NLP':
##
## annotate
library(parallel)
library(tokenizers)
library(tau)
library(NLP)
library(stringr)
library(devtools)
## Loading required package: usethis
library(quanteda)
## Package version: 3.3.1
## Unicode version: 13.0
## ICU version: 69.1
## Parallel computing: 4 of 4 threads used.
## See https://quanteda.io for tutorials and examples.
##
## Attaching package: 'quanteda'
## The following object is masked from 'package:tm':
##
## stopwords
## The following objects are masked from 'package:NLP':
##
## meta, meta<-
library(kayadata)
library(syuzhet)
library(e1071)
library(sentimentr)
##
## Attaching package: 'sentimentr'
## The following object is masked from 'package:syuzhet':
##
## get_sentences
library(SentimentAnalysis)
##
## Attaching package: 'SentimentAnalysis'
## The following object is masked from 'package:base':
##
## write
library(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
library(pacman)
pacman::p_load(textstem, dplyr)
_Dataset yang digunakan adalah data yang diperoleh dari hasil crowling data di twitter. data ini berisi 100 tweets tentang kebakaran gunung bromo diduga akibat dari oknum petugas foto prawedding yang menyebabkan kebakaran yang luarbiasa__
Untuk mengimport file data dari excel ke R dapat menggunakan fungsi read excel dari library readxl, yang kemudian disimpan dalam variabel Kebakaran.Gunung.Bromo
setwd("C:/Users/kjl/Documents/Tugas Kuliah/Komputasi Lanjut Semester V")
Kebakaran.Gunung.Bromo <- read.csv("~/Tugas Kuliah/Komputasi Lanjut Semester V/Kebakaran-Gunung-Bromo.csv", sep=";")
tweets<-Kebakaran.Gunung.Bromo$full_text
head(Kebakaran.Gunung.Bromo)
## created_at id_str
## 1 Thu Sep 07 04:36:56 +0000 2023 1.699643e+18
## 2 Thu Sep 07 07:51:08 +0000 2023 1.699692e+18
## 3 Thu Sep 07 06:05:08 +0000 2023 1.699665e+18
## 4 Thu Sep 07 13:44:17 +0000 2023 1.699781e+18
## 5 Thu Sep 07 10:17:58 +0000 2023 1.699729e+18
## 6 Thu Sep 07 08:13:45 +0000 2023 1.699697e+18
## full_text
## 1 Ini pelajaran berharga buat gunung-gunung lainnya supaya pengelola memperketat dan memeriksa semua barang yang dibawa oleh para wisatawan, kalo para pendaki, biasanya di basecamp itu ranselnya dibongkar semua utk diperiksa dan didata, sampai potensi sampah yg dihasilkan punâ\200¦ https://t.co/sfwhpJMQux
## 2 Denda dongg, kalau modal nikahnya sampai habis kalau perlu sampai jual asetnya, kok goblok jadi orang
## 3 Prewedd ala-ala cinta alam yang malah ngerusak alamðŸ\230©ðŸ\230©
## 4 Kelakuan orang makin ada² aja
## 5 Maaf, misal manti pas nikah tenda nya beliau boleh di lempar flare ga 👉ðŸ\217»ðŸ‘\210ðŸ\217»
## 6 penjara donk semua yang ngerusak, biar kapok
## quote_count reply_count retweet_count favorite_count lang user_id_str
## 1 1 2 8 83 in 8.916931e+07
## 2 0 4 8 218 in 1.233937e+18
## 3 0 0 3 164 in 1.009643e+18
## 4 0 0 0 1 in 7.379091e+08
## 5 0 6 0 60 in 5.184182e+08
## 6 0 5 1 152 in 1.385664e+09
## conversation_id_str username
## 1 1.699617e+18 dAsalbantani
## 2 1.699617e+18 urlovelymeow
## 3 1.699617e+18 putrriretno
## 4 1.699617e+18 Amadeaxm
## 5 1.699617e+18 hyaluronicc__
## 6 1.699617e+18 pinkawiz_art
## tweet_url
## 1 https://twitter.com/dAsalbantani/status/1699642885933793314
## 2 https://twitter.com/urlovelymeow/status/1699691756185629160
## 3 https://twitter.com/putrriretno/status/1699665081926386102
## 4 https://twitter.com/Amadeaxm/status/1699780633101553690
## 5 https://twitter.com/hyaluronicc__/status/1699728710340129056
## 6 https://twitter.com/pinkawiz_art/status/1699697449420652748
Duplikat
#duplicate
tweets <- Kebakaran.Gunung.Bromo%>%
as.data.frame() %>%
distinct()
tweets
Jumlah baris tweet setelah duplikat dihapus
nrow(tweets)
## NULL
Hapus url
tweets <- tweets %>%
replace_html() %>%
replace_url()
tweets
tweets <- strip(tweets)
head(tweets)
stemming/lemmatizing = kata dasar
#stemming/lemmatizing = kata dasar
stem_strings(tweets)
cetak tweet dengan html yang dikonversi di index
replace_html(replace_emoji(tweets))
melakukan tugas penggantian seluruh variabel teks
tweets <- tweets %>%
replace_emoji(.) %>%
replace_html(.)
print menggantikan data teks pada indeks [4:5]
replace_tag(tweets)
Tahapan yang harus dilalui untuk membersihkan data tweets adalah sebagai berikut :
Menghilangkan substring ’’ dengan fungsi gsub() lalu mengganti nama data yang sudah bersih dari substring ’’ menjadi tweets Menghilangkan link-link html dan url, emoji, hashtag, dan mention pada tweets Berikut adalah syntax yang digunakan:
tweets <- tweets %>%
replace_tag(tweets, pattern = "@([A-Za-z0-9_]+)",replacement="") %>% # remove mentions
replace_hash(tweets, pattern = "#([A-Za-z0-9_]+)",replacement="") # remove hashtags
tweets
strip simbol
tweets <- strip(tweets)
tweets <-removeWords(tweets, c("di","dan","yang","akan","agar","seperti","yaitu","kami","kami",
"mari","pada","jelang","dimana","dengan","sudah","ini","seluruh",
"diminta","tak","itu","hai","bisa","wib","oleh","mai","jam", "aug",
"masa","berikut","kalau","klik","ibodwq","terd","httpstconvv","tue","wed",
"httpstcoxu","yzmrlyx","tahapan","refaabdi","kota","kpu","kpuid","rt",
"hingga","saat", "belum","apa","sih","suara","pesta","dindap","http",
"httpstco","gak","jadi","asn","bakal","wkwk","wkwkw","aug","iya","goblok",
"uu","i","ada","ngene","yang","bjir","ðÿðÿ","un","anjir","tahi","tbtb",
"my","wios","sialan","wkwkwkwk","sip","omo","like","plss","ket","e",
"after","ha","pakðÿ", "but","rill","cashback","allah","and","o","ðÿ'^ðÿ",
"nya","ya","ðÿ","no","nuruk","ki","jir","anjing","biar","kagak","sayang",
"mah","anjay","ngaruh","kalo","gua","thesis","skripsiðÿ","duh","ih",
"ots","a","pft","plis","plan","ra","rabi","o","skripshit","duit","sih",
"nih", "amp", "ï","tuh","tau","â","â","aaaa","deh","ðÿº","kan", "gara",
"coba","dll","iki","gue","kena","oon","pas","sad","up","wkwkwk","waleh",
"ajg","ah","adaâ","alaala","alah","alamðÿ","allahâ","ayo","end","bgt",
"udh","gak", "tolol","bu","biak","is", "kok", "flare", "trs", "org"))
head(rev)
##
## 1 function (x)
## 2 UseMethod("rev")
lower case = mengubah huruf kapital menjadi huruf kecil
tweets <- tolower(tweets)
tweets
Mengembalikan Kata yang disingkat Menjadi Kata Aslinya
tweets <- replace_contraction(tweets)
tweets
Mengembalikan Kata yang Mengalami Perpanjangan Menjadi Kata Aslinya
tweets <- replace_word_elongation(tweets)
tweets
Menyimpang data yang sudah dibersihkan
write.csv(rev,file = "C:/Users/kjl/Documents/data-bersih3.csv", row.names = F)
Word Cloud memperhatikan frekuensi setiap kata dalam pembuatannya, maka diperlukan sebuah matriks yang dapat menyajikan frekuensi setiap kata. Matriks tersebut dapat diperoleh dengan fungsi TermDocumentMatrix()
Selanjutnya, matriks tersebut diurutkan berdasarkan frekuensi kata dari yang terbesar. Untuk mempermudah pemahaman terhadap kata yang paling sering muncul, dapat dibuat sebuah dataframe dengan syntax seperti berikut :
Mengubah Data Frame Menjadi Data Faktor
tdm <- TermDocumentMatrix(tweets)
m <- as.matrix(tdm)
v <- sort(rowSums(m),decreasing = TRUE)
Mengubah Data Faktor Menjadi Data Frame
d <- data.frame(word = names(v), freq = v)
Membuat Word cloud
wordcloud(d$word, d$freq,
random.order = FALSE,
max.words = 500,
colors = brewer.pal(name="Dark2",8))
Dengan Word Cloud di atas terlihat bahwa kata Prewed, Orang, dan Bromo adalah kata yang paling sering dikaitkan dengan Kebakaran di Bromo pada cuitan pengguna twitter akhir-akhir ini. Berdasarkan Word Cloud ini dapat diambil sebuah informasi penting bahwa sedang di bromo sedang terjadi kebakaran tengah ramai dibicarakan oleh masyarakat Indonesia khususnya pengguna twitter.
Informasi-informasi ini dapat dijadikan fondasi dasar untuk analisis data teks atau analisis wacana lanjutan seperti analisis sentimen untuk melihat kecenderungan arah opini masyarakat.
tdm <-TermDocumentMatrix (tweets,
control = list(wordLengths= c (1, inf)))
tdm
Periksa kata-kata yang sering muncul
(freq.terms <- findFreqTerms(tdm, lowfreq = 14))
## [1] "prewed"
term.freq <- rowSums(as.matrix(tdm))
term.freq <- subset(term.freq, term.freq >= 14)
df <- data.frame(term = names(term.freq), freq = term.freq)
ggplot(df, aes(x = term, y = freq)) + geom_bar(stat = "identity") +
xlab("Terms") + ylab("Count") + coord_flip()
Menghapus istilah-istilah yang jarang?
tdm2 <- removeSparseTerms(tdm, sparse = 0.95)
m2 <- as.matrix(tdm2)
Analisis Cluster adalah salah satu teknik multivariat yang bertujuan mengklasifikasi suatu objek-objek ke dalam suatu kelompok-kelompok yang berbeda antara lain antara kelompok satu dengan lainnya. Objek-objek yang telah memiliki kedekatan jarak relatif sama dengan objek lainnya (Qonitatin & Novita, 2017). Karakteristik objek-objek dalam satuan kelompok memiliki tingkat kemiripan yang tinggi, sedangkan karakteristik antar objek pada suatu kelompok dengan kelompok lain memiliki tingkat kemiripan yang rendah (Mattjik & Sumertajaya, 2011).
distMatrix <- dist(scale (m2))
fit <- hclust (distMatrix, method = "ward")
## The "ward" method has been renamed to "ward.D"; note new "ward.D2"
plot(fit)
rect.hclust(fit, k = 3)
Dengan melihat selisih terpanjang dari gamabar diatas terlihat bahwa pemotongan yang tepat akan menghasilkan 3 cluster.
K-Means Clustering merupakan salah satu metode data clustering non hirarki yang berusaha mempartisi data yang ada ke dalam bentuk satu atau lebih cluster atau kelompok sehingga data yang memiliki karakteristik yang sama dikelompokkan ke dalam satu cluster yang sama dan data yang mempunyai karakteristik yang berbeda dikelompokkan ke dalam kelompok lainnya. K-Means adalah metode clustering berbasis jarak yang membagi data ke dalam sejumlah cluster dan algoritma ini hanya bekerja pada data dengan atribut numerik. Algoritma K-Means termasuk partitioning clustering yang memisahkan data ke k daerah bagian yang terpisah. Algoritma K-Means sangat terkenal karena kemudahan dan kemampuannya meng-cluster data yang besar dan data outlier dengan sangat cepat. K-Means merupakan metode non hirarki yang pada awalnya mengambil sebagian banyaknya komponen populasi untuk dijadikan pusat cluster awal. Berikutnya K-Means menguji masing-masing komponen di dalam populasi data dan menandai komponen tersebut ke salah satu pusat cluster yang telah didefinisikan tergantung dari jarak minimum antar komponen dengan tiap-tiap cluster. Posisi pusat cluster akan dihitung kembali sampai semua komponen data digolongkan ke dalam tiap-tiap pusat cluster dan terakhir akan terbentuk posisi pusat cluster yang baru.
m3 <- t(m2) # transpose the matrix to cluster documents (tweets)
m3
## Terms
## Docs denda orang aja mau bromo prewed
## 1 0 0 0 0 0 0
## 2 1 1 0 0 0 0
## 3 0 0 0 0 0 0
## 4 0 1 1 0 0 0
## 5 0 0 0 0 0 0
## 6 0 0 0 0 0 0
## 7 0 0 0 0 0 0
## 8 0 0 0 1 0 0
## 9 0 0 0 0 0 0
## 10 0 0 0 0 0 0
## 11 0 0 0 0 0 0
## 12 0 0 0 0 0 0
## 13 0 0 0 0 0 0
## 14 0 0 0 0 1 0
## 15 0 0 1 1 0 1
## 16 0 0 0 0 0 0
## 17 0 0 0 0 0 0
## 18 0 0 0 1 0 0
## 19 0 0 0 1 0 0
## 20 0 1 0 1 0 0
## 21 0 0 0 0 0 0
## 22 1 0 0 0 0 0
## 23 0 1 0 0 0 1
## 24 0 0 0 0 0 0
## 25 0 0 0 0 0 0
## 26 0 0 0 0 0 1
## 27 0 0 0 0 0 0
## 28 0 0 0 0 0 0
## 29 0 0 0 0 0 0
## 30 0 0 0 0 0 0
## 31 0 0 0 0 0 1
## 32 0 0 0 0 0 0
## 33 0 0 0 0 0 1
## 34 0 0 0 0 1 0
## 35 0 0 0 0 0 0
## 36 0 0 0 0 0 1
## 37 0 1 1 0 0 1
## 38 0 0 0 0 0 0
## 39 0 0 0 0 0 0
## 40 0 0 0 0 0 0
## 41 0 0 0 0 2 0
## 42 0 0 0 0 0 0
## 43 0 0 1 0 0 0
## 44 0 0 0 0 0 0
## 45 0 0 0 0 0 0
## 46 0 0 0 0 1 0
## 47 0 0 0 0 0 0
## 48 0 0 0 0 0 0
## 49 0 0 0 0 0 0
## 50 0 0 1 0 0 0
## 51 0 0 0 0 0 2
## 52 0 0 0 0 0 0
## 53 0 0 0 0 1 0
## 54 0 2 0 0 0 0
## 55 0 0 0 0 0 0
## 56 0 0 0 0 0 0
## 57 0 0 0 0 0 0
## 58 1 0 0 0 1 0
## 59 0 0 0 0 0 0
## 60 0 0 0 0 0 0
## 61 0 0 0 0 0 0
## 62 0 0 0 0 0 0
## 63 0 0 0 0 0 1
## 64 0 0 0 0 1 0
## 65 0 0 0 0 0 0
## 66 0 0 0 0 1 0
## 67 0 0 0 0 1 0
## 68 0 0 0 0 0 0
## 69 0 0 0 0 0 0
## 70 1 0 0 0 0 1
## 71 1 0 0 0 0 0
## 72 0 1 0 1 0 0
## 73 0 0 0 0 0 0
## 74 0 0 0 1 0 0
## 75 0 0 0 0 0 0
## 76 0 0 0 0 0 0
## 77 0 0 0 0 0 0
## 78 0 0 0 0 0 0
## 79 0 0 0 0 1 0
## 80 0 0 0 0 0 1
## 81 0 0 0 0 0 0
## 82 0 0 0 0 0 0
## 83 0 0 0 0 0 0
## 84 0 0 0 0 0 0
## 85 0 0 0 0 0 1
## 86 0 1 0 0 0 0
## 87 0 0 0 0 0 1
## 88 0 0 0 0 0 0
## 89 0 0 0 0 0 0
## 90 0 0 0 0 0 0
## 91 0 0 0 0 0 0
## 92 0 0 0 0 0 0
## 93 0 0 0 0 0 0
## 94 0 0 0 0 0 0
## 95 0 1 0 0 0 0
## 96 1 0 1 1 0 0
## 97 0 0 1 1 0 0
## 98 0 0 0 0 0 1
## 99 0 0 0 0 0 0
## 100 0 1 0 0 0 0
set.seed(122)
k<- 3
kmeansResult<-kmeans(m3, k)
round(kmeansResult$centers, digits=3)
## denda orang aja mau bromo prewed
## 1 0.10 1.1 0.200 0.200 0.0 0.200
## 2 0.10 0.0 0.000 0.000 1.1 0.000
## 3 0.05 0.0 0.062 0.088 0.0 0.162
for (i in 1:k) {
cat(paste("cluster ", i, ": ", sep = ""))
s <- sort(kmeansResult$centers[i, ], decreasing = T)
cat(names(s)[1:5], "\n")
# print the tweets of every cluster
# print(tweets[which(kmeansResult£cluster==i)])
}
## cluster 1: orang aja mau prewed denda
## cluster 2: bromo denda orang aja mau
## cluster 3: prewed mau aja denda orang