Pendahuluan

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.

Persiapan Data

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

Eksplorasi Awal Data

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.

Identifikasi Missing Value

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.

Data Cleaning

Menghapus Data Duplikat

pelanggan_clean <- unique(pelanggan_raw)

nrow(pelanggan_raw)
## [1] 12
nrow(pelanggan_clean)
## [1] 11

Menyeragamkan Nama Kota

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

Menyeragamkan Status Pelanggan

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

Penanganan Missing Value

Mengisi Missing Value Usia

median_usia <- median(pelanggan_clean$usia, na.rm = TRUE)

pelanggan_clean$usia[
  is.na(pelanggan_clean$usia)
] <- median_usia

Mengisi Missing Value Pendapatan

median_pendapatan <- median(
  pelanggan_clean$pendapatan,
  na.rm = TRUE
)

pelanggan_clean$pendapatan[
  is.na(pelanggan_clean$pendapatan)
] <- median_pendapatan

Mengisi Missing Value Kota

pelanggan_clean$kota[
  is.na(pelanggan_clean$kota)
] <- "PEKANBARU"

Verifikasi Missing Value

colSums(is.na(pelanggan_clean))
## customer_id        nama        usia  pendapatan        kota      status 
##           0           0           0           0           0           0

Penanganan Outlier

Mendeteksi Outlier Pendapatan

boxplot(pelanggan_clean$pendapatan,
        main = "Boxplot Pendapatan")

Nilai pendapatan sebesar 500 juta terlihat jauh berbeda dibandingkan data lainnya sehingga dapat dianggap sebagai outlier.

Membatasi Nilai 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

Transformasi Data

Robust Scaling

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.

Integrasi Data

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

Evaluasi Dataset Akhir

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.

Kesimpulan

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.