Asuransi mobil menjadi salah satu jenis asuransi yang populer dan penting dalam industri asuransi di Indonesia. Kebanyakan orang yang memiliki kendaraan bermotor mengambil asuransi mobil untuk melindungi diri dari risiko finansial akibat kerusakan atau kehilangan kendaraan mereka. Namun, industri asuransi mobil dihadapkan pada tantangan meningkatnya angka kecelakaan lalu lintas di Indonesia dalam beberapa tahun terakhir.
Data yang dihimpun tim JEO Kompas.com dari Direktorat Penegakan Hukum pada Korps Lalu Lintas Polri menunjukkan tren yang memprihatinkan dalam angka kecelakaan lalu lintas di Indonesia. Dari tahun 2017 hingga 2019, angka kecelakaan lalu lintas mengalami peningkatan, dengan jumlah korban meninggal dunia dan kerugian materil yang signifikan. Meskipun terjadi penurunan angka kecelakaan pada tahun 2020, namun jumlah korban meninggal dunia tetap tinggi, yang kemungkinan dipengaruhi oleh pembatasan mobilitas akibat wabah Covid-19.
Menariknya, pada tahun 2021, angka kecelakaan lalu lintas kembali meningkat, meskipun terjadi penurunan pada tahun sebelumnya. Angka kecelakaan yang terus meningkat ini menjadi perhatian serius bagi perusahaan asuransi untuk mengoptimalkan proses klaim asuransi mobil dan mengelola risiko dengan lebih baik.
Pada tahun 2017, 2018, 2020, dan 2021, perilaku pengemudi yang ceroboh saat menghadapi lalu lintas dari depan menjadi penyebab utama kecelakaan lalu lintas. Sedangkan pada tahun 2019, faktor kelelahan pengemudi menjadi penyebab utama kecelakaan. Informasi ini memberikan wawasan yang penting bagi perusahaan asuransi dalam mengidentifikasi potensi risiko klaim asuransi mobil yang berkaitan dengan perilaku pengemudi.
Selain itu, data visualisasi juga menunjukkan bahwa sepanjang tahun 2017 hingga 2021, faktor utama kecelakaan berdasarkan klasifikasi awal kendaraan adalah rusaknya sistem rem, diikuti oleh kurang baiknya kemudi, kerusakan roda, kerusakan lampu, dan buatan yang berlebihan. Hal ini menunjukkan bahwa kondisi teknis dan mekanis kendaraan memiliki peran yang signifikan dalam menyebabkan kecelakaan lalu lintas.
Dengan informasi ini, pengembangan model prediksi klaim asuransi mobil menggunakan metode Machine Learning menjadi semakin relevan dan penting. Model ini akan memanfaatkan data mengenai pemegang polis, karakteristik kendaraan, masa polis, usia kendaraan, dan faktor-faktor lainnya sebagai fitur-fitur untuk melakukan prediksi apakah pemegang polis akan mengajukan klaim asuransi mobil atau tidak.
Melalui implementasi model prediksi yang akurat, perusahaan asuransi akan dapat mengidentifikasi potensi risiko klaim yang berkaitan dengan perilaku pengemudi dan kondisi kendaraan. Dengan demikian, perusahaan asuransi dapat mengambil langkah pencegahan yang tepat untuk mengurangi risiko kecelakaan dan klaim asuransi yang tinggi.
Selain itu, informasi dari data visualisasi juga memberikan peluang bagi perusahaan asuransi untuk memberikan edukasi dan program pelatihan kepada pemegang polis mengenai keselamatan berkendara dan pentingnya pemeliharaan kendaraan secara berkala. Langkah ini dapat membantu mengurangi risiko kecelakaan dan meningkatkan kesadaran pemegang polis tentang pentingnya memiliki asuransi mobil yang tepat.
Dengan mengintegrasikan data visualisasi ini ke dalam model prediksi klaim asuransi mobil menggunakan metode Machine Learning seperti Logistic Regression dan Decision Tree serta GridSearchCV untuk mencari parameter terbaik, perusahaan asuransi dapat meningkatkan kemampuan dalam mengelola risiko, menentukan premi yang tepat, dan memberikan layanan yang lebih baik kepada pemegang polis. Model ini juga akan membantu menciptakan lingkungan berkendara yang lebih aman dan membantu mengurangi angka kecelakaan lalu lintas di Indonesia secara keseluruhan.
Peningkatan angka kecelakaan lalu lintas di Indonesia dalam beberapa tahun terakhir telah menjadi perhatian serius bagi industri asuransi mobil. Dalam rangka mengoptimalkan proses klaim asuransi dan meningkatkan manajemen risiko, perusahaan asuransi perlu memiliki kemampuan prediksi yang akurat terkait potensi klaim dari pemegang polis mereka. Namun, dengan volume data yang besar dan beragam dari pemegang polis yang berbeda, metode analisis manual dan berfikir kritis menjadi kurang efisien.
Proyek ini bertujuan untuk menjalankan analisis mendalam terhadap klaim asuransi mobil dengan memanfaatkan pendekatan Machine Learning, khususnya Logistic Regression dan Decision Tree, serta mengoptimalkan model-model tersebut dengan menggunakan GridSearchCV. Tujuan utama adalah untuk mengidentifikasi faktor-faktor yang memiliki dampak signifikan terhadap kemungkinan seorang pemegang polis mengajukan klaim asuransi mobil. Data yang digunakan akan mencakup beragam informasi, seperti karakteristik kendaraan, masa polis, usia kendaraan, dan sejarah klaim sebelumnya. Kami juga akan menggali faktor-faktor lain yang relevan yang memengaruhi keputusan pengajuan klaim. Dengan menerapkan teknik-teknik Machine Learning yang canggih, model yang dikembangkan akan memiliki kapasitas untuk melakukan prediksi dengan akurasi tinggi, memungkinkan perusahaan asuransi untuk memahami dan mengelola risiko lebih baik, serta memberikan layanan yang lebih baik kepada pemegang polis.
Hasil dari proyek ini diharapkan akan memberikan pemahaman yang lebih mendalam tentang faktor-faktor apa yang paling memengaruhi klaim asuransi mobil, sehingga perusahaan asuransi dapat mengambil langkah-langkah preventif yang lebih tepat dan mengoptimalkan penentuan premi secara lebih akurat. Selain itu, kami akan memperkenalkan elemen tambahan pada proyek ini dengan melakukan klastering pada pemegang polis. Ini akan memungkinkan kita untuk mengelompokkan pemegang polis ke dalam segmen-segmen yang berbeda berdasarkan perilaku dan karakteristik mereka. Dengan melakukan ini, perusahaan asuransi akan dapat memberikan layanan yang lebih spesifik dan disesuaikan dengan kebutuhan masing-masing kelompok pemegang polis, meningkatkan kepuasan pelanggan, dan pada gilirannya, menciptakan lingkungan berkendara yang lebih aman.
Proyek ini bertujuan untuk menganalisis dan melakukan prediksi klaim asuransi mobil dengan menggunakan metode Logistic Regression dan Decision Tree. Teknik GridSearchCV akan diterapkan untuk mengoptimalkan parameter-parameter model. Dataset yang digunakan berasal dari sumber Kaggle dengan judul “Car Insurance Claim Prediction - Classification”. Dataset ini mengandung informasi yang relevan mengenai pemegang polis asuransi mobil, seperti masa polis, usia mobil, usia pemilik mobil, merek dan model mobil, tenaga dan jenis mesin, serta variabel target yang menunjukkan apakah pemegang polis akan mengajukan klaim dalam 6 bulan mendatang.
Data dalam dataset mencakup atribut seperti policy_id (identifikasi polis), policy_tenure (masa polis), age_of_car (usia mobil), age_of_policyholder (usia pemilik mobil), area_cluster (kelompok wilayah), population_density (kepadatan penduduk kota), make (merek mobil), segment (segmen mobil), model (model mobil), fuel_type (jenis bahan bakar), max_torque (tenaga maksimum), max_power (daya maksimum), engine_type (jenis mesin), airbags (jumlah airbag), serta berbagai atribut lainnya yang terkait dengan spesifikasi teknis mobil. Car Insurance Claim Prediction | Kaggle
Hasil dari proyek ini akan mencakup pengembangan model prediksi yang canggih untuk analisis dan prediksi klaim asuransi mobil yang akurat. Model ini akan memiliki kemampuan untuk mengidentifikasi potensi risiko klaim dengan tingkat akurasi yang tinggi berdasarkan data pemegang polis dan karakteristik kendaraan. Selain itu, proyek ini akan melibatkan penggunaan teknik klastering dan klasifikasi untuk mengelompokkan pemegang polis ke dalam segmen-segmen yang relevan berdasarkan perilaku klaim mereka.
Melalui penerapan Logistic Regression, Decision Tree, GridSearchCV, serta teknik klastering dan klasifikasi, proyek ini akan memberikan pemahaman mendalam tentang faktor-faktor apa yang memengaruhi kecenderungan pengajuan klaim asuransi. Model yang dihasilkan akan memungkinkan perusahaan asuransi untuk mengelola risiko dengan lebih efektif dan memberikan wawasan strategis tentang segmen pemegang polis.
Penerapan analisis dan prediksi klaim asuransi mobil dengan metode Logistic Regression dan Decision Tree, bersama dengan GridSearchCV dan teknik klastering dan klasifikasi, akan memiliki dampak positif yang substansial pada industri asuransi mobil. Perusahaan asuransi akan mampu mengidentifikasi dengan lebih baik potensi risiko klaim yang tinggi, memungkinkan pengambilan tindakan pencegahan yang lebih tepat waktu.
Selain itu, model ini akan memungkinkan perusahaan asuransi untuk menentukan premi dengan lebih akurat berdasarkan karakteristik pemegang polis dan kendaraan, meningkatkan keadilan dalam penilaian premi. Penggunaan teknik klastering dan klasifikasi juga akan membantu perusahaan asuransi dalam memahami profil pemegang polis mereka dengan lebih baik, sehingga dapat memberikan layanan yang lebih personal.
Library yang digunakan adalah
library(dplyr)
library(ggplot2)
library(dplyr)
library(corrplot)
library(car)
# wrangling and EDA
library(tidyverse)
library(tidyquant)
library(lubridate)
# Visualization
library(ggthemes)
library(scales)
#clustering
library(factoextra)
library(FactoMineR)
library(dbscan) # DBSCAN
library(cluster) #K-Medoid
Kita akan membaca dan menampilkan data yang akan kita analisis.
train <- read.csv("data_input/train.csv")
head(train)
Deskripsi Data :
Berikut adalah penjelasan tiap variabel dalam bahasa Indonesia:
policy_id: Pengidentifikasi unik pemegang polis.policy_tenure: Masa kebijakan, yaitu jangka waktu
polis.age_of_car: Usia mobil yang dinormalisasi dalam
beberapa tahun.age_of_policyholder: Usia pemegang polis yang
dinormalisasi dalam beberapa tahun.area_cluster: Klaster wilayah pemegang polis.population_density: Kepadatan penduduk kota (tempat
tinggal pemegang polis).make: Produsen / perusahaan mobil yang disandikan.segment: Segmen mobil (A/B1/B2/C1/C2).model: Nama mobil yang dikodekan.fuel_type: Jenis bahan bakar yang digunakan oleh
mobil.max_torque: Torsi Maksimum yang dihasilkan mobil (Nm@rpm).max_power: Tenaga Maksimum yang dihasilkan mobil (bhp@rpm).engine_type: Jenis mesin yang digunakan pada
mobil.airbags: Jumlah airbag yang dipasang di mobil.is_esc: Bendera Boolean yang menunjukkan apakah
Electronic Stability Control (ESC) ada di dalam mobil atau tidak.is_adjustable_steering: Bendera Boolean yang
menunjukkan apakah setir mobil dapat disetel atau tidak.is_tpms: Bendera Boolean yang menunjukkan apakah Sistem
Pemantauan Tekanan Ban (TPMS) ada di dalam mobil atau tidak.is_parking_sensors: Bendera Boolean yang menunjukkan
apakah sensor parkir ada di dalam mobil atau tidak.is_parking_camera: Bendera Boolean yang menunjukkan
apakah kamera parkir ada di dalam mobil atau tidak.rear_brakes_type: Jenis rem yang digunakan di bagian
belakang mobil.displacement: Perpindahan mesin mobil (cc).cylinder: Jumlah silinder yang ada di mesin mobil.transmission_type: Jenis transmisi mobil.gear_box: Jumlah persneling di dalam mobil.steering_type: Jenis sistem kemudi mobil.turning_radius: Radius putar mobil.length: Panjang mobil.width: Lebar mobil.height: Tinggi mobil.gross_weight: Berat kotor mobil.is_front_fog_lights: Bendera Boolean yang menunjukkan
apakah lampu kabut depan ada di mobil atau tidak.is_rear_window_wiper: Bendera Boolean yang menunjukkan
apakah penghapus kaca belakang ada di mobil atau tidak.is_rear_window_washer: Bendera Boolean yang menunjukkan
apakah penyiram kaca belakang ada di mobil atau tidak.is_rear_window_defogger: Bendera Boolean yang
menunjukkan apakah penghangat kaca belakang ada di mobil atau
tidak.is_brake_assist: Bendera Boolean yang menunjukkan
apakah Brake Assist ada di mobil atau tidak.is_power_door_locks: Bendera Boolean yang menunjukkan
apakah kunci pintu otomatis ada di mobil atau tidak.is_central_locking: Bendera Boolean yang menunjukkan
apakah kunci sentral ada di mobil atau tidak.is_power_steering: Bendera Boolean yang menunjukkan
apakah sistem kemudi daya ada di mobil atau tidak.is_driver_seat_height_adjustable: Bendera Boolean yang
menunjukkan apakah ketinggian kursi pengemudi dapat diatur atau
tidak.is_day_night_rear_view_mirror: Bendera Boolean yang
menunjukkan apakah cermin pandang belakang dapat diatur sebagai
day-night atau tidak.is_ecw: Bendera Boolean yang menunjukkan apakah Power
Windows ada di mobil atau tidak.is_speed_alert: Bendera Boolean yang menunjukkan apakah
fitur peringatan kecepatan ada di mobil atau tidak.ncap_rating: Rating NCAP (New Car Assessment Program)
mobil.is_claim: Indikator apakah ada klaim (claim) asuransi
yang diajukan atau tidak.dim(train)
## [1] 58592 44
Sebelum melakukan pemodelan pada data Concrete kita, langkah pertama yang harus dilakukan adalah melakukan data preprocessing. Data preprocessing adalah proses untuk membersihkan dan menyiapkan data agar sesuai dengan persyaratan dan kebutuhan analisis atau pemodelan yang akan dilakukan. # Data Preprocessing
Hal pertama yang kita lakukan adalah mengecek tipe data. APakah sudah sesuai atau tidak.
glimpse(train)
## Rows: 58,592
## Columns: 44
## $ policy_id <chr> "ID00001", "ID00002", "ID00003", "ID0…
## $ policy_tenure <dbl> 0.51587359, 0.67261851, 0.84111026, 0…
## $ age_of_car <dbl> 0.05, 0.02, 0.02, 0.11, 0.11, 0.07, 0…
## $ age_of_policyholder <dbl> 0.6442308, 0.3750000, 0.3846154, 0.43…
## $ area_cluster <chr> "C1", "C2", "C3", "C4", "C5", "C6", "…
## $ population_density <int> 4990, 27003, 4076, 21622, 34738, 1305…
## $ make <int> 1, 1, 1, 1, 2, 3, 4, 1, 3, 1, 1, 1, 1…
## $ segment <chr> "A", "A", "A", "C1", "A", "C2", "B2",…
## $ model <chr> "M1", "M1", "M1", "M2", "M3", "M4", "…
## $ fuel_type <chr> "CNG", "CNG", "CNG", "Petrol", "Petro…
## $ max_torque <chr> "60Nm@3500rpm", "60Nm@3500rpm", "60Nm…
## $ max_power <chr> "40.36bhp@6000rpm", "40.36bhp@6000rpm…
## $ engine_type <chr> "F8D Petrol Engine", "F8D Petrol Engi…
## $ airbags <int> 2, 2, 2, 2, 2, 6, 2, 2, 6, 6, 2, 2, 2…
## $ is_esc <chr> "No", "No", "No", "Yes", "No", "Yes",…
## $ is_adjustable_steering <chr> "No", "No", "No", "Yes", "No", "Yes",…
## $ is_tpms <chr> "No", "No", "No", "No", "No", "Yes", …
## $ is_parking_sensors <chr> "Yes", "Yes", "Yes", "Yes", "No", "Ye…
## $ is_parking_camera <chr> "No", "No", "No", "Yes", "Yes", "Yes"…
## $ rear_brakes_type <chr> "Drum", "Drum", "Drum", "Drum", "Drum…
## $ displacement <int> 796, 796, 796, 1197, 999, 1493, 1497,…
## $ cylinder <int> 3, 3, 3, 4, 3, 4, 4, 4, 4, 4, 3, 3, 4…
## $ transmission_type <chr> "Manual", "Manual", "Manual", "Automa…
## $ gear_box <int> 5, 5, 5, 5, 5, 6, 5, 5, 6, 5, 5, 5, 5…
## $ steering_type <chr> "Power", "Power", "Power", "Electric"…
## $ turning_radius <dbl> 4.60, 4.60, 4.60, 4.80, 5.00, 5.20, 5…
## $ length <int> 3445, 3445, 3445, 3995, 3731, 4300, 3…
## $ width <int> 1515, 1515, 1515, 1735, 1579, 1790, 1…
## $ height <int> 1475, 1475, 1475, 1515, 1490, 1635, 1…
## $ gross_weight <int> 1185, 1185, 1185, 1335, 1155, 1720, 1…
## $ is_front_fog_lights <chr> "No", "No", "No", "Yes", "No", "Yes",…
## $ is_rear_window_wiper <chr> "No", "No", "No", "No", "No", "Yes", …
## $ is_rear_window_washer <chr> "No", "No", "No", "No", "No", "Yes", …
## $ is_rear_window_defogger <chr> "No", "No", "No", "Yes", "No", "Yes",…
## $ is_brake_assist <chr> "No", "No", "No", "Yes", "No", "Yes",…
## $ is_power_door_locks <chr> "No", "No", "No", "Yes", "Yes", "Yes"…
## $ is_central_locking <chr> "No", "No", "No", "Yes", "Yes", "Yes"…
## $ is_power_steering <chr> "Yes", "Yes", "Yes", "Yes", "Yes", "Y…
## $ is_driver_seat_height_adjustable <chr> "No", "No", "No", "Yes", "No", "Yes",…
## $ is_day_night_rear_view_mirror <chr> "No", "No", "No", "Yes", "Yes", "No",…
## $ is_ecw <chr> "No", "No", "No", "Yes", "Yes", "Yes"…
## $ is_speed_alert <chr> "Yes", "Yes", "Yes", "Yes", "Yes", "Y…
## $ ncap_rating <int> 0, 0, 0, 2, 2, 3, 5, 2, 3, 0, 0, 2, 2…
## $ is_claim <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1…
Dari hasil diatas dapat diketahui ada beberapa kolom yang belum sesuai tipe datanya sehingga kita akan mengubahnya.
unique(train$population_density)
## [1] 4990 27003 4076 21622 34738 13051 6112 8794 17804 73430 6108 34791
## [13] 5410 7788 290 16206 65567 35036 27742 20905 3264 16733
train <- train %>%
mutate(area_cluster = as.factor(area_cluster),
make = as.factor(make),
segment = as.factor(segment),
model = as.factor(model),
fuel_type = as.factor(fuel_type),
max_torque = as.factor(max_torque),
max_power = as.factor(max_power),
engine_type = as.factor(engine_type),
airbags = as.factor(airbags),
is_esc = as.factor(is_esc),
is_adjustable_steering = as.factor(is_adjustable_steering),
is_tpms = as.factor(is_tpms),
is_parking_sensors = as.factor(is_parking_sensors),
is_parking_camera = as.factor(is_parking_camera),
rear_brakes_type = as.factor(rear_brakes_type),
displacement = as.factor(displacement),
cylinder = as.factor(cylinder),
transmission_type = as.factor(transmission_type),
gear_box = as.factor(gear_box),
steering_type = as.factor(steering_type),
turning_radius = as.factor(turning_radius), # bisa dikelompokkan
is_front_fog_lights = as.factor(is_front_fog_lights),
is_rear_window_wiper = as.factor(is_rear_window_wiper),
is_rear_window_washer = as.factor(is_rear_window_washer),
is_rear_window_defogger = as.factor(is_rear_window_defogger),
is_brake_assist = as.factor(is_brake_assist),
is_power_door_locks = as.factor(is_power_door_locks),
is_central_locking = as.factor(is_central_locking),
is_power_steering = as.factor(is_power_steering),
is_driver_seat_height_adjustable = as.factor(is_driver_seat_height_adjustable),
is_day_night_rear_view_mirror = as.factor(is_day_night_rear_view_mirror),
is_ecw = as.factor(is_ecw),
is_speed_alert = as.factor(is_speed_alert),
ncap_rating = as.factor(ncap_rating),
is_claim = as.factor(is_claim)
)
Lalu kita melakukan Feature Selection, pemahaman yang kuat tentang
domain masalah dan tujuan analisis bisnis menjadi kunci untuk
mengidentifikasi variabel yang relevan dan penting dalam memprediksi
atau menjelaskan fenomena tertentu.Variabel yang tidak digunakan adalah
policy_id, karena merupakan identifier.
# menghapus policy_id
data <- train %>%
select(-policy_id,)
Kita harus ingat bahwa penting untuk memeriksa adanya outlier dalam data. Outlier adalah nilai yang secara signifikan berbeda dari sebagian besar data dan dapat mempengaruhi hasil analisis. Jika ditemukan outlier, langkah-langkah khusus perlu diambil untuk mengatasi masalah ini. Beberapa solusi untuk menangani outlier antara lain menghapus data outlier dari dataset, menggantikan outlier dengan nilai lain seperti median atau mean, atau menggunakan teknik analisis statistik yang lebih tahan terhadap outlier untuk mengurangi dampaknya.
# # Definisikan variabel numerik
# numeric_vars <- c("policy_tenure","age_of_car", "age_of_policyholder" ,"population_density", "width", "height", "gross_weight")
# # Fungsi untuk menampilkan boxplot dan menandai outlier pada variabel numerik
# plot_outliers <- function(data, var) {
# ggplot(data, aes(x = 1, y = !!sym(var))) +
# geom_boxplot(color = 'black', fill = 'skyblue', outlier.shape = NA) +
# geom_jitter(width = 0.1, alpha = 0.7, color = 'red') +
# labs(title = paste("Boxplot ", var), x = "", y = var) +
# theme_minimal() +
# theme(axis.text.x = element_blank())
# }
# # Menampilkan boxplot dan menandai outlier pada setiap variabel numerik
# for (var in numeric_vars) {
# print(plot_outliers(data, var))
# }
Kita dapat melihat bebrapa kolom memiliki outlier sehingga kita akan mengatasinya dengan cara menghapus baris yang outlier.
Kolom age_of_car memiliki nilai outlier yang lebih besar
dari 0.25, sehingga kita akan menghapus baris yang mengandung outlier
tersebut. Setelah dilakukan penghapusan, kami akan menampilkan boxplot
untuk menunjukkan bahwa outlier pada kolom tersebut telah dihilangkan
dan tidak ada lagi dalam data.
# Fungsi untuk menemukan dan menampilkan outlier pada kolom tertentu
find_outliers <- function(column_data) {
Q <- quantile(column_data, probs = c(0.25, 0.75), na.rm = FALSE)
iqr <- IQR(column_data)
up <- Q[2] + 1.5 * iqr # Upper Range
low <- Q[1] - 1.5 * iqr # Lower Range
outliers <- column_data[column_data < low | column_data > up]
return(outliers)
}
# Memanggil fungsi untuk menemukan outlier pada kolom data$age_of_car
outliers_age_of_car <- find_outliers(data$age_of_car)
# Menampilkan nilai outlier pada kolom data$age_of_car
print(outliers_age_of_car)
## [1] 0.39 0.29 0.38 0.29 0.26 0.27 0.28 0.30 0.25 0.30 0.30 0.27 0.29 0.31 0.33
## [16] 0.29 0.29 0.35 0.28 0.32 0.31 0.29 0.37 0.31 0.31 0.25 1.00 0.31 0.42 0.29
## [31] 0.32 0.30 0.29 0.25 0.30 0.32 0.25 0.27 0.26 0.31 0.32 0.27 0.33 0.32 0.25
## [46] 0.27 0.25 0.28 0.32 0.25 0.39 0.25 0.25 0.27 0.27 0.31 0.27 0.28 0.29 0.30
## [61] 0.30 0.26 0.25 0.25 0.28 0.36 0.31 0.25 0.37 0.38 0.28 0.31 0.27 0.31 0.26
## [76] 0.30 0.30 0.27 0.26 0.36 0.33 0.30 0.27 0.31 0.25 0.26 0.30 1.00 0.25 0.38
## [91] 0.25 0.30 0.29 0.31 0.30 0.29 0.31 0.25 0.32 0.31 0.39 0.28 0.26 0.29 0.26
## [106] 0.30 0.26 0.33 0.26 0.27 0.30 0.25 0.30 0.31 0.30 0.31 0.29 0.25 0.28 0.31
## [121] 0.30 0.27 0.32 0.25 0.30 0.32 0.33 0.25 0.29 0.26 0.27 0.25 0.29 1.00 0.27
## [136] 0.29 0.25 0.25 0.45 0.49 0.26 0.25 0.25 0.28 0.30 0.36 0.46 0.25 0.30 0.27
## [151] 0.33 0.26 0.29 0.34 0.28 0.30 0.34 0.25 0.30 0.28 0.32 0.29 0.31 0.28 0.27
## [166] 0.31 0.25 0.25 0.26 0.46 0.82 0.27 0.44 0.25 0.25 0.31 0.30 0.28 0.26 0.25
## [181] 0.25 0.31 0.28 0.30 0.62 0.25 0.27 0.28 0.25 0.25 0.34 0.28 0.38 0.81 0.27
## [196] 0.34 0.32 0.26 0.30 0.27 0.39 0.28 0.28 0.31 0.33 0.28 0.27 0.29 0.30 0.29
## [211] 0.28 0.25 0.30 0.33 0.26 0.27 0.25 0.36 0.27 0.26 0.26 0.32 0.33 0.34 0.26
## [226] 0.25 0.25 0.33 0.25 0.28 0.27 0.25 0.28 0.27 0.26 0.27 0.37 0.29 0.25 0.31
## [241] 0.30 0.31 0.36 0.34 0.26 0.31 0.27 0.26 0.39 0.36 0.31 0.25 0.49 0.44 0.30
## [256] 0.33 0.25 0.26 0.30 0.27 0.30 0.28 0.33 0.28 0.36 0.25 0.36 0.32 0.28
# Filtering out rows where age_of_car is less than 0.25 (assuming age_of_car is the correct column name)
data <- data %>% filter(!(age_of_car >= 0.25))
# Creating a boxplot for the age_of_car column
boxplot(data$age_of_car)
# Checking the dimensions of the filtered_data
dim(data)
## [1] 58323 43
Kolom age_of_policyholder memiliki nilai outlier yang
lebih besar dari 0.8269231, sehingga kita akan menghapus baris yang
mengandung outlier tersebut. Setelah dilakukan penghapusan, kami akan
menampilkan boxplot untuk menunjukkan bahwa outlier pada kolom tersebut
telah dihilangkan dan tidak ada lagi dalam data.
outliers_age_of_policyholder <- find_outliers(data$age_of_policyholder)
print(min(outliers_age_of_policyholder))
## [1] 0.8269231
data <- data %>% filter(!(age_of_policyholder >= 0.8269231))
boxplot(data$age_of_car)
dim(data)
## [1] 58158 43
Pada tahap Exploratory Data Analysis (EDA), tujuan utamanya adalah untuk mendapatkan wawasan dan pemahaman yang lebih mendalam tentang data yang akan digunakan dalam analisis atau pemodelan. Tujuan akhir dari EDA adalah untuk mempersiapkan data agar siap digunakan dalam analisis lebih lanjut dan pemodelan, serta untuk memastikan bahwa kita memiliki pemahaman yang kuat tentang data yang sedang dihadapi.
Sekarang kita akan melihat perbandingan pada kolom
is_claim
library(ggplot2)
ggplot(data, aes(x = is_claim)) +
geom_bar(fill = "darkblue") +
geom_text(stat = "count", aes(label = ..count..), vjust = -0.5) +
labs(x = "is_claim", y = "Count", title = "Countplot for is_claim")
Dari hasil bar di atas, dapat diketahui proporsi pengajuan klaim pada
data sebagai berikut:
Grafik Bar ini menggambarkan bahwa sebagian besar data memiliki klaim yang tidak diajukan (93.58%), sedangkan sejumlah kecil data (6.42%) mengajukan klaim.
modelBagaimana persebaran rating NCAP terkait dengan berbagai model mobil? Apakah terdapat kecenderungan bahwa beberapa model mobil lebih sering menggunakan transmisi otomatis daripada transmisi manual?
library(ggplot2)
library(dplyr)
# Data preparation
selected_columns <- c("model", "ncap_rating", "fuel_type", "age_of_car", "transmission_type", "is_brake_assist", "gross_weight", "airbags", "is_parking_camera")
selected_data <- data %>% select(all_of(selected_columns))
# Distribusi Rating NCAP berdasarkan Model
ggplot(selected_data, aes(x = model, fill = factor(ncap_rating))) +
geom_bar() +
labs(title = "Distribusi Rating NCAP berdasarkan Model",
x = "Model Mobil",
y = "Jumlah Mobil",
fill = "Rating NCAP")
# Jenis Transmisi pada Model Mobil
ggplot(selected_data, aes(x = model, fill = transmission_type)) +
geom_bar() +
labs(title = "Jenis Transmisi pada Model Mobil",
x = "Model Mobil",
y = "Jumlah Mobil",
fill = "Jenis Transmisi")
Dalam analisis ini, saya memeriksa bagaimana rating NCAP terdistribusi pada berbagai model mobil. Hasil menunjukkan bahwa model mobil M1, M10, dan M7 memiliki rating NCAP 1, model M2, M3, M6, dan M8 memiliki rating NCAP 2, model M4 memiliki rating NCAP 3, model M9 memiliki rating NCAP 4, dan model M11 dan M5 memiliki rating NCAP 5.
Selanjutnya, saya juga mengevaluasi preferensi jenis transmisi pada berbagai model mobil. Temuan menunjukkan bahwa model mobil M2, M3, M4, dan M7 cenderung menggunakan transmisi otomatis, sementara model M1, M10, M11, M5, M6, M8, dan M9 lebih cenderung menggunakan transmisi manual.
policy_tenureBerapa rata-rata masa kebijakan asuransi yang dimiliki pemegang polis? Bagaimana distribusi masa kebijakan asuransi dalam dataset ini?
# Visualisasi rata-rata masa kebijakan asuransi
ggplot(data, aes(x = policy_tenure)) +
geom_histogram(binwidth = 0.1, fill = "skyblue", color = "black") +
labs(title = "Distribusi Masa Kebijakan Asuransi",
x = "Masa Kebijakan Asuransi",
y = "Frekuensi") +
theme_minimal()
# Visualisasi distribusi masa kebijakan asuransi
ggplot(data, aes(x = policy_tenure)) +
geom_density(fill = "skyblue", color = "black") +
labs(title = "Distribusi Masa Kebijakan Asuransi",
x = "Masa Kebijakan Asuransi",
y = "Density") +
theme_minimal()
summary(data$policy_tenure)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.002735 0.208908 0.571731 0.609758 1.037957 1.396641
Rata-rata masa kebijakan asuransi yang dimiliki pemegang polis adalah sekitar 0.609758 tahun (sekitar 7,32 bulan).
Distribusi masa kebijakan asuransi dalam dataset ini memiliki nilai minimum sekitar 0.002735 tahun (kurang dari satu hari), nilai median sekitar 0.571731 tahun (sekitar 6,86 bulan), dan nilai maksimum sekitar 1.396641 tahun (sekitar 16,76 bulan).
Secara keseluruhan, distribusi ini mencakup rentang waktu yang relatif pendek, dengan rata-rata sekitar 7,32 bulan. Poin menariknya adalah nilai median yang lebih rendah dari rata-rata, yang bisa mengindikasikan adanya outlier di sisi lebih tinggi dari distribusi. Dengan kata lain, sejumlah kecil pemegang polis mungkin memiliki masa kebijakan yang jauh lebih lama daripada mayoritas pemegang polis lainnya.
age_of_carBagaimana usia mobil terdistribusi dalam dataset?
# Memasukkan pustaka yang diperlukan
library(ggplot2)
# Menampilkan distribusi usia mobil
ggplot(data, aes(x = age_of_car)) +
geom_histogram(binwidth = 0.02, fill = "skyblue", color = "black") +
labs(title = "Distribusi Usia Mobil",
x = "Usia Mobil",
y = "Frekuensi") +
theme_minimal()
summary(data$age_of_car)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.00000 0.02000 0.06000 0.06827 0.11000 0.24000
Dari visualisasi diatas dapat diketahui bahwa sebagian besar mobil dalam dataset memiliki usia yang relatif muda (dalam rentang 0 hingga 0.11 tahun), dengan usia rata-rata sekitar 0.06827 tahun (sekitar 24,9 hari). Nilai median yang lebih rendah dari mean menunjukkan bahwa distribusi mungkin memiliki ekor panjang di sisi yang lebih tinggi.
age_of_policyholderBagaimana distribusi usia pemegang polis dalam dataset?
# Visualisasi distribusi usia pemegang polis
ggplot(data, aes(x = age_of_policyholder)) +
geom_histogram(binwidth = 0.05, fill = "skyblue", color = "white") +
labs(title = "Distribusi Usia Pemegang Polis",
x = "Usia Pemegang Polis",
y = "Jumlah") +
theme_minimal()
summary(data$age_of_policyholder)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.2885 0.3654 0.4519 0.4681 0.5481 0.8269
Dari histogram dannilai-nilai ini, kita dapat menggambarkan distribusi usia pemegang polis sebagai berikut:
area_clusterBagaimana jumlah pemegang polis terdistribusi dalam setiap klaster wilayah? Apakah terdapat perbedaan jumlah klaim antara klaster wilayah yang berbeda?
# Load necessary libraries
library(ggplot2)
# Visualisasi distribusi jumlah pemegang polis dalam setiap klaster wilayah
ggplot(data, aes(x = area_cluster)) +
geom_bar(fill = "dodgerblue", alpha = 0.7) +
labs(title = "Distribusi Jumlah Pemegang Polis Berdasarkan Klaster Wilayah",
x = "Klaster Wilayah",
y = "Jumlah Pemegang Polis")
# Membandingkan jumlah klaim antara klaster wilayah yang berbeda
ggplot(data, aes(x = area_cluster, fill = factor(is_claim))) +
geom_bar(position = "dodge") +
labs(title = "Perbandingan Jumlah Klaim Berdasarkan Klaster Wilayah",
x = "Klaster Wilayah",
y = "Jumlah",
fill = "Klaim") +
scale_fill_manual(values = c("dodgerblue", "tomato"),
labels = c("Tidak Ada Klaim", "Ada Klaim"))
table(data$area_cluster)
##
## C1 C10 C11 C12 C13 C14 C15 C16 C17 C18 C19 C2 C20
## 1459 3133 1205 1571 3394 3632 768 401 491 242 949 7310 107
## C21 C22 C3 C4 C5 C6 C7 C8 C9
## 377 205 6079 660 6952 882 2158 13465 2718
table(data$area_cluster, data$is_claim)
##
## 0 1
## C1 1385 74
## C10 2987 146
## C11 1133 72
## C12 1484 87
## C13 3202 192
## C14 3353 279
## C15 730 38
## C16 378 23
## C17 472 19
## C18 216 26
## C19 878 71
## C2 6793 517
## C20 102 5
## C21 348 29
## C22 188 17
## C3 5648 431
## C4 609 51
## C5 6551 401
## C6 827 55
## C7 2051 107
## C8 12522 943
## C9 2583 135
Distribusi Jumlah Pemegang Polis Berdasarkan Klaster Wilayah:
Klaster C1 memiliki 1459 pemegang polis. Klaster C10 memiliki 3133 pemegang polis. Klaster C11 memiliki 1205 pemegang polis. dan seterusnya hingga Klaster C9 memiliki 2718 pemegang polis.
Ya,terdapat perbedaan jumlah klaim antara klaster wilayah. Dalam perbandingan jumlah klaim berdasarkan klaster wilayah, kategori C8 menonjol karena memiliki mayoritas pemegang polis yang tidak mengajukan klaim, yaitu sebanyak 12.522 pemegang polis. Meskipun demikian, perlu dicatat bahwa ada sejumlah pemegang polis dalam kategori ini yang tetap mengajukan klaim, sebanyak 943 pemegang polis.
segmentBagaimana jumlah mobil terdistribusi dalam setiap segmen mobil?
library(ggplot2)
# Visualisasi distribusi jumlah mobil dalam setiap segmen
ggplot(data, aes(x = segment, fill = segment)) +
geom_bar() +
geom_text(stat = "count", aes(label = after_stat(count)), vjust = -0.5, size = 3, color = "black") +
labs(title = "Distribusi Jumlah Mobil Berdasarkan Segmen",
x = "Segmen Mobil",
y = "Jumlah Mobil") +
theme_minimal()
Jumlah kendaraan yang terdistribusi pada masing-masing segmen mobil
adalah sebagai berikut:
Data ini menggambarkan sebaran jumlah kendaraan dalam berbagai segmen mobil berdasarkan informasi yang telah di berikan. Hasilnya menunjukkan bahwa segmen B2 memiliki jumlah kendaraan terbanyak dibandingkan segmen lainnya, diikuti oleh segmen A dan C2.
is_tpmsbagaimana perbandingan mobil dengan Sistem Pemantauan Tekanan Ban (TPMS)?
library(ggplot2)
# Menghitung jumlah klaim untuk mobil dengan dan tanpa TPMS
claim_counts <- data %>%
group_by(is_tpms, is_claim) %>%
summarize(count = n())
# Visualisasi perbandingan mobil dengan TPMS terhadap is_claim
ggplot(claim_counts, aes(x = is_tpms, y = count, fill = factor(is_claim))) +
geom_bar(stat = "identity", position = "stack") +
labs(x = "TPMS (Tire Pressure Monitoring System)",
y = "Number of Cars",
fill = "Claim",
title = "Comparison of TPMS and Claim") +
scale_x_discrete(labels = c("No TPMS", "TPMS")) +
scale_fill_manual(values = c("0" = "darkblue", "1" = "skyblue")) +
theme_minimal()
table(data$is_tpms, data$is_claim)
##
## 0 1
## No 41469 2826
## Yes 12971 892
Terlihat bahwa jumlah mobil tanpa TPMS yang mengajukan klaim (2,826) lebih tinggi daripada jumlah mobil dengan TPMS yang mengajukan klaim (892). Hal ini mungkin menunjukkan bahwa mobil tanpa TPMS cenderung memiliki risiko klaim yang lebih tinggi.
Mobil dengan TPMS memiliki jumlah klaim yang lebih rendah dibandingkan dengan mobil tanpa TPMS. Ini bisa mengindikasikan bahwa keberadaan TPMS dapat membantu dalam mencegah situasi yang dapat menyebabkan klaim, seperti kegagalan ban yang tidak terdeteksi.
fuel_typeBagaimana pola distribusi jenis bahan bakar yang digunakan oleh mobil dalam dataset ini? Apakah terdapat hubungan antara jenis bahan bakar yang digunakan dengan adanya klaim asuransi?
library(ggplot2)
# Visualisasi distribusi jenis bahan bakar
ggplot(data, aes(x = fuel_type)) +
geom_bar(fill = "skyblue") +
labs(title = "Distribusi Jenis Bahan Bakar",
x = "Jenis Bahan Bakar",
y = "Jumlah Mobil")
# Visualisasi perbandingan jenis bahan bakar terhadap klaim
ggplot(data, aes(x = fuel_type, fill = factor(is_claim))) +
geom_bar(position = "dodge") +
labs(title = "Perbandingan Jenis Bahan Bakar terhadap Klaim",
x = "Jenis Bahan Bakar",
y = "Jumlah Mobil",
fill = "Klaim") +
scale_fill_manual(values = c("No" = "skyblue", "Yes" = "salmon")) +
geom_text(stat = "count", aes(label = ..count..), position = position_dodge(width = 0.9), vjust = -0.5)
Dari hasil grafik batang yang menggambarkan “Distribusi Jenis Bahan Bakar”, terlihat bahwa jenis bahan bakar yang paling umum digunakan adalah petrol, diikuti oleh CNG (dalam jumlah yang hampir sama), dan diesel menjadi yang paling jarang digunakan.
Dalam konteks visualisasi “Perbandingan Jenis Bahan Bakar terhadap Klaim Asuransi”, diperoleh wawasan bahwa jumlah klaim asuransi pada mobil berbahan bakar petrol lebih tinggi daripada jenis bahan bakar lainnya, dengan jumlah klaim sebanyak 1346. Namun, jenis bahan bakar CNG memiliki jumlah tidak klaim yang lebih tinggi, yaitu sebanyak 19054, sedangkan jumlah klaimnya lebih rendah yaitu 1232.
Selanjutnya kita masuk ke tahap preprocessing, dilakukan pengecekan apakah data sudah memiliki distribusi normal atau mengalami condong (skewness). Jika ditemukan bahwa data cenderung condong, maka akan diterapkan transformasi data untuk mengubahnya menjadi distribusi yang lebih mendekati normal. Transformasi ini bertujuan untuk mengatasi masalah ketidaksimetrisan data sehingga dapat mendukung analisis statistik yang lebih akurat dan andal.
library(moments)
# Periksa distribusi dari masing-masing variabel numerik
numeric_vars <- c("policy_tenure","age_of_car", "age_of_policyholder" ,"population_density", "width", "height", "gross_weight")
# Menampilkan histogram dan skewness dari masing-masing variabel numerik
for (var in numeric_vars) {
print(paste("Skewness ", var, ":", round(skewness(data[[var]]), 2)))
}
## [1] "Skewness policy_tenure : 0.06"
## [1] "Skewness age_of_car : 0.59"
## [1] "Skewness age_of_policyholder : 0.59"
## [1] "Skewness population_density : 1.67"
## [1] "Skewness width : -0.48"
## [1] "Skewness height : 1.04"
## [1] "Skewness gross_weight : 0.55"
Hasil di atas menunjukkan nilai skewness dari masing-masing variabel numerik pada dataset. Skewness mengukur tingkat ketidaksimetrisan distribusi data. Jika nilai skewness mendekati 0, maka distribusi data cenderung simetris. Jika nilai skewness positif, maka distribusi data cenderung condong ke kanan (ekor panjang di sebelah kanan). Sebaliknya, jika nilai skewness negatif, distribusi data cenderung condong ke kiri (ekor panjang di sebelah kiri).
sqrt function:Dengan menggunakan fungsi sqrt pada proses transformasi,
nilai-nilai pada variabel akan diakar kuadratkan, sehingga mengubah
distribusi data menjadi lebih simetris dan dapat memperbaiki
ketidaknormalan dalam data. Hasil dari transformasi ini akan membuat
data lebih sesuai dengan asumsi yang diperlukan untuk beberapa analisis
statistik atau algoritma machine learning.
# Identifikasi kolom-kolom numerik
numeric_cols <- sapply(data, is.numeric)
# Melakukan transformasi akar kuadrat (sqrt) untuk kolom-kolom numerik di train_x
for (col in names(data)[numeric_cols]) {
data[[col]] <- sqrt(data[[col]])
}
summary(data)
## policy_tenure age_of_car age_of_policyholder area_cluster
## Min. :0.0523 Min. :0.0000 Min. :0.5371 C8 :13465
## 1st Qu.:0.4571 1st Qu.:0.1414 1st Qu.:0.6045 C2 : 7310
## Median :0.7561 Median :0.2449 Median :0.6723 C5 : 6952
## Mean :0.7181 Mean :0.2321 Mean :0.6786 C3 : 6079
## 3rd Qu.:1.0188 3rd Qu.:0.3317 3rd Qu.:0.7403 C14 : 3632
## Max. :1.1818 Max. :0.4899 Max. :0.9094 C13 : 3394
## (Other):17326
## population_density make segment model fuel_type
## Min. : 17.03 1:37896 A :17291 M1 :14933 CNG :20286
## 1st Qu.: 78.18 2: 2358 B1 : 4149 M4 :13863 Diesel:17546
## Median : 93.78 3:13863 B2 :18122 M6 :13629 Petrol:20326
## Mean :124.54 4: 1932 C1 : 3529 M8 : 4149
## 3rd Qu.:164.33 5: 2109 C2 :13863 M7 : 2919
## Max. :270.98 Utility: 1204 M3 : 2358
## (Other): 6307
## max_torque max_power engine_type
## 113Nm@4400rpm :17610 88.50bhp@6000rpm :17610 F8D Petrol Engine :14933
## 60Nm@3500rpm :14933 40.36bhp@6000rpm :14933 1.5 L U2 CRDi :13863
## 250Nm@2750rpm :13863 113.45bhp@4000rpm:13863 K Series Dual jet :13629
## 82.1Nm@3400rpm: 4149 55.92bhp@5300rpm : 4149 K10C : 4149
## 91Nm@4250rpm : 2358 67.06bhp@5500rpm : 2358 1.2 L K Series Engine: 2919
## 200Nm@1750rpm : 2109 97.89bhp@3600rpm : 2109 1.0 SCe : 2358
## (Other) : 3136 (Other) : 3136 (Other) : 6307
## airbags is_esc is_adjustable_steering is_tpms is_parking_sensors
## 1: 1204 No :39956 No :23002 No :44295 No : 2358
## 2:40172 Yes:18202 Yes:35156 Yes:13863 Yes:55800
## 6:16782
##
##
##
##
## is_parking_camera rear_brakes_type displacement cylinder transmission_type
## No :35489 Disc:13863 1197 :17610 3:21798 Automatic:20202
## Yes:22669 Drum:44295 796 :14933 4:36360 Manual :37956
## 1493 :13863
## 998 : 4149
## 999 : 2358
## 1498 : 2109
## (Other): 3136
## gear_box steering_type turning_radius length width
## 5:43937 Electric:23651 4.6 :14933 Min. :58.69 Min. :38.41
## 6:14221 Manual : 1204 4.8 :14691 1st Qu.:58.69 1st Qu.:38.92
## Power :33303 5.2 :13863 Median :62.01 Median :41.65
## 4.7 : 4149 Mean :61.99 Mean :40.86
## 5 : 3932 3rd Qu.:63.21 3rd Qu.:41.89
## 4.85 : 2919 Max. :65.57 Max. :42.56
## (Other): 3671
## height gross_weight is_front_fog_lights is_rear_window_wiper
## Min. :38.41 Min. :32.42 No :24576 No :41376
## 1st Qu.:38.41 1st Qu.:34.42 Yes:33582 Yes:16782
## Median :39.12 Median :36.54
## Mean :39.40 Mean :37.10
## 3rd Qu.:40.44 3rd Qu.:38.86
## Max. :42.72 Max. :41.47
##
## is_rear_window_washer is_rear_window_defogger is_brake_assist
## No :41376 No :37847 No :26327
## Yes:16782 Yes:20311 Yes:31831
##
##
##
##
##
## is_power_door_locks is_central_locking is_power_steering
## No :16137 No :16137 No : 1204
## Yes:42021 Yes:42021 Yes:56954
##
##
##
##
##
## is_driver_seat_height_adjustable is_day_night_rear_view_mirror is_ecw
## No :24218 No :36081 No :16137
## Yes:33940 Yes:22077 Yes:42021
##
##
##
##
##
## is_speed_alert ncap_rating is_claim
## No : 358 0:19056 0:54440
## Yes:57800 2:21198 1: 3718
## 3:13863
## 4: 2109
## 5: 1932
##
##
Dengan melakukan transformasi menggunakan sqrt, kita
berharap mendapatkan hasil analisis atau pemodelan yang lebih akurat dan
dapat dipercaya, serta memastikan bahwa data telah memenuhi asumsi yang
diperlukan sebelum digunakan dalam analisis lebih lanjut.
Setelah mengubah data, langkah berikutnya adalah melakukan
standarisasi. Tujuan dari standarisasi adalah
mengubah distribusi data agar memiliki rata-rata (mean) 0 dan deviasi
standar (standard deviation) 1. Alasan utama untuk melakukan
standarisasi setelah transformasi data adalah untuk mengatasi
ketidakseimbangan variabel. Setelah transformasi, beberapa variabel
mungkin memiliki rentang nilai yang sangat berbeda. Tanpa penyesuaian,
variabel dengan rentang nilai yang besar dapat memiliki pengaruh yang
dominan pada model atau analisis daripada variabel dengan rentang nilai
yang lebih kecil. Dengan melakukan standarisasi, semua variabel akan
memiliki rentang nilai yang serupa, sehingga kontribusi masing-masing
variabel dalam analisis menjadi seimbang.
# Identifikasi kolom-kolom numerik pada train_x
numeric_cols_data <- sapply(data, is.numeric)
# Melakukan standarisasi untuk kolom-kolom numerik di train_x
for (col in names(data)[numeric_cols_data]) {
data[[col]] <- (data[[col]] - mean(data[[col]])) / sd(data[[col]])
}
Setelah kita melakukan transformasi dan standarisasi, kita kembali melihat rangkuman data kita.
summary(data)
## policy_tenure age_of_car age_of_policyholder area_cluster
## Min. :-2.1712 Min. :-1.9334 Min. :-1.62741 C8 :13465
## 1st Qu.:-0.8513 1st Qu.:-0.7552 1st Qu.:-0.85266 C2 : 7310
## Median : 0.1239 Median : 0.1073 Median :-0.07333 C5 : 6952
## Mean : 0.0000 Mean : 0.0000 Mean : 0.00000 C3 : 6079
## 3rd Qu.: 0.9804 3rd Qu.: 0.8297 3rd Qu.: 0.70930 C14 : 3632
## Max. : 1.5119 Max. : 2.1479 Max. : 2.65274 C13 : 3394
## (Other):17326
## population_density make segment model fuel_type
## Min. :-1.8615 1:37896 A :17291 M1 :14933 CNG :20286
## 1st Qu.:-0.8027 2: 2358 B1 : 4149 M4 :13863 Diesel:17546
## Median :-0.5327 3:13863 B2 :18122 M6 :13629 Petrol:20326
## Mean : 0.0000 4: 1932 C1 : 3529 M8 : 4149
## 3rd Qu.: 0.6888 5: 2109 C2 :13863 M7 : 2919
## Max. : 2.5355 Utility: 1204 M3 : 2358
## (Other): 6307
## max_torque max_power engine_type
## 113Nm@4400rpm :17610 88.50bhp@6000rpm :17610 F8D Petrol Engine :14933
## 60Nm@3500rpm :14933 40.36bhp@6000rpm :14933 1.5 L U2 CRDi :13863
## 250Nm@2750rpm :13863 113.45bhp@4000rpm:13863 K Series Dual jet :13629
## 82.1Nm@3400rpm: 4149 55.92bhp@5300rpm : 4149 K10C : 4149
## 91Nm@4250rpm : 2358 67.06bhp@5500rpm : 2358 1.2 L K Series Engine: 2919
## 200Nm@1750rpm : 2109 97.89bhp@3600rpm : 2109 1.0 SCe : 2358
## (Other) : 3136 (Other) : 3136 (Other) : 6307
## airbags is_esc is_adjustable_steering is_tpms is_parking_sensors
## 1: 1204 No :39956 No :23002 No :44295 No : 2358
## 2:40172 Yes:18202 Yes:35156 Yes:13863 Yes:55800
## 6:16782
##
##
##
##
## is_parking_camera rear_brakes_type displacement cylinder transmission_type
## No :35489 Disc:13863 1197 :17610 3:21798 Automatic:20202
## Yes:22669 Drum:44295 796 :14933 4:36360 Manual :37956
## 1493 :13863
## 998 : 4149
## 999 : 2358
## 1498 : 2109
## (Other): 3136
## gear_box steering_type turning_radius length
## 5:43937 Electric:23651 4.6 :14933 Min. :-1.315296
## 6:14221 Manual : 1204 4.8 :14691 1st Qu.:-1.315296
## Power :33303 5.2 :13863 Median : 0.006244
## 4.7 : 4149 Mean : 0.000000
## 5 : 3932 3rd Qu.: 0.483965
## 4.85 : 2919 Max. : 1.428429
## (Other): 3671
## width height gross_weight is_front_fog_lights
## Min. :-1.7755 Min. :-0.9932 Min. :-1.6669 No :24576
## 1st Qu.:-1.4018 1st Qu.:-0.9932 1st Qu.:-0.9536 Yes:33582
## Median : 0.5702 Median :-0.2829 Median :-0.2015
## Mean : 0.0000 Mean : 0.0000 Mean : 0.0000
## 3rd Qu.: 0.7431 3rd Qu.: 1.0386 3rd Qu.: 0.6244
## Max. : 1.2221 Max. : 3.3262 Max. : 1.5545
##
## is_rear_window_wiper is_rear_window_washer is_rear_window_defogger
## No :41376 No :41376 No :37847
## Yes:16782 Yes:16782 Yes:20311
##
##
##
##
##
## is_brake_assist is_power_door_locks is_central_locking is_power_steering
## No :26327 No :16137 No :16137 No : 1204
## Yes:31831 Yes:42021 Yes:42021 Yes:56954
##
##
##
##
##
## is_driver_seat_height_adjustable is_day_night_rear_view_mirror is_ecw
## No :24218 No :36081 No :16137
## Yes:33940 Yes:22077 Yes:42021
##
##
##
##
##
## is_speed_alert ncap_rating is_claim
## No : 358 0:19056 0:54440
## Yes:57800 2:21198 1: 3718
## 3:13863
## 4: 2109
## 5: 1932
##
##
Clustering adalah proses pengelompokan data berdasarkan karakteristik atau atributnya yang mirip. Tujuan utama dari clustering adalah untuk membentuk kelompok atau cluster yang terdiri dari observasi atau data yang memiliki kesamaan atau kedekatan dalam karakteristik tertentu. Dalam proses clustering, observasi yang termasuk dalam satu cluster diharapkan memiliki kemiripan yang tinggi antara satu sama lain, sedangkan observasi yang termasuk dalam cluster yang berbeda seharusnya memiliki perbedaan karakteristik yang signifikan.
Sebelum melanjutkan dengan analisis clustering, langkah pertama
adalah melakukan filter pada dataset untuk hanya menyertakan observasi
yang memiliki nilai target (is_claim) sama dengan 1.
Setelah itu, kita akan memilih hanya fitur-fitur yang memiliki tipe data
numerik dari dataset ini. Ini dilakukan agar kita fokus pada data yang
terkait dengan klaim (claim) saja. Setelah proses filtering selesai,
kita akan melakukan pemeriksaan awal terhadap dataset yang telah
difilter, termasuk melihat tipe data dan ringkasan statistiknya.
data_num <- data %>%
filter(is_claim == 1 ) %>%
select_if(is.numeric)
glimpse(data_num)
## Rows: 3,718
## Columns: 8
## $ policy_tenure <dbl> -1.643600155, 0.498443430, 0.025677753, 0.91821753…
## $ age_of_car <dbl> -0.4904312, 0.5658859, -1.9333872, 0.4229500, -1.1…
## $ age_of_policyholder <dbl> 0.16952914, -0.58352834, 1.21683219, 0.93042823, 0…
## $ population_density <dbl> -1.0509405, 1.0707109, 0.3896176, 0.6888373, -0.53…
## $ length <dbl> 0.006244311, 0.006244311, -1.315296299, 1.42842939…
## $ width <dbl> 0.5702345, 0.5702345, -1.4018405, 1.0433744, -1.40…
## $ height <dbl> -0.2829101, -0.2829101, -0.9932410, 1.0385812, -0.…
## $ gross_weight <dbl> -0.2014773, -0.2014773, -0.9535817, 1.5544926, -0.…
summary(data_num)
## policy_tenure age_of_car age_of_policyholder population_density
## Min. :-2.1676 Min. :-1.93339 Min. :-1.62741 Min. :-1.86149
## 1st Qu.:-0.2853 1st Qu.:-0.75522 1st Qu.:-0.67211 1st Qu.:-0.80273
## Median : 0.6298 Median :-0.07054 Median : 0.00846 Median :-0.53268
## Mean : 0.3042 Mean :-0.12840 Mean : 0.07931 Mean :-0.05654
## 3rd Qu.: 1.0522 3rd Qu.: 0.70108 3rd Qu.: 0.70930 3rd Qu.: 0.68884
## Max. : 1.4273 Max. : 2.06198 Max. : 2.65274 Max. : 2.53547
## length width height gross_weight
## Min. :-1.315296 Min. :-1.77546 Min. :-0.99324 Min. :-1.66686
## 1st Qu.:-0.612453 1st Qu.:-1.40184 1st Qu.:-0.79822 1st Qu.:-0.95358
## Median : 0.006244 Median : 0.57023 Median :-0.28291 Median :-0.20148
## Mean : 0.026119 Mean : 0.03871 Mean :-0.00676 Mean : 0.01677
## 3rd Qu.: 0.483965 3rd Qu.: 0.74314 3rd Qu.: 1.03858 3rd Qu.: 0.62437
## Max. : 1.428429 Max. : 1.22211 Max. : 3.32619 Max. : 1.55449
Dalam menentukan k-optimum kita akan menggunakan elbow method. Elbow Plot merupakan plot antara banyak klaster dengan total dari simpangan/variasi per kluster (total WSS).
fviz_nbclust(
x = data_num, #data untuk clustering
FUNcluster = kmeans, #algoritma kmeans
method = "wss" #berdasarkan wss
)
Pada tahap pemilihan nilai k untuk analisis clustering, kita ingin
mencari nilai k yang tepat di mana penurunan total within sum of squares
tidak lagi menurun secara drastis dan cenderung melandai. Nilai k ini
dapat dianggap sebagai nilai k optimum yang paling cocok untuk data
kita
Setelah melakukan analisis, nilai k optimum yang dipilih adalah 3.
RNGkind(sample.kind = "Rounding")
set.seed(50)
# k-means dengan k optimum
data_cluster <- kmeans(data_num,centers = 3)
# Jumlah data tiap cluster
data_cluster$size
## [1] 989 1750 979
Didapat bahwa pada cluster 1 = 989 data, cluster 2 = 1750 data, cluster 3 = 979 data
data_cluster$centers
## policy_tenure age_of_car age_of_policyholder population_density length
## 1 -0.2962897 -1.1982929 0.006521476 0.1200334 -1.22836381
## 2 0.5306581 0.2446304 0.104703547 -0.1194804 0.04058008
## 3 0.5059348 0.2856326 0.107458212 -0.1224086 1.26756459
## width height gross_weight
## 1 -1.3282397 -0.9524972 -0.9560309
## 2 0.3653425 -0.1496174 -0.2528313
## 3 0.8357416 1.2040015 1.4814236
# hasil clustering (label cluster untuk tiap observasi)
as.data.frame(data_cluster$cluster)
data_cluster$iter
## [1] 3
Kebaikan hasil clustering dapat dilihat dari 3 nilai:
$withinss): jumlah jarak kuadrat
dari tiap observasi ke centroid tiap cluster.$betweenss): jumlah jarak
kuadrat terbobot dari tiap centroid ke rata-rata global. Dibobotkan
berdasarkan banyaknya observasi pada cluster.$totss): jumlah jarak kuadrat
dari tiap observasi ke rata-rata global.# cek nilai wss
data_cluster$withinss
## [1] 4106.206 7062.944 4130.073
data_cluster$tot.withinss
## [1] 15299.22
# cek nilai bss
data_cluster$betweenss
## [1] 13319.76
# cek nilai tss
data_cluster$totss
## [1] 28618.98
# cek rasio bss/tss
data_cluster$betweenss/data_cluster$totss
## [1] 0.4654169
Dari hasil diatas, nilai proporsi sebesar 0.46 (atau 46%) menunjukkan bahwa model K-means telah berhasil menjelaskan sekitar 48% variasi dalam data berdasarkan kluster yang dibentuk. Hal ini menandakan bahwa pengelompokan yang dilakukan oleh algoritma K-means cukup baik dalam menggambarkan pola-pola atau kelompok-kelompok yang ada dalam data kita.
Membuat kolom baru yang berisikan informasi label dari cluster yang terbentuk menggunakan k optimum
data_num$cluster <- as.factor(data_cluster$cluster)
head(data_num)
Grouping data based on cluster label
Melakukan grouping berdasarkan cluster yang terbentuk, untuk mengetahui karakteristik dari masing-masing cluster
as.data.frame(data_cluster$centers)
# melakukan profiling cluster dari data asli (supaya nantinya jika ketemu dengan perlu data yg perlu discaling sebelum kmeans nya , interpretasinya tidak salah)
data_centroid <- data_num %>%
group_by(cluster) %>%
summarise_all(mean)
data_centroid
Untuk mempermudah profiling: tabel yang menampilkan cluster dengan nilai terendah dan tertinggi untuk masing-masing karakteristik whisky
library(tidyr)
data_centroid %>%
pivot_longer(-cluster) %>%
group_by(name) %>%
summarize(
kelompok_min = which.min(value),
kelompok_max = which.max(value))
💡 Profiling tiap cluster :
Berikut adalah label untuk setiap cluster berdasarkan hasil analisis K-means pada data kita:
Cluster 1 (Kelompok 1): - Fitur yang cenderung lebih rendah:
age_of_car, age_of_policyholder,
gross_weight, height, length,
policy_tenure, width - Fitur yang cenderung
lebih tinggi: population_density - Label:
“Klaim Rendah, Polis Lama, Area Padat”
Cluster 2 (Kelompok 2): - Fitur yang cenderung lebih tinggi:
policy_tenure - Label: “Klaim Tinggi,
Polis Lama”
Cluster 3 (Kelompok 3): - Fitur yang cenderung lebih rendah:
age_of_car, age_of_policyholder,
gross_weight, height, length,
width - Fitur yang cenderung lebih tinggi:
population_density - Label: “Klaim Rendah,
Polis Lama, Area Rendah”
Untuk mempermudah profiling: radar plot
Plot radat (radar plot) adalah jenis grafik yang digunakan untuk memvisualisasikan variasi nilai dari beberapa variabel atau atribut pada data dalam bentuk poligon dengan sumbu radial. Setiap sumbu mewakili satu atribut, dan jarak dari pusat poligon ke titik di setiap sumbu mencerminkan nilai atribut tersebut.
data_centroid %>%
pivot_longer(-cluster) %>%
ggplot(aes(x = value, y = tidytext::reorder_within(name, value, cluster), fill = value)) +
geom_col() +
scale_fill_gradient(low = "pink", high = "navy") +
facet_wrap(~cluster, scales = "free_y") +
theme_minimal() +
labs(title = "Karakteristik tiap Cluster",
y = "",
x = "Skor")
# install.packages("ggiraphExtra")
library(ggiraphExtra)
ggRadar(data=data_num,
aes(colour=cluster),
interactive=TRUE)
Interpretasi hasil sebelumnya (hasil K-means) berdasarkan plot radat ini dapat memberikan wawasan tentang karakteristik audio dari masing-masing kluster. Pada plot radat ini, kita dapat melihat seberapa tinggi atau rendah nilai atribut pada masing-masing kluster.
Misalnya, jika pada plot radat, kluster 1 menunjukkan karakteristik yang tinggi pada atribut “population_density”, tetapi rendah pada atribut “length” dan “height”.
Cluster 1 (Kelompok 1) tampaknya mewakili pelanggan yang memiliki klaim rendah. Ini dapat diindikasikan oleh fakta bahwa hampir semua fitur yang diukur, seperti usia kendaraan (age_of_car), usia pemegang polis (age_of_policyholder), berat kotor (gross_weight), tinggi (height), panjang (length), lebar (width), dan lama polis (policy_tenure) cenderung lebih rendah. Namun, area di mana pelanggan ini tinggal memiliki kepadatan penduduk yang lebih tinggi (population_density). Label yang sesuai untuk kluster ini mungkin adalah “Klaim Rendah, Polis Lama, Area Padat.”
Cluster 2 (Kelompok 2) cenderung memiliki nilai tinggi pada atribut “policy_tenure”, yang mengindikasikan bahwa mereka adalah pelanggan dengan polis lama. Namun, atribut lain tidak memiliki perbedaan yang signifikan dengan kelompok lainnya. Label yang sesuai untuk kluster ini mungkin adalah “Klaim Tinggi, Polis Lama.”
Cluster 3 (Kelompok 3) memiliki karakteristik yang berbeda dari dua kluster sebelumnya. Mereka cenderung memiliki nilai yang lebih rendah pada fitur usia kendaraan (age_of_car), usia pemegang polis (age_of_policyholder), berat kotor (gross_weight), tinggi (height), panjang (length), dan lebar (width). Namun, mereka juga tinggal di area dengan kepadatan penduduk yang lebih rendah (population_density). Label yang sesuai untuk kluster ini mungkin adalah “Klaim Rendah, Polis Lama, Area Rendah.”
Setelah berhasil melakukan proses clustering untuk mengelompokkan data pelanggan, langkah selanjutnya adalah melakukan klasifikasi pada data yang sudah di-klaim. Ini berarti kita ingin mengetahui keanggotaan kluster dari pelanggan yang telah melakukan klaim. Dengan demikian, kita dapat mengelompokkan pelanggan yang sudah melakukan klaim ke dalam tiga kelas yang telah terbentuk sebelumnya. Hasil dari klustering ini kemudian dapat menjadi masukan atau fitur tambahan dalam model klasifikasi, yang dapat digunakan untuk analisis lebih lanjut atau pengambilan keputusan yang lebih tepat terkait dengan pelanggan yang telah melakukan klaim. Dengan cara ini, kita dapat mengoptimalkan penggunaan informasi klustering dalam proses klasifikasi untuk mendapatkan wawasan yang lebih dalam dan akurat terkait dengan perilaku dan kebutuhan pelanggan.
df_claim <- data %>%
filter(is_claim == 1) %>%
select(- is_claim)
cluster <- data_num$cluster
# Menggabungkan dua data frame, df dan data_num, berdasarkan nama kolom yang sesuai
combined_df <- cbind(df_claim, cluster)
glimpse(combined_df)
## Rows: 3,718
## Columns: 43
## $ policy_tenure <dbl> -1.643600155, 0.498443430, 0.02567775…
## $ age_of_car <dbl> -0.4904312, 0.5658859, -1.9333872, 0.…
## $ age_of_policyholder <dbl> 0.16952914, -0.58352834, 1.21683219, …
## $ area_cluster <fct> C3, C5, C4, C2, C8, C8, C6, C18, C18,…
## $ population_density <dbl> -1.0509405, 1.0707109, 0.3896176, 0.6…
## $ make <fct> 1, 1, 1, 3, 1, 1, 3, 1, 1, 1, 3, 1, 1…
## $ segment <fct> B2, B2, A, C2, A, B2, C2, B1, A, B2, …
## $ model <fct> M6, M6, M1, M4, M1, M6, M4, M8, M1, M…
## $ fuel_type <fct> Petrol, Petrol, CNG, Diesel, CNG, Pet…
## $ max_torque <fct> 113Nm@4400rpm, 113Nm@4400rpm, 60Nm@35…
## $ max_power <fct> 88.50bhp@6000rpm, 88.50bhp@6000rpm, 4…
## $ engine_type <fct> K Series Dual jet, K Series Dual jet,…
## $ airbags <fct> 2, 2, 2, 6, 2, 2, 6, 2, 2, 2, 6, 2, 6…
## $ is_esc <fct> No, No, No, Yes, No, No, Yes, No, No,…
## $ is_adjustable_steering <fct> Yes, Yes, No, Yes, No, Yes, Yes, No, …
## $ is_tpms <fct> No, No, No, Yes, No, No, Yes, No, No,…
## $ is_parking_sensors <fct> Yes, Yes, Yes, Yes, Yes, Yes, Yes, Ye…
## $ is_parking_camera <fct> No, No, No, Yes, No, No, Yes, No, No,…
## $ rear_brakes_type <fct> Drum, Drum, Drum, Disc, Drum, Drum, D…
## $ displacement <fct> 1197, 1197, 796, 1493, 796, 1197, 149…
## $ cylinder <fct> 4, 4, 3, 4, 3, 4, 4, 3, 3, 4, 4, 3, 4…
## $ transmission_type <fct> Manual, Manual, Manual, Automatic, Ma…
## $ gear_box <fct> 5, 5, 5, 6, 5, 5, 6, 5, 5, 5, 6, 5, 5…
## $ steering_type <fct> Electric, Electric, Power, Power, Pow…
## $ turning_radius <fct> 4.8, 4.8, 4.6, 5.2, 4.6, 4.8, 5.2, 4.…
## $ length <dbl> 0.006244311, 0.006244311, -1.31529629…
## $ width <dbl> 0.5702345, 0.5702345, -1.4018405, 1.0…
## $ height <dbl> -0.2829101, -0.2829101, -0.9932410, 1…
## $ gross_weight <dbl> -0.2014773, -0.2014773, -0.9535817, 1…
## $ is_front_fog_lights <fct> Yes, Yes, No, Yes, No, Yes, Yes, No, …
## $ is_rear_window_wiper <fct> No, No, No, Yes, No, No, Yes, No, No,…
## $ is_rear_window_washer <fct> No, No, No, Yes, No, No, Yes, No, No,…
## $ is_rear_window_defogger <fct> No, No, No, Yes, No, No, Yes, No, No,…
## $ is_brake_assist <fct> Yes, Yes, No, Yes, No, Yes, Yes, No, …
## $ is_power_door_locks <fct> Yes, Yes, No, Yes, No, Yes, Yes, Yes,…
## $ is_central_locking <fct> Yes, Yes, No, Yes, No, Yes, Yes, Yes,…
## $ is_power_steering <fct> Yes, Yes, Yes, Yes, Yes, Yes, Yes, Ye…
## $ is_driver_seat_height_adjustable <fct> Yes, Yes, No, Yes, No, Yes, Yes, No, …
## $ is_day_night_rear_view_mirror <fct> Yes, Yes, No, No, No, Yes, No, No, No…
## $ is_ecw <fct> Yes, Yes, No, Yes, No, Yes, Yes, Yes,…
## $ is_speed_alert <fct> Yes, Yes, Yes, Yes, Yes, Yes, Yes, Ye…
## $ ncap_rating <fct> 2, 2, 0, 3, 0, 2, 3, 2, 0, 2, 3, 2, 0…
## $ cluster <fct> 2, 2, 1, 3, 1, 2, 3, 1, 1, 2, 3, 2, 2…
RNGkind(sample.kind = "Rounding")
set.seed(417)
# index sampling
index <- sample(x = nrow(combined_df), size = nrow(combined_df) * 0.8)
# splitting
data_train <- combined_df[index, ]
data_test <- combined_df[-index, ]
Decision Tree merupakan tree-based model yang cukup sederhana dengan performa yang robust/powerful untuk prediksi. Decision Tree menghasilkan visualisasi berupa pohon keputusan yang dapat diinterpretasi dengan mudah.
library(partykit)
model_tree <- ctree(cluster ~ ., combined_df)
plot(model_tree)
plot(model_tree, type="simple")
Setelah kita latih data train maka kita bisa gunakan langsung pada data test. Evaluasi performa model complex
library(caret)
# prediksi kelas di data test
pred_pra_test <- predict(model_tree,data_test,type = "response")
# confusion matrix data test
conf_matrix_tree_pra <- confusionMatrix(pred_pra_test, data_test$cluster)
conf_matrix_tree_pra
## Confusion Matrix and Statistics
##
## Reference
## Prediction 1 2 3
## 1 176 3 0
## 2 1 366 0
## 3 0 0 198
##
## Overall Statistics
##
## Accuracy : 0.9946
## 95% CI : (0.9863, 0.9985)
## No Information Rate : 0.496
## P-Value [Acc > NIR] : < 2.2e-16
##
## Kappa : 0.9914
##
## Mcnemar's Test P-Value : NA
##
## Statistics by Class:
##
## Class: 1 Class: 2 Class: 3
## Sensitivity 0.9944 0.9919 1.0000
## Specificity 0.9947 0.9973 1.0000
## Pos Pred Value 0.9832 0.9973 1.0000
## Neg Pred Value 0.9982 0.9920 1.0000
## Prevalence 0.2379 0.4960 0.2661
## Detection Rate 0.2366 0.4919 0.2661
## Detection Prevalence 0.2406 0.4933 0.2661
## Balanced Accuracy 0.9945 0.9946 1.0000
# prediksi kelas di data train
pred_pra_train <- predict(model_tree, data_train, type="response")
# confusion matrix data train
conf_matrix_dt_pra_train <- confusionMatrix(pred_pra_train, data_train$cluster)
conf_matrix_dt_pra_train
## Confusion Matrix and Statistics
##
## Reference
## Prediction 1 2 3
## 1 804 17 0
## 2 8 1364 0
## 3 0 0 781
##
## Overall Statistics
##
## Accuracy : 0.9916
## 95% CI : (0.9876, 0.9946)
## No Information Rate : 0.4644
## P-Value [Acc > NIR] : < 2.2e-16
##
## Kappa : 0.9869
##
## Mcnemar's Test P-Value : NA
##
## Statistics by Class:
##
## Class: 1 Class: 2 Class: 3
## Sensitivity 0.9901 0.9877 1.0000
## Specificity 0.9921 0.9950 1.0000
## Pos Pred Value 0.9793 0.9942 1.0000
## Neg Pred Value 0.9963 0.9894 1.0000
## Prevalence 0.2730 0.4644 0.2626
## Detection Rate 0.2703 0.4586 0.2626
## Detection Prevalence 0.2761 0.4613 0.2626
## Balanced Accuracy 0.9911 0.9913 1.0000
Untuk nilai Accuracy pada model_tree : > Data train = 99.16% & Data test = 99.46%
Dan kita akan coba juga untuk melakukan tuning model dengan mengatur parameter mincriterion = 0.90 dan minsplit = 15.
tree2_model <- ctree(cluster ~ ., combined_df, control = ctree_control(mincriterion=0.9, minsplit=15, minbucket=0))
plot(tree2_model)
plot(tree2_model, type = "simple")
library(caret)
# prediksi kelas di data test
pred_pra_test <- predict(tree2_model,data_test,type = "response")
# confusion matrix data test
conf_matrix_tree_pra <- confusionMatrix(pred_pra_test, data_test$cluster)
conf_matrix_tree_pra
## Confusion Matrix and Statistics
##
## Reference
## Prediction 1 2 3
## 1 176 2 0
## 2 1 367 0
## 3 0 0 198
##
## Overall Statistics
##
## Accuracy : 0.996
## 95% CI : (0.9883, 0.9992)
## No Information Rate : 0.496
## P-Value [Acc > NIR] : < 2.2e-16
##
## Kappa : 0.9936
##
## Mcnemar's Test P-Value : NA
##
## Statistics by Class:
##
## Class: 1 Class: 2 Class: 3
## Sensitivity 0.9944 0.9946 1.0000
## Specificity 0.9965 0.9973 1.0000
## Pos Pred Value 0.9888 0.9973 1.0000
## Neg Pred Value 0.9982 0.9947 1.0000
## Prevalence 0.2379 0.4960 0.2661
## Detection Rate 0.2366 0.4933 0.2661
## Detection Prevalence 0.2392 0.4946 0.2661
## Balanced Accuracy 0.9954 0.9960 1.0000
# prediksi kelas di data train
pred_pra_train <- predict(tree2_model, data_train, type="response")
# confusion matrix data train
conf_matrix_dt_pra_train <- confusionMatrix(pred_pra_train, data_train$cluster)
conf_matrix_dt_pra_train
## Confusion Matrix and Statistics
##
## Reference
## Prediction 1 2 3
## 1 809 11 0
## 2 3 1370 0
## 3 0 0 781
##
## Overall Statistics
##
## Accuracy : 0.9953
## 95% CI : (0.9921, 0.9974)
## No Information Rate : 0.4644
## P-Value [Acc > NIR] : < 2.2e-16
##
## Kappa : 0.9927
##
## Mcnemar's Test P-Value : NA
##
## Statistics by Class:
##
## Class: 1 Class: 2 Class: 3
## Sensitivity 0.9963 0.9920 1.0000
## Specificity 0.9949 0.9981 1.0000
## Pos Pred Value 0.9866 0.9978 1.0000
## Neg Pred Value 0.9986 0.9931 1.0000
## Prevalence 0.2730 0.4644 0.2626
## Detection Rate 0.2720 0.4607 0.2626
## Detection Prevalence 0.2757 0.4617 0.2626
## Balanced Accuracy 0.9956 0.9951 1.0000
Untuk nilai Accuracy pada tree2_model : > Data train = 99.43% & Data test = 99.6%
Hasil akurasi menunjukkan bahwa kedua model, baik
model_tree maupun tree2_model, memiliki
akurasi yang sangat tinggi pada kedua dataset (train dan test). Ini
berarti kedua model tersebut mampu dengan sangat baik dalam
mengklasifikasikan data ke dalam tiga cluster yang ada (cluster 1, 2,
dan 3). Namun, jika kita membandingkan kinerja keduanya, model
tree2_model memiliki sedikit keunggulan dalam akurasi
dibandingkan dengan model_tree, terutama pada data tes.
Berdasarkan perbandingan ini, model tree2_model
tampaknya lebih baik dalam mengklasifikasikan data menjadi tiga cluster
(cluster 1, 2, dan 3) dibandingkan dengan model_tree.