Data preprocessing merupakan tahap penting dalam proses data mining. Data mentah sering kali mengandung berbagai permasalahan seperti nilai hilang (missing value), data duplikat, ketidakkonsistenan penulisan kategori, serta nilai ekstrem (outlier). Jika masalah tersebut tidak ditangani dengan baik, maka hasil analisis dapat menjadi kurang akurat.
Pada praktikum ini digunakan dua sumber data, yaitu data pelanggan dan data transaksi. Kedua dataset akan dibersihkan, ditransformasikan, dan diintegrasikan sehingga menghasilkan dataset yang siap digunakan untuk proses analisis lebih lanjut.
pelanggan_raw <- data.frame(
customer_id = c("C001","C002","C003","C004","C005","C006",
"C007","C008","C009","C010","C010","C011"),
nama = c("Ani","Budi","Citra","Dodi","Eka","Fani",
"Gilang","Hana","Indra","Joko","Joko","Kiki"),
usia = c(21,25,23,150,27,NA,31,29,22,35,35,28),
pendapatan = c(4500000,NA,5200000,4800000,4900000,5100000,
500000000,4700000,4600000,5300000,5300000,NA),
kota = c("Pekanbaru","PKU","PEKANBARU","Dumai","pekanbaru",
"DUMAI","Pekanbaru","Siak","PKU","Dumai","Dumai",NA),
status = c("Aktif","aktif","ACTIVE","A","Tidak Aktif",
"nonaktif","Aktif","AKTIF","A",
"Tidak aktif","Tidak aktif","Aktif"),
stringsAsFactors = FALSE
)
transaksi_raw <- data.frame(
cust_id = c("C001","C002","C003","C004","C005",
"C006","C007","C008","C009","C010","C012"),
jumlah_transaksi = c(5,3,7,2,6,4,20,5,3,8,1),
total_purchase = c(1500000,900000,2700000,600000,
2100000,1300000,25000000,
1700000,800000,3200000,250000)
)
pelanggan_raw
## customer_id nama usia pendapatan kota status
## 1 C001 Ani 21 4.5e+06 Pekanbaru Aktif
## 2 C002 Budi 25 NA PKU aktif
## 3 C003 Citra 23 5.2e+06 PEKANBARU ACTIVE
## 4 C004 Dodi 150 4.8e+06 Dumai A
## 5 C005 Eka 27 4.9e+06 pekanbaru Tidak Aktif
## 6 C006 Fani NA 5.1e+06 DUMAI nonaktif
## 7 C007 Gilang 31 5.0e+08 Pekanbaru Aktif
## 8 C008 Hana 29 4.7e+06 Siak AKTIF
## 9 C009 Indra 22 4.6e+06 PKU A
## 10 C010 Joko 35 5.3e+06 Dumai Tidak aktif
## 11 C010 Joko 35 5.3e+06 Dumai Tidak aktif
## 12 C011 Kiki 28 NA <NA> Aktif
transaksi_raw
## cust_id jumlah_transaksi total_purchase
## 1 C001 5 1.5e+06
## 2 C002 3 9.0e+05
## 3 C003 7 2.7e+06
## 4 C004 2 6.0e+05
## 5 C005 6 2.1e+06
## 6 C006 4 1.3e+06
## 7 C007 20 2.5e+07
## 8 C008 5 1.7e+06
## 9 C009 3 8.0e+05
## 10 C010 8 3.2e+06
## 11 C012 1 2.5e+05
summary(pelanggan_raw)
## customer_id nama usia pendapatan
## Length:12 Length:12 Min. : 21.00 Min. : 4500000
## Class :character Class :character 1st Qu.: 24.00 1st Qu.: 4725000
## Mode :character Mode :character Median : 28.00 Median : 5000000
## Mean : 38.73 Mean : 54440000
## 3rd Qu.: 33.00 3rd Qu.: 5275000
## Max. :150.00 Max. :500000000
## NA's :1 NA's :2
## kota status
## Length:12 Length:12
## Class :character Class :character
## Mode :character Mode :character
##
##
##
##
summary(transaksi_raw)
## cust_id jumlah_transaksi total_purchase
## Length:11 Min. : 1.000 Min. : 250000
## Class :character 1st Qu.: 3.000 1st Qu.: 850000
## Mode :character Median : 5.000 Median : 1500000
## Mean : 5.818 Mean : 3640909
## 3rd Qu.: 6.500 3rd Qu.: 2400000
## Max. :20.000 Max. :25000000
Berdasarkan hasil ringkasan data, terlihat adanya nilai hilang pada beberapa atribut serta nilai yang sangat besar pada kolom pendapatan.
colSums(is.na(pelanggan_raw))
## customer_id nama usia pendapatan kota status
## 0 0 1 2 1 0
Output di atas menunjukkan jumlah data yang hilang pada masing-masing kolom.
pelanggan_clean <- unique(pelanggan_raw)
nrow(pelanggan_raw)
## [1] 12
nrow(pelanggan_clean)
## [1] 11
pelanggan_clean$kota <- toupper(trimws(pelanggan_clean$kota))
pelanggan_clean$kota[pelanggan_clean$kota == "PKU"] <- "PEKANBARU"
table(pelanggan_clean$kota)
##
## DUMAI PEKANBARU SIAK
## 3 6 1
pelanggan_clean$status <- toupper(trimws(pelanggan_clean$status))
pelanggan_clean$status[pelanggan_clean$status %in%
c("AKTIF","ACTIVE","A")] <- "AKTIF"
pelanggan_clean$status[pelanggan_clean$status %in%
c("NONAKTIF","TIDAK AKTIF","TIDAK AKTIF")] <- "NONAKTIF"
table(pelanggan_clean$status)
##
## AKTIF NONAKTIF
## 8 3
median_usia <- median(pelanggan_clean$usia, na.rm = TRUE)
pelanggan_clean$usia[
is.na(pelanggan_clean$usia)
] <- median_usia
median_pendapatan <- median(
pelanggan_clean$pendapatan,
na.rm = TRUE
)
pelanggan_clean$pendapatan[
is.na(pelanggan_clean$pendapatan)
] <- median_pendapatan
pelanggan_clean$kota[
is.na(pelanggan_clean$kota)
] <- "PEKANBARU"
colSums(is.na(pelanggan_clean))
## customer_id nama usia pendapatan kota status
## 0 0 0 0 0 0
boxplot(pelanggan_clean$pendapatan,
main = "Boxplot Pendapatan")
Nilai pendapatan sebesar 500 juta terlihat jauh berbeda dibandingkan data lainnya sehingga dapat dianggap sebagai outlier.
Q1 <- quantile(pelanggan_clean$pendapatan, 0.25)
Q3 <- quantile(pelanggan_clean$pendapatan, 0.75)
IQR_value <- IQR(pelanggan_clean$pendapatan)
lower_bound <- Q1 - 1.5 * IQR_value
upper_bound <- Q3 + 1.5 * IQR_value
pelanggan_clean$pendapatan <- pmin(
pelanggan_clean$pendapatan,
upper_bound
)
summary(pelanggan_clean$pendapatan)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 4500000 4750000 4900000 4968182 5150000 5750000
median_income <- median(
pelanggan_clean$pendapatan
)
iqr_income <- IQR(
pelanggan_clean$pendapatan
)
pelanggan_clean$income_scaled <-
(pelanggan_clean$pendapatan -
median_income) / iqr_income
head(pelanggan_clean)
## customer_id nama usia pendapatan kota status income_scaled
## 1 C001 Ani 21.0 4500000 PEKANBARU AKTIF -1.00
## 2 C002 Budi 25.0 4900000 PEKANBARU AKTIF 0.00
## 3 C003 Citra 23.0 5200000 PEKANBARU AKTIF 0.75
## 4 C004 Dodi 150.0 4800000 DUMAI AKTIF -0.25
## 5 C005 Eka 27.0 4900000 PEKANBARU NONAKTIF 0.00
## 6 C006 Fani 27.5 5100000 DUMAI NONAKTIF 0.50
Transformasi ini digunakan agar pengaruh outlier terhadap data menjadi lebih kecil.
library(dplyr)
## Warning: package 'dplyr' was built under R version 4.5.1
##
## 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
data_final <- left_join(
pelanggan_clean,
transaksi_raw,
by = c("customer_id" = "cust_id")
)
data_final
## customer_id nama usia pendapatan kota status income_scaled
## 1 C001 Ani 21.0 4500000 PEKANBARU AKTIF -1.000
## 2 C002 Budi 25.0 4900000 PEKANBARU AKTIF 0.000
## 3 C003 Citra 23.0 5200000 PEKANBARU AKTIF 0.750
## 4 C004 Dodi 150.0 4800000 DUMAI AKTIF -0.250
## 5 C005 Eka 27.0 4900000 PEKANBARU NONAKTIF 0.000
## 6 C006 Fani 27.5 5100000 DUMAI NONAKTIF 0.500
## 7 C007 Gilang 31.0 5750000 PEKANBARU AKTIF 2.125
## 8 C008 Hana 29.0 4700000 SIAK AKTIF -0.500
## 9 C009 Indra 22.0 4600000 PEKANBARU AKTIF -0.750
## 10 C010 Joko 35.0 5300000 DUMAI NONAKTIF 1.000
## 11 C011 Kiki 28.0 4900000 PEKANBARU AKTIF 0.000
## jumlah_transaksi total_purchase
## 1 5 1.5e+06
## 2 3 9.0e+05
## 3 7 2.7e+06
## 4 2 6.0e+05
## 5 6 2.1e+06
## 6 4 1.3e+06
## 7 20 2.5e+07
## 8 5 1.7e+06
## 9 3 8.0e+05
## 10 8 3.2e+06
## 11 NA NA
str(data_final)
## 'data.frame': 11 obs. of 9 variables:
## $ customer_id : chr "C001" "C002" "C003" "C004" ...
## $ nama : chr "Ani" "Budi" "Citra" "Dodi" ...
## $ usia : num 21 25 23 150 27 27.5 31 29 22 35 ...
## $ pendapatan : num 4500000 4900000 5200000 4800000 4900000 5100000 5750000 4700000 4600000 5300000 ...
## $ kota : chr "PEKANBARU" "PEKANBARU" "PEKANBARU" "DUMAI" ...
## $ status : chr "AKTIF" "AKTIF" "AKTIF" "AKTIF" ...
## $ income_scaled : num -1 0 0.75 -0.25 0 ...
## $ jumlah_transaksi: num 5 3 7 2 6 4 20 5 3 8 ...
## $ total_purchase : num 1.5e+06 9.0e+05 2.7e+06 6.0e+05 2.1e+06 1.3e+06 2.5e+07 1.7e+06 8.0e+05 3.2e+06 ...
summary(data_final)
## customer_id nama usia pendapatan
## Length:11 Length:11 Min. : 21.00 Min. :4500000
## Class :character Class :character 1st Qu.: 24.00 1st Qu.:4750000
## Mode :character Mode :character Median : 27.50 Median :4900000
## Mean : 38.05 Mean :4968182
## 3rd Qu.: 30.00 3rd Qu.:5150000
## Max. :150.00 Max. :5750000
##
## kota status income_scaled jumlah_transaksi
## Length:11 Length:11 Min. :-1.0000 Min. : 2.00
## Class :character Class :character 1st Qu.:-0.3750 1st Qu.: 3.25
## Mode :character Mode :character Median : 0.0000 Median : 5.00
## Mean : 0.1705 Mean : 6.30
## 3rd Qu.: 0.6250 3rd Qu.: 6.75
## Max. : 2.1250 Max. :20.00
## NA's :1
## total_purchase
## Min. : 600000
## 1st Qu.: 1000000
## Median : 1600000
## Mean : 3980000
## 3rd Qu.: 2550000
## Max. :25000000
## NA's :1
Dataset hasil integrasi telah memiliki format yang lebih konsisten, tidak mengandung data duplikat, serta memiliki penanganan terhadap nilai hilang dan outlier.
Berdasarkan praktikum yang telah dilakukan, proses data preprocessing berhasil memperbaiki kualitas data melalui pembersihan data, penanganan missing value, penyeragaman kategori, deteksi outlier, transformasi data, dan integrasi dataset. Dataset yang dihasilkan menjadi lebih siap untuk digunakan dalam proses analisis maupun pemodelan data mining.