Laporan ini bertujuan untuk mengklasifikasikan apakah suatu pesan teks termasuk SPAM atau HAM berdasarkan kontennya. Tujuan dari laporan ini adalah untuk menganalisis dan memodelkan data pesan teks sehingga dapat memprediksi dengan akurat apakah pesan tersebut adalah SPAM atau HAM.
Dalam era digital saat ini, pesan teks atau SMS menjadi salah satu bentuk komunikasi yang umum digunakan. Namun, seringkali kita menerima pesan-pesan yang tidak diinginkan atau yang lebih dikenal sebagai SPAM. SPAM dapat mengganggu dan membuang waktu kita. Oleh karena itu, penting untuk memiliki alat yang dapat memfilter pesan-pesan SPAM tersebut secara otomatis. Dalam laporan ini, saya akan menggunakan analisis teks dan teknik pemodelan untuk mengklasifikasikan pesan teks apakah termasuk SPAM atau HAM, sehingga membantu kita mengelola pesan-pesan yang masuk dengan lebih efisien.
Tujuan dari pembuatan laporan ini adalah untuk mengklasifikasikan apakah suatu pesan teks termasuk SPAM atau HAM. Dalam laporan ini, saya akan menggunakan teknik pemrosesan teks dan pemodelan yang tepat untuk menganalisis pesan-pesan teks yang ada. Beberapa target dan prediktor yang mungkin kita gunakan untuk mencapai tujuan ini antara lain:
status
.kecuali status
.Dalam bagian ini, kita akan membaca data dan melakukan proses pembersihan (jika diperlukan).
Pertama, kita akan memuat dataset latih dan dataset uji yang akan digunakan dalam analisis. Dataset latih akan digunakan untuk melatih model dan dataset uji akan digunakan untuk menguji performa model yang telah dilatih.
# Memuat dataset latih
train_data <- read.csv("data/data-train.csv")
# Memuat dataset uji
test_data <- read.csv("data/data-test.csv")
Selanjutnya, kita akan melakukan eksplorasi terhadap struktur data dan variabel yang ada.
đź’ˇData trainmemiliki 2,004 rows dengan total Features/columns 3.
## 'data.frame': 2004 obs. of 3 variables:
## $ datetime: chr "2017-02-15T14:48:00Z" "2017-02-15T15:24:00Z" "2017-02-15T16:07:00Z" "2017-02-15T16:59:00Z" ...
## $ text : chr "Telegram code 53784" "Rezeki Nomplok Dompetku Pengiriman Uang! Kirim uang di Alfamart & dptkan hadiah jutaan rupiah setiap hari.Perio"| __truncated__ "WhatsApp code 123-994.\n\nYou can also tap on this link to verify your phone: v.whatsapp.com/123994" "Transaksi travel online pakai CIMB Clicks gratis perlindungan kecelakaan & tiket nonton di Pasarpolis.com. Ayo "| __truncated__ ...
## $ status : chr "ham" "spam" "ham" "ham" ...
đź’ˇ Tipe datanya sudah sesuai dengan kasus kali ini, namun perlu dilakukkan penyesuaian lebih lanjut.
Kemudian, kita akan memeriksa apakah terdapat missing values atau nilai yang hilang pada dataset. Jika ada, kita akan menangani missing values tersebut dengan melakukan imputasi atau penghapusan nilai yang hilang, sesuai dengan kebutuhan analisis kita.
# Memeriksa missing values pada dataset latih
colSums(is.na(train_data))
## datetime text status
## 0 0 0
đź’ˇ tidak ada missing values
dalam dataset.
# Mengubah kolom datetime menjadi tipe data waktu
train_data$datetime <- as.POSIXct(train_data$datetime)
# Membuat kolom jam
train_data$hour <- format(train_data$datetime, "%H")
# Menghitung frekuensi total per jam untuk setiap status
hourly_freq <- table(train_data$hour, train_data$status)
# Mengubah tipe data kolom hour menjadi numerik
hourly_freq <- as.data.frame(hourly_freq)
hourly_freq$Var1 <- as.numeric(as.character(hourly_freq$Var1))
# Menghitung jumlah frekuensi untuk kategori ham dan spam
ham_freq <- sum(hourly_freq$Freq[hourly_freq$Var2 == "ham"])
spam_freq <- sum(hourly_freq$Freq[hourly_freq$Var2 == "spam"])
# Menghitung persentase untuk kategori ham dan spam
ham_percentage <- ham_freq / (ham_freq + spam_freq) * 100
spam_percentage <- spam_freq / (ham_freq + spam_freq) * 100
# Membuat data frame untuk pie chart
pie_data <- data.frame(Category = c("ham", "spam"),
Frequency = c(ham_freq, spam_freq),
Percentage = c(ham_percentage, spam_percentage))
# Membuat plot pie chart
ggplot(pie_data, aes(x = "", y = Frequency, fill = Category)) +
geom_bar(stat = "identity", width = 1, alpha = 0.7) +
coord_polar("y", start = 0) +
labs(x = NULL, y = NULL, fill = "Status") +
ggtitle("Perbandingan Frekuensi Total antara Ham dan Spam") +
theme_minimal() +
theme(axis.line = element_blank(),
axis.text = element_blank(),
axis.title = element_blank(),
panel.grid = element_blank(),
plot.title = element_text(hjust = 0.5)) +
geom_text(aes(label = paste0(round(Percentage, 1), "%")), position = position_stack(vjust = 0.5))
đź’ˇ Terdapat 842 pesan yang tergolong dalam kategori spam,
dengan persentase sebesar 42 %
dari total frekuensi pesan.
Hal ini menarik karena menunjukkan bahwa pesan spam cukup signifikan
dalam dataset.
library(lubridate)
# Mengubah kolom datetime menjadi tipe data waktu
train_data$datetime <- as.POSIXct(train_data$datetime)
# Ekstrak tanggal dan jam dari kolom datetime
train_data$date <- as.Date(train_data$datetime)
train_data$hour <- hour(train_data$datetime)
# Memvisualisasikan distribusi tanggal dengan box plot
ggplot(train_data, aes(x = date, y = hour)) +
geom_boxplot(fill = "lightblue", color = "black", alpha = 0.7) +
labs(title = "Distribusi Jam Berdasarkan Tanggal", x = "Tanggal", y = "Jam") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
đź’ˇDapat dilihat bahwa mayoritas data berada dalam rentang periode Juli 2017 hingga Januari 2018, Median berada di akhir tahun 2017, menunjukkan bahwa jam tertentu pada periode tersebut paling sering muncul.
kali ini saya mau melihat karakteristik teks yang terkait dengan
pesan spam menggunakan visualisasi wordcloud
# Filter data untuk kategori "spam"
spam_text <- train_data$text[train_data$status == "spam"]
# Menggabungkan semua teks spam menjadi satu string
spam_text <- paste(spam_text, collapse = " ")
# Menghapus kata-kata yang tidak relevan atau umum dalam teks spam
custom_stopwords <- c("dan", "atau", "ini", "itu", "dari", "dengan", "ke", "di", "untuk")
# Membuat wordcloud untuk teks spam dengan batasan kata
wordcloud(spam_text, stopwords = custom_stopwords, max.words = 100)
Dari hasil wordcloud tersebut, terlihat bahwa pesan spam cenderung berisi promosi terkait “pulsa,” “kuota,” “info,” “sms,” “internet”. Kata-kata seperti “promo,” “diskon,” “gratis,” dan “hadiah” juga sering muncul dalam pesan spam, menunjukkan adanya penawaran khusus untuk menarik perhatian penerima pesan.
đź’ˇDalam kasus ini, saya akan melakukan preprocesing pada kolom
text menggunakan pustaka textclean
. Preprocess
data teks melibatkan langkah-langkah seperti tokenisasi, pembersihan
tanda baca & emoticon, mengubah ke huruf kecil, dan lainnya untuk
mempersiapkan data sebelum dilakukan analisis teks lebih lanjut.
# Mengecek keberadaan emoticon dalam kolom "text"
has_emoticon <- any(stringr::str_detect(train_data$text, ":\\)|:\\(|;\\)|;\\)|:D"))
# Mengecek keberadaan punctuation dalam kolom "text"
has_punctuation <- any(stringr::str_detect(train_data$text, "[[:punct:]]"))
# Output hasil pengecekan
has_emoticon
## [1] FALSE
has_punctuation
## [1] TRUE
đź’ˇSetelah melakukan pengecekan pada data, tidak ditemukan adanya
emotikon. Namun, ada tanda baca punctuation
yang perlu
ditangani.
# library(katadasaR)
library(textclean) #meembersihkan teks
library(tokenizers) #membagi teks menjadi token2
library(wordcloud) #membuat wodcloud
library(stringr) #memaipulasi teks / regex
library(tm)
head(train_data$text)
## [1] "Telegram code 53784"
## [2] "Rezeki Nomplok Dompetku Pengiriman Uang! Kirim uang di Alfamart & dptkan hadiah jutaan rupiah setiap hari.Periode s.d. 28Feb17.Info: http://bit.ly/dmpurna MFI1"
## [3] "WhatsApp code 123-994.\n\nYou can also tap on this link to verify your phone: v.whatsapp.com/123994"
## [4] "Transaksi travel online pakai CIMB Clicks gratis perlindungan kecelakaan & tiket nonton di Pasarpolis.com. Ayo transaksi & nikmati manfaatnya! Info S&K 14041."
## [5] "Apakah Anda mencoba mengakses akun Anda dari perangkat lain? Jika ya, mohon klik tautan ini https://api.gojek.co.id/customers/device?token=f192293e-3117-46e9-bac3-1d1473c23113 dalam 72 jam ke depan. Jika tidak, mohon abaikan pesan ini"
## [6] "Apakah Anda mencoba mengakses akun Anda dari perangkat lain? Jika ya, mohon klik tautan ini https://api.gojek.co.id/customers/device?token=f192293e-3117-46e9-bac3-1d1473c23113 dalam 72 jam ke depan. Jika tidak, mohon abaikan pesan ini"
# Mengubah teks menjadi huruf kecil.
preprocessed_text <- tolower(train_data$text)
# Mengganti kontraksi kata menjadi bentuk lengkap.
preprocessed_text <- replace_contraction(preprocessed_text)
# Menghilangkan karakter selain alphanumeric dan spasi.
preprocessed_text <- gsub("[^[:alnum:][:space:]]", "", preprocessed_text)
# Menghilangkan tanda baca.
preprocessed_text <- gsub("[[:punct:]]", "", preprocessed_text)
# Menghilangkan angka.
preprocessed_text <- gsub("\\d+", "", preprocessed_text)
# Membersihkan teks dari karakter yang tidak diinginkan.
preprocessed_text <- strip(preprocessed_text)
head(preprocessed_text)
## [1] "telegram code"
## [2] "rezeki nomplok dompetku pengiriman uang kirim uang di alfamart dptkan hadiah jutaan rupiah setiap hariperiode sd febinfo httpbitlydmpurna mfi"
## [3] "whatsapp code you can also tap on this link to verify your phone vwhatsappcom"
## [4] "transaksi travel online pakai cimb clicks gratis perlindungan kecelakaan tiket nonton di pasarpoliscom ayo transaksi nikmati manfaatnya info sk"
## [5] "apakah anda mencoba mengakses akun anda dari perangkat lain jika ya mohon klik tautan ini httpsapigojekcoidcustomersdevicetokenfeebacdc dalam jam ke depan jika tidak mohon abaikan pesan ini"
## [6] "apakah anda mencoba mengakses akun anda dari perangkat lain jika ya mohon klik tautan ini httpsapigojekcoidcustomersdevicetokenfeebacdc dalam jam ke depan jika tidak mohon abaikan pesan ini"
Setelah itu, saya membuat document-term matrix (DTM) untuk mewakili data teks dengan menggunakan Corpus dan DocumentTermMatrix. DTM membantu mengubah teks menjadi bentuk matriks, Dengan adanya DTM, kita dapat melanjutkan dengan analisis teks lebih lanjut, seperti pemodelan teks menggunakan algoritma seperti Naive Bayes, Random Forest, atau SVM untuk mengklasifikasikan pesan teks menjadi SPAM atau HAM.
# Mengubah teks menjadi Corpus.
corpus <- Corpus(VectorSource(preprocessed_text))
# Membuat Document Term Matrix (DTM).
dtm <- DocumentTermMatrix(corpus)
# Menampilkan hasil DTM
dtm
## <<DocumentTermMatrix (documents: 2004, terms: 3148)>>
## Non-/sparse entries: 22277/6286315
## Sparsity : 100%
## Maximal term length: 79
## Weighting : term frequency (tf)
DTM (DocumentTermMatrix)
menunjukkan bahwa dalam dataset
berisi 2004 pesan teks, terdapat 3148 kata yang berbeda yang muncul.
Kepadatan DTM ini adalah 100%, artinya setiap sel dalam matriks memiliki
nilai (tidak ada entri kosong). DTM ini memberikan gambaran detail
tentang distribusi kata dalam dataset teks, yang bisa digunakan untuk
analisis teks lebih lanjut.
Kali ini saya akan coba membandingkan beberapa pendekatan metode untuk tugas klasifikasi teks (misalnya: Naive Bayes, Random Forest, SVM)
Dataset dibagi menjadi 70% untuk train dan 30% untuk test dengan
fungsi createDataPartition
.
# Memuat library yang diperlukan
library(caret)
library(randomForest)
library(e1071)
library(kernlab) # Untuk SVM
library(tm) # Untuk Text Mining (membuat Corpus dan DTM)
# Convert response variable to a factor
train_data$status <- factor(train_data$status)
# Split data menjadi data training dan data testing(validasi)
set.seed(123)
train_index <- createDataPartition(train_data$status, p = 0.7, list = FALSE)
train_set <- train_data[train_index, ]
test_set <- train_data[-train_index, ]
pada tahap ini saya melakukan beberapa pendekatan untuk membersihkan
data yang sudah di split, seperti :
konversi teks menjadi huruf kecil, penghilangan kontraksi, menghapus angka, tanda baca, dan kata-kata umum menggunakan *stopword*
.
kali ini saya tidak melakukan normalisasi
karena model yang
digunakan untuk klasifikasi teks (Naive Bayes, Random Forest, dan
Support Vector Machine) tidak memerlukan normalisasi pada data masukan
(DTM).
library(tm)
test_data <- read.csv("data/data-test.csv", stringsAsFactors = FALSE)
# Preprocessing pada teks dataset yang akan diprediksi
preprocess_text <- function(text) {
# Mengubah teks menjadi huruf kecil
text <- tolower(text)
# Mengganti kontraksi kata menjadi bentuk lengkap
text <- replace_contraction(text)
# Menghilangkan karakter selain alphanumeric dan spasi
text <- gsub("[^[:alnum:][:space:]]", "", text)
# Menghilangkan tanda baca
text <- gsub("[[:punct:]]", "", text)
# Menghilangkan angka
text <- gsub("\\d+", "", text)
# Membersihkan teks dari karakter yang tidak diinginkan
text <- strip(text)
return(text)
}
# Membuat Corpus dari data training dan data testing
corpus_train <- Corpus(VectorSource(train_set$text))
corpus_test <- Corpus(VectorSource(test_set$text)) #corpus_valid
test_corpus <- Corpus(VectorSource(test_data$text))
# Preprocessing Corpus
# Buat daftar kata bawaan untuk bahasa Indonesia // tidak tau library/fungsinya
stopwords_id <- c("dan", "atau", "adalah", "dari", "di", "ke", "sebuah", "itu", "ini", "yang")
corpus_train <- tm_map(corpus_train, content_transformer(tolower))
corpus_train <- tm_map(corpus_train, content_transformer(replace_contraction))
corpus_train <- tm_map(corpus_train, removeNumbers)
corpus_train <- tm_map(corpus_train, removePunctuation)
corpus_train <- tm_map(corpus_train, removeWords, stopwords_id) # bagaimmana indonesia?
corpus_train <- tm_map(corpus_train, stripWhitespace)
corpus_valid <- tm_map(corpus_test, content_transformer(tolower))
corpus_valid <- tm_map(corpus_test, content_transformer(replace_contraction))
corpus_valid <- tm_map(corpus_test, removeNumbers)
corpus_valid <- tm_map(corpus_test, removePunctuation)
corpus_valid <- tm_map(corpus_test, removeWords, stopwords_id)
corpus_valid <- tm_map(corpus_test, stripWhitespace)
test_corpus <- tm_map(test_corpus, content_transformer(tolower))
test_corpus <- tm_map(corpus_test, content_transformer(replace_contraction))
test_corpus <- tm_map(test_corpus, removePunctuation)
test_corpus <- tm_map(test_corpus, removeNumbers)
test_corpus <- tm_map(test_corpus, removeWords, stopwords_id)
test_corpus <- tm_map(test_corpus, stripWhitespace)
# Membuat Document Term Matrix (DTM).
dtm_train <- DocumentTermMatrix(corpus_train)
dtm_valid <- DocumentTermMatrix(corpus_valid, control = list(dictionary = Terms(dtm_train))) # data_valid
# Buat Document Term Matrix (DTM) untuk dataset uji
dtm_test <- DocumentTermMatrix(test_corpus, control = list(dictionary = Terms(dtm_train)))
dtm_test_mat <- as.matrix(dtm_test)
# Konversi DTM menjadi matriksmethod
dtm_train_mat <- as.matrix(dtm_train)
dtm_valid_mat <- as.matrix(dtm_valid)
saya menggunakan 3 model klasifikasi, yaitu
Naive Bayes, Random Forest, dan Support Vector Machine (SVM).
Evaluasi model dilakukan dengan menghitung akurasi pada data training
dan data testing menggunakan predict dan mean.
Pemilihan model untuk klasifikasi pesan spam atau ham didasarkan pada pertimbangan beberapa metode. Pertama, Naive Bayes dipilih karena sederhana dan efisien dalam mengatasi data teks. Kedua, Random Forest digunakan karena kekuatan sebagai model ensemble yang mengatasi overfitting dan cocok untuk data teks kompleks. Terakhir, SVM dipertimbangkan karena kemampuannya menemukan batas keputusan optimal dan dapat menangani data yang tidak linier.
# Memilih model untuk dibandingkan
models <- c("Naive Bayes", "Random Forest", "Support Vector Machine")
# Inisialisasi list untuk menyimpan hasil model
model_results <- list()
# Looping untuk membangun dan mengevaluasi model
for (model_name in models) {
# Membangun model menggunakan caret
model <- NULL
if (model_name == "Naive Bayes") {
model <- naiveBayes(as.matrix(dtm_train), train_set$status)
} else if (model_name == "Random Forest") {
model <- randomForest(as.matrix(dtm_train), train_set$status)
} else if (model_name == "Support Vector Machine") {
model <- svm(as.matrix(dtm_train), train_set$status)
}
# Evaluasi model pada data training
train_pred <- predict(model, dtm_train_mat)
train_acc <- mean(train_pred == train_set$status)
# Evaluasi model pada data validasi
valid_pred <- predict(model, dtm_valid_mat)
valid_acc <- mean(valid_pred == test_set$status)
# Simpan hasil evaluasi ke dalam list
model_results[[model_name]] <- list(train_accuracy = train_acc, valid_accuracy = valid_acc)
}
# Tampilkan hasil evaluasi model
result_df <- data.frame(Model = character(), Training_Accuracy = numeric(), Validation_Accuracy = numeric(), stringsAsFactors = FALSE)
for (model_name in models) {
cat("Model:", model_name, "\n")
cat("Training Accuracy:", model_results[[model_name]]$train_accuracy, "\n")
cat("Validation Accuracy:", model_results[[model_name]]$valid_accuracy, "\n\n")
# Simpan hasil evaluasi ke dalam dataframe
result_df <- rbind(result_df, data.frame(Model = model_name,
Training_Accuracy = model_results[[model_name]]$train_accuracy,
Validation_Accuracy = model_results[[model_name]]$valid_accuracy,
stringsAsFactors = FALSE))
}
## Model: Naive Bayes
## Training Accuracy: 0.3860399
## Validation Accuracy: 0.42
##
## Model: Random Forest
## Training Accuracy: 0.9900285
## Validation Accuracy: 0.955
##
## Model: Support Vector Machine
## Training Accuracy: 0.9900285
## Validation Accuracy: 0.5966667
# Tampilkan dataframe hasil evaluasi
print(result_df)
## Model Training_Accuracy Validation_Accuracy
## 1 Naive Bayes 0.3860399 0.4200000
## 2 Random Forest 0.9900285 0.9550000
## 3 Support Vector Machine 0.9900285 0.5966667
Hasil evaluasi menunjukkan bahwa Random Forest memiliki akurasi yang sangat tinggi pada data training (99.0%) namun sedikit menurun pada data validasi (95.0%), mengindikasikan kemungkinan adanya overfitting. Meskipun begitu, model ini masih memiliki performa yang lebih baik pada data testing dibandingkan dengan model SVM dan Naive Bayes. Dengan demikian, model Random Forest mungkin merupakan pilihan terbaik untuk mengklasifikasikan teks dalam kasus ini.
Berikut kata-kata yang memiliki pengaruh besar dalam hasil prediksi menggunakan model Random Forest. Informasi ini sangat berharga karena dapat membantu kita dalam memahami faktor-faktor apa saja yang berperan dalam mempengaruhi hasil prediksi dan dapat digunakan untuk mengoptimalkan atau meningkatkan performa model.
# Melatih model Random Forest pada data training
model_rf <- randomForest(as.matrix(dtm_train), train_set$status)
# Mendapatkan tingkat penting variabel dari model Random Forest
rf_var_imp <- importance(model_rf)
# Buat data frame untuk variable importance
rf_var_imp_df <- data.frame(word = row.names(rf_var_imp), importance = rf_var_imp[, 1])
# Mengurutkan dan memilih 15 kata-kata penting teratas
rf_var_imp_df <- rf_var_imp_df %>%
arrange(desc(importance)) %>%
head(15)
# Tampilkan kata-kata penting dari model Random Forest
print(rf_var_imp_df)
## word importance
## info info 23.299473
## ooredoo ooredoo 12.366892
## ayo ayo 11.604051
## berlaku berlaku 10.004051
## kuota kuota 9.967524
## hanya hanya 9.931377
## kamu kamu 9.898857
## iring iring 9.689708
## internetan internetan 8.944873
## bls bls 8.722977
## pulsa pulsa 8.494814
## gratis gratis 8.126968
## beli beli 8.027739
## bronet bronet 7.608694
## cek cek 7.408633
đź’ˇ Tingkat penting variabel menggambarkan seberapa besar kontribusi setiap kata terhadap prediksi. Semakin tinggi tingkat kepentingannya, semakin berpengaruh kata tersebut dalam proses pengambilan keputusan model.
# Mengukur performa model pada dataset validasi
valid_pred <- predict(model_rf, dtm_valid_mat)
valid_cm <- confusionMatrix(valid_pred, test_set$status) # Ganti test_set dengan valid_data
# Menghitung akurasi, sensitivitas, spesifisitas, dan presisi pada dataset validasi
valid_accuracy <- valid_cm$overall["Accuracy"]
valid_sensitivity <- valid_cm$byClass["Sensitivity"]
valid_specificity <- valid_cm$byClass["Specificity"]
valid_precision <- valid_cm$byClass["Precision"]
# Melaporkan performa model pada dataset validasi
cat("Performa model pada dataset validasi:\n")
## Performa model pada dataset validasi:
cat("Akurasi:", valid_accuracy, "\n")
## Akurasi: 0.9516667
cat("Sensitivitas:", valid_sensitivity, "\n")
## Sensitivitas: 0.9626437
cat("Spesifisitas:", valid_specificity, "\n")
## Spesifisitas: 0.9365079
cat("Presisi:", valid_precision, "\n\n")
## Presisi: 0.954416
test_data$datetime <- format(test_data$datetime, format = "%Y-%m-%d %H:%M:%S")
# Evaluasi model terbaik pada dataset uji
test_pred <- predict(model_rf, dtm_test_mat)
test_pred <- factor(test_pred, levels = levels(test_set$status))
# Ubah format datetime menjadi POSIXct
test_data$datetime <- as.POSIXct(test_data$datetime, format = "%Y-%m-%d %H:%M:%S")
# Jika level faktor test_pred dan test_data$status tidak sama, atur levelnya agar sama
levels(test_pred) <- levels(test_set$status)
test_cm <- confusionMatrix(test_pred, test_set$status)
# Menghitung akurasi, sensitivitas, spesifisitas, dan presisi pada dataset uji
test_accuracy <- test_cm$overall["Accuracy"]
test_sensitivity <- test_cm$byClass["Sensitivity"]
test_specificity <- test_cm$byClass["Specificity"]
test_precision <- test_cm$byClass["Precision"]
# Melaporkan performa model pada dataset uji
cat("Performa model pada dataset uji:\n")
## Performa model pada dataset uji:
cat("Akurasi:", test_accuracy, "\n")
## Akurasi: 0.9666667
cat("Sensitivitas:", test_sensitivity, "\n")
## Sensitivitas: 0.9683908
cat("Spesifisitas:", test_specificity, "\n")
## Spesifisitas: 0.9642857
cat("Presisi:", test_precision, "\n")
## Presisi: 0.9739884
Pada kode berikut, pengaturan jumlah kata yang muncul dalam wordcloud
dilakukan dengan menggunakan fungsi min.freq.
Argumen ini
menentukan frekuensi minimum kata yang harus muncul agar dimasukkan ke
dalam wordcloud. Kata-kata yang muncul dengan frekuensi lebih rendah
dari nilai min.freq akan diabaikan.
# Mengidentifikasi SMS yang diprediksi dengan tidak benar
misclassified_sms <- test_data[test_pred != test_set$status, "text"]
head(misclassified_sms)
## [1] "GRATIS UNLIMITED YOUTUBE+INTERNET 10GB+CHAT&SOSMED+SMS+NELPON selama 30hari.Data Rollover.PROMO 100Rb (Normal 115rb). MAU? Tekan C25 kirim SMS ke 929 sekarang"
## [2] "Proses PEMBLOKIRAN kartu bagi yg blm registrasi sdg berjalan,segera registrasi kartu Anda,dapatkan bonus 250MB+250mnt+250SMS.Ketik ULANG#NIK#No.KK# SMS ke4444"
## [3] "Paket kamu akan diperpanjang otomatis HARI INI ke PAKET BRONET 24JAM 100MB 1hr Rp3500. Pastikan pulsa kamu min5rb ya. Info838"
## [4] "AGAR TDK DIBLOKIR,sgr registrasi ulang kartu prabayar Anda.Tlp dan SMS keluar diblokir mulai 1-31 Maret 2018.Ketik ULANG#NIK#No.KK SMS ke 4444.Info 838"
## [5] "PAKET BRONET 4G OWSEM 4GB sudah aktif. 1GB kuota utama+3GB kuota 4G berlaku di jam 00-23.59 s.d 19-04-2018.Info838"
## [6] "DISKON main & makan cantik di weekend, tiket masuk Trans Studio Bandung, Kidzania, Sindu Kusuma Edupark, Kebab Baba Rafi, dll. Download AXISnet axisnet.id/app"
# Buat Wordcloud dari teks yang diprediksi tidak benar
wordcloud(misclassified_sms, scale = c(5, 0.5), min.freq = 2, random.order = FALSE, colors = brewer.pal(8, "Dark2"))
💡 Berdasarkan kata-kata dalam wordcloud dan teks yang salah terklasifikasi, terlihat adanya pola umum. Kata-kata seperti “paket,” “bronet,” “axis,” “info,” “utk” (untuk), dan “kamu” sering muncul dalam SMS yang salah terklasifikasi. Pola ini menunjukkan model kesulitan mengenali SMS tentang paket internet (paket data) dan informasi terkait. Kesimpulannya, ada pola umum di antara teks yang salah terklasifikasi terutama terkait dengan konten paket internet.
Namun, perlu dilakukan analisis lebih lanjut terhadap teks tersebut. Hal ini dapat melibatkan eksplorasi lebih dalam terhadap karakteristik teks, penggunaan kata-kata atau frasa tertentu, konteks penggunaan, atau fitur-fitur lain yang mungkin mempengaruhi prediksi model. Dengan analisis yang lebih mendalam, mungkin akan terlihat pola atau tren yang dapat memberikan wawasan tentang mengapa SMS tertentu sering salah terklasifikasi oleh model.
Insight singkat dari hasil evaluasi performa model:
đź’ˇ Hasil ini menunjukkan bahwa model klasifikasi memiliki kemampuan prediksi yang kuat dan siap digunakan untuk mengatasi masalah deteksi pesan spam pada skala yang lebih besar atau dalam aplikasi nyata.
Proyek capstone ini bertujuan untuk mengatasi masalah klasifikasi pesan spam menggunakan machine learning. Prosesnya dimulai dari pengumpulan data pesan teks, lalu data dibagi menjadi training dan test set. Selanjutnya, dilakukan pra-pemrosesan data dengan membersihkan teks dan mengonversinya ke dalam bentuk matriks.
Proyek capstone ini berhasil mencapai tujuan dalam mengatasi masalah klasifikasi pesan spam. Model Random Forest yang digunakan berhasil mencapai akurasi lebih dari 94%, serta sensitivitas dan spesifisitas yang tinggi.
Random Forest menunjukkan kinerja yang sangat baik dengan akurasi lebih dari 94%. Sensitivitas dan spesifisitas yang tinggi menunjukkan kemampuan model dalam mengklasifikasikan pesan positif dan negatif.
Model Random Forest berhasil mencapai tingkat
akurasi lebih dari 94% pada dataset validasi maupun test.
Selain itu, model ini juga memiliki tingkat sensitivitas dan
spesifisitas yang tinggi, menandakan kemampuannya dalam mengidentifikasi
pesan positif dan negatif dengan akurat. Dengan performa seperti ini,
model Random Forest siap digunakan untuk mengklasifikasikan pesan spam
dalam implementasi bisnis.
Model ini dapat diimplementasikan dalam lingkungan bisnis untuk meningkatkan efisiensi komunikasi dengan memfilter pesan-pesan spam. Potensi implementasi bisnisnya termasuk filter pesan dalam platform komunikasi perusahaan, perlindungan dari pesan spam bagi pengguna individu, dan meningkatkan efektivitas kampanye pemasaran serta komunikasi pelanggan