Dataset utama terdiri dari 11 observasi, yaitu C001 sampai C011. Beberapa observasi tambahan ditambahkan untuk memperlihatkan proses preprocessing secara lebih lengkap.
Data yang diperoleh dari suatu sumber pada umumnya belum dapat langsung digunakan untuk analisis. Data mentah dapat mengandung berbagai permasalahan seperti nilai yang hilang, kesalahan penulisan, format kategori yang tidak seragam, nilai yang tidak logis, serta nilai yang terlalu ekstrem.
Permasalahan tersebut dapat memengaruhi hasil analisis apabila tidak ditangani dengan baik. Oleh karena itu, diperlukan proses data preprocessing, yaitu serangkaian tahapan yang dilakukan untuk membersihkan, memperbaiki, mentransformasi, dan mempersiapkan data sebelum digunakan pada proses analisis selanjutnya.
Pada praktikum ini digunakan data pelanggan yang berisi informasi mengenai identitas pelanggan, usia, pendapatan, kota, dan status. Selain itu, digunakan data transaksi untuk menunjukkan proses penggabungan dua sumber data.
Tahapan yang dilakukan meliputi pemeriksaan data awal, data cleaning, pemeriksaan missing value, pemeriksaan nilai tidak logis, penanganan missing value, deteksi outlier, normalisasi, standardisasi, integrasi data, dan pemeriksaan dataset akhir.
Praktikum ini bertujuan untuk:
Dataset dibuat menggunakan fungsi data.frame(). Sebelas
observasi pertama, yaitu C001 sampai C011, tetap dipertahankan sebagai
data utama. Beberapa observasi tambahan digunakan untuk memperluas
contoh pengolahan.
pelanggan_raw <- data.frame(
customer_id = c(
"C001","C002","C003","C004","C005",
"C006","C007","C008","C009","C010","C011",
"C012","C013","C014","C015"
),
nama = c(
"Ani","Budi","Citra","Dodi","Eka",
"Fani","Gilang","Hana","Indra","Joko","Kiki",
"Lala","Mira","Nanda","Oki"
),
usia = c(
21,25,23,150,27,
NA,31,29,22,35,28,
24,26,30,33
),
pendapatan = c(
4500000,
NA,
5200000,
4800000,
4900000,
5100000,
500000000,
4700000,
4600000,
5300000,
NA,
4400000,
5600000,
6000000,
5000000
),
kota = c(
"Pekanbaru",
" PKU",
"PEKANBARU",
"Dumai",
"pekanbaru",
"DUMAI",
"Pekanbaru",
"Pekanbaru",
"PKU",
"Dumai",
NA,
"Pekanbaru",
"Dumai",
"Pekanbaru",
"PKU"
),
status = c(
"Aktif",
"aktif",
"ACTIVE",
"A",
"Tidak Aktif",
"nonaktif",
"Aktif",
"AKTIF",
"A",
"Tidak aktif",
"Aktif",
"Aktif",
"Tidak Aktif",
"Aktif",
"Aktif"
),
stringsAsFactors = FALSE
)
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 Pekanbaru AKTIF
## 9 C009 Indra 22 4.6e+06 PKU A
## 10 C010 Joko 35 5.3e+06 Dumai Tidak aktif
## 11 C011 Kiki 28 NA <NA> Aktif
## 12 C012 Lala 24 4.4e+06 Pekanbaru Aktif
## 13 C013 Mira 26 5.6e+06 Dumai Tidak Aktif
## 14 C014 Nanda 30 6.0e+06 Pekanbaru Aktif
## 15 C015 Oki 33 5.0e+06 PKU Aktif
Dataset tersebut terdiri dari 15 observasi dan 6 variabel. Sebanyak 11 observasi pertama, yaitu C001 sampai C011, merupakan data utama yang tetap dipertahankan. Observasi C012 sampai C015 digunakan sebagai data tambahan.
Pada data awal terlihat beberapa permasalahan yang nantinya perlu
diperbaiki. Permasalahan tersebut berupa nilai NA pada
beberapa variabel, perbedaan penulisan kota dan status, serta nilai usia
150 tahun yang perlu diperiksa karena tidak sesuai dengan konteks data
pelanggan.
Langkah pertama dilakukan untuk mengetahui jumlah observasi dan
jumlah variabel yang terdapat dalam dataset. Fungsi dim()
digunakan untuk memperoleh informasi tersebut.
dim(pelanggan_raw)
## [1] 15 6
Output menunjukkan bahwa dataset memiliki 15 baris dan 6 kolom. Baris menunjukkan jumlah observasi atau pelanggan yang tersedia, sedangkan kolom menunjukkan jumlah variabel yang digunakan.
Dengan demikian, dataset awal memiliki 15 observasi dengan 6
karakteristik, yaitu customer_id, nama,
usia, pendapatan, kota, dan
status.
Pemeriksaan struktur dilakukan untuk mengetahui tipe data dari setiap variabel.
str(pelanggan_raw)
## 'data.frame': 15 obs. of 6 variables:
## $ customer_id: chr "C001" "C002" "C003" "C004" ...
## $ nama : chr "Ani" "Budi" "Citra" "Dodi" ...
## $ usia : num 21 25 23 150 27 NA 31 29 22 35 ...
## $ pendapatan : num 4.5e+06 NA 5.2e+06 4.8e+06 4.9e+06 5.1e+06 5.0e+08 4.7e+06 4.6e+06 5.3e+06 ...
## $ kota : chr "Pekanbaru" " PKU" "PEKANBARU" "Dumai" ...
## $ status : chr "Aktif" "aktif" "ACTIVE" "A" ...
Berdasarkan struktur data, variabel customer_id,
nama, kota, dan status merupakan
data karakter. Variabel usia dan pendapatan
merupakan data numerik.
Tipe data tersebut telah sesuai dengan karakteristik masing-masing variabel. Usia dan pendapatan dapat digunakan dalam perhitungan numerik, sedangkan identitas, kota, dan status digunakan sebagai informasi kategorik.
Seluruh isi dataset dapat dilihat menggunakan nama objek dataset.
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 Pekanbaru AKTIF
## 9 C009 Indra 22 4.6e+06 PKU A
## 10 C010 Joko 35 5.3e+06 Dumai Tidak aktif
## 11 C011 Kiki 28 NA <NA> Aktif
## 12 C012 Lala 24 4.4e+06 Pekanbaru Aktif
## 13 C013 Mira 26 5.6e+06 Dumai Tidak Aktif
## 14 C014 Nanda 30 6.0e+06 Pekanbaru Aktif
## 15 C015 Oki 33 5.0e+06 PKU Aktif
Output memperlihatkan seluruh observasi yang terdapat dalam dataset. Dari data tersebut terlihat bahwa beberapa variabel belum memiliki format yang seragam.
Pada variabel kota terdapat beberapa bentuk penulisan, seperti
Pekanbaru, PEKANBARU, pekanbaru,
dan PKU. Pada variabel status terdapat Aktif,
aktif, ACTIVE, dan A.
Selain itu, terdapat beberapa nilai kosong serta usia 150 tahun pada C004. Kondisi tersebut menunjukkan bahwa data perlu melalui proses preprocessing.
head(pelanggan_raw)
## customer_id nama usia pendapatan kota status
## 1 C001 Ani 21 4500000 Pekanbaru Aktif
## 2 C002 Budi 25 NA PKU aktif
## 3 C003 Citra 23 5200000 PEKANBARU ACTIVE
## 4 C004 Dodi 150 4800000 Dumai A
## 5 C005 Eka 27 4900000 pekanbaru Tidak Aktif
## 6 C006 Fani NA 5100000 DUMAI nonaktif
Fungsi head() secara default menampilkan enam observasi
pertama. Output ini memberikan gambaran awal mengenai bentuk dan isi
data tanpa harus menampilkan seluruh observasi.
Dari enam observasi pertama dapat terlihat bahwa terdapat ketidakkonsistenan penulisan kategori serta beberapa nilai yang perlu diperiksa pada tahap selanjutnya.
Statistik deskriptif digunakan untuk melihat karakteristik umum variabel numerik.
summary(pelanggan_raw)
## customer_id nama usia pendapatan
## Length:15 Length:15 Min. : 21.00 Min. : 4400000
## Class :character Class :character 1st Qu.: 24.25 1st Qu.: 4700000
## Mode :character Mode :character Median : 27.50 Median : 5000000
## Mean : 36.00 Mean : 43084615
## 3rd Qu.: 30.75 3rd Qu.: 5300000
## Max. :150.00 Max. :500000000
## NA's :1 NA's :2
## kota status
## Length:15 Length:15
## Class :character Class :character
## Mode :character Mode :character
##
##
##
##
Output summary() memberikan informasi berupa nilai
minimum, kuartil pertama, median, rata-rata, kuartil ketiga, dan
maksimum untuk variabel numerik.
Pada variabel usia terdapat nilai maksimum sebesar 150 tahun. Nilai tersebut terlihat sangat berbeda dibandingkan usia pelanggan lainnya sehingga perlu diperiksa lebih lanjut.
Pada variabel pendapatan juga terdapat nilai yang jauh lebih besar dibandingkan sebagian besar observasi. Nilai tersebut nantinya akan diperiksa menggunakan metode deteksi outlier.
Missing value merupakan kondisi ketika suatu nilai tidak tersedia
dalam dataset. Pemeriksaan dilakukan menggunakan fungsi
is.na() yang kemudian dijumlahkan berdasarkan kolom.
colSums(
is.na(pelanggan_raw)
)
## customer_id nama usia pendapatan kota status
## 0 0 1 2 1 0
Output menunjukkan jumlah nilai kosong pada masing-masing variabel.
Variabel usia dan pendapatan memiliki missing
value, sedangkan terdapat pula nilai kosong pada variabel
kota.
Informasi ini penting karena missing value perlu ditangani sebelum data digunakan untuk analisis. Jika dibiarkan, beberapa metode statistik dapat menghasilkan error atau hasil yang kurang sesuai.
Selain jumlah, missing value juga dapat dilihat berdasarkan persentasenya.
persentase_missing <- round(
colMeans(
is.na(pelanggan_raw)
) * 100,
2
)
persentase_missing
## customer_id nama usia pendapatan kota status
## 0.00 0.00 6.67 13.33 6.67 0.00
Persentase menunjukkan proporsi data yang hilang terhadap keseluruhan observasi pada setiap variabel.
Nilai persentase yang kecil menunjukkan bahwa hanya sebagian kecil data yang hilang. Pada dataset ini jumlah missing value masih relatif sedikit sehingga penanganannya dapat dilakukan melalui imputasi pada variabel numerik.
pelanggan_raw[
!complete.cases(pelanggan_raw),
]
## customer_id nama usia pendapatan kota status
## 2 C002 Budi 25 NA PKU aktif
## 6 C006 Fani NA 5100000 DUMAI nonaktif
## 11 C011 Kiki 28 NA <NA> Aktif
Output menampilkan observasi yang memiliki setidaknya satu nilai kosong.
Dengan melihat observasi tersebut, dapat diketahui pelanggan mana yang datanya belum lengkap. Informasi ini membantu menentukan langkah preprocessing yang sesuai.
Data mentah tidak langsung diubah. Sebuah salinan dibuat agar data asli tetap tersedia sebagai pembanding.
pelanggan <- pelanggan_raw
Objek pelanggan sekarang menjadi dataset yang digunakan
untuk proses cleaning dan preprocessing berikutnya, sedangkan
pelanggan_raw tetap menyimpan data awal.
Pada variabel kota ditemukan perbedaan penggunaan huruf, spasi, dan singkatan. Oleh karena itu dilakukan penyeragaman.
pelanggan$kota <- trimws(
pelanggan$kota
)
pelanggan$kota <- toupper(
pelanggan$kota
)
pelanggan$kota[
pelanggan$kota == "PKU"
] <- "PEKANBARU"
pelanggan$kota
## [1] "PEKANBARU" "PEKANBARU" "PEKANBARU" "DUMAI" "PEKANBARU" "DUMAI"
## [7] "PEKANBARU" "PEKANBARU" "PEKANBARU" "DUMAI" NA "PEKANBARU"
## [13] "DUMAI" "PEKANBARU" "PEKANBARU"
Fungsi trimws() digunakan untuk menghilangkan spasi yang
tidak diperlukan, sedangkan toupper() mengubah seluruh
huruf menjadi huruf kapital.
Selanjutnya, kategori PKU diubah menjadi
PEKANBARU karena keduanya dianggap merujuk pada kota yang
sama.
Setelah proses tersebut dilakukan, penulisan kota menjadi lebih konsisten dan kategori yang sebenarnya sama tidak lagi dianggap sebagai kategori yang berbeda.
pelanggan$status <- trimws(
pelanggan$status
)
pelanggan$status <- toupper(
pelanggan$status
)
pelanggan$status[
pelanggan$status %in%
c("ACTIVE", "A")
] <- "AKTIF"
pelanggan$status[
pelanggan$status %in%
c(
"NONAKTIF",
"TIDAK AKTIF"
)
] <- "TIDAK AKTIF"
pelanggan$status
## [1] "AKTIF" "AKTIF" "AKTIF" "AKTIF" "TIDAK AKTIF"
## [6] "TIDAK AKTIF" "AKTIF" "AKTIF" "AKTIF" "TIDAK AKTIF"
## [11] "AKTIF" "AKTIF" "TIDAK AKTIF" "AKTIF" "AKTIF"
Output menunjukkan bahwa penulisan status telah diseragamkan.
Kategori ACTIVE dan A digabungkan menjadi
AKTIF, sedangkan NONAKTIF dan
TIDAK AKTIF diseragamkan menjadi
TIDAK AKTIF.
Penyeragaman ini penting agar kategori yang memiliki makna sama tidak dihitung sebagai kategori yang berbeda pada analisis selanjutnya.
table(
pelanggan$kota,
useNA = "ifany"
)
##
## DUMAI PEKANBARU <NA>
## 4 10 1
Output menunjukkan frekuensi masing-masing kategori kota setelah proses cleaning.
Kategori yang sebelumnya memiliki variasi penulisan seperti
PKU, Pekanbaru, dan PEKANBARU
telah diseragamkan menjadi PEKANBARU.
Nilai NA tetap muncul karena proses cleaning kategori
tidak digunakan untuk mengisi nilai yang hilang.
table(
pelanggan$status,
useNA = "ifany"
)
##
## AKTIF TIDAK AKTIF
## 11 4
Output menunjukkan bahwa kategori status telah menjadi lebih
konsisten, yaitu AKTIF dan TIDAK AKTIF.
Dengan penyeragaman tersebut, analisis frekuensi maupun analisis kategorik berikutnya dapat dilakukan dengan lebih tepat.
pelanggan[
pelanggan$usia > 100,
c(
"customer_id",
"nama",
"usia"
)
]
## customer_id nama usia
## 4 C004 Dodi 150
## NA <NA> <NA> NA
Output menunjukkan bahwa pelanggan C004 memiliki usia 150 tahun.
Dalam konteks data pelanggan, usia tersebut dianggap tidak logis sehingga perlu diperiksa dan diperbaiki. Nilai seperti ini dapat terjadi karena kesalahan input atau kesalahan pencatatan.
pelanggan$usia[
pelanggan$customer_id == "C004"
] <- 50
Nilai usia C004 diubah dari 150 menjadi 50 tahun karena 150 dianggap sebagai nilai yang tidak sesuai dengan konteks dataset.
pelanggan[
pelanggan$customer_id == "C004",
c(
"customer_id",
"nama",
"usia"
)
]
## customer_id nama usia
## 4 C004 Dodi 50
Output menunjukkan bahwa usia C004 sekarang telah berubah menjadi 50 tahun.
Dengan demikian, nilai usia yang sebelumnya tidak logis telah diperbaiki dan dapat digunakan pada tahapan preprocessing selanjutnya.
colSums(
is.na(pelanggan)
)
## customer_id nama usia pendapatan kota status
## 0 0 1 2 1 0
Setelah proses cleaning, masih terdapat beberapa nilai yang kosong. Missing value pada variabel numerik akan ditangani menggunakan median.
Median digunakan karena lebih tahan terhadap pengaruh nilai ekstrem dibandingkan rata-rata.
median_usia <- median(
pelanggan$usia,
na.rm = TRUE
)
median_usia
## [1] 27.5
Nilai yang ditampilkan merupakan median usia dengan mengabaikan nilai
NA.
Nilai tersebut akan digunakan sebagai pengganti bagi observasi yang tidak memiliki informasi usia.
median_pendapatan <- median(
pelanggan$pendapatan,
na.rm = TRUE
)
median_pendapatan
## [1] 5e+06
Nilai yang diperoleh merupakan median pendapatan setelah nilai kosong diabaikan.
Median tersebut akan digunakan untuk menggantikan pendapatan yang hilang.
pelanggan$usia_imputasi <- ifelse(
is.na(pelanggan$usia),
median_usia,
pelanggan$usia
)
pelanggan$pendapatan_imputasi <- ifelse(
is.na(pelanggan$pendapatan),
median_pendapatan,
pelanggan$pendapatan
)
Fungsi ifelse() digunakan untuk melakukan imputasi.
Apabila nilai merupakan NA, nilai tersebut diganti dengan
median. Apabila nilai tidak kosong, nilai aslinya tetap
dipertahankan.
Dengan cara ini, informasi yang sudah tersedia tidak berubah dan hanya nilai yang hilang yang digantikan.
pelanggan[
,
c(
"customer_id",
"usia",
"usia_imputasi",
"pendapatan",
"pendapatan_imputasi"
)
]
## customer_id usia usia_imputasi pendapatan pendapatan_imputasi
## 1 C001 21 21.0 4.5e+06 4.5e+06
## 2 C002 25 25.0 NA 5.0e+06
## 3 C003 23 23.0 5.2e+06 5.2e+06
## 4 C004 50 50.0 4.8e+06 4.8e+06
## 5 C005 27 27.0 4.9e+06 4.9e+06
## 6 C006 NA 27.5 5.1e+06 5.1e+06
## 7 C007 31 31.0 5.0e+08 5.0e+08
## 8 C008 29 29.0 4.7e+06 4.7e+06
## 9 C009 22 22.0 4.6e+06 4.6e+06
## 10 C010 35 35.0 5.3e+06 5.3e+06
## 11 C011 28 28.0 NA 5.0e+06
## 12 C012 24 24.0 4.4e+06 4.4e+06
## 13 C013 26 26.0 5.6e+06 5.6e+06
## 14 C014 30 30.0 6.0e+06 6.0e+06
## 15 C015 33 33.0 5.0e+06 5.0e+06
Kolom sebelum imputasi memperlihatkan kondisi awal data, sedangkan kolom sesudah imputasi memperlihatkan data setelah nilai kosong diganti menggunakan median.
Observasi yang sebelumnya memiliki NA sekarang memiliki
nilai numerik. Sementara itu, observasi yang sudah memiliki nilai tetap
mempertahankan nilai aslinya.
colSums(
is.na(
pelanggan[
,
c(
"usia_imputasi",
"pendapatan_imputasi"
)
]
)
)
## usia_imputasi pendapatan_imputasi
## 0 0
Output menunjukkan bahwa variabel usia_imputasi dan
pendapatan_imputasi sudah tidak memiliki missing value.
Hal tersebut menunjukkan bahwa proses imputasi median telah berhasil dilakukan pada kedua variabel numerik tersebut.
boxplot(
pelanggan$pendapatan_imputasi,
horizontal = TRUE,
main = "Boxplot Pendapatan Pelanggan",
xlab = "Pendapatan"
)
Boxplot digunakan untuk melihat distribusi data dan mengidentifikasi kemungkinan adanya nilai ekstrem.
Pada grafik terlihat adanya pendapatan yang jauh lebih tinggi dibandingkan sebagian besar observasi lainnya. Nilai tersebut kemudian diperiksa secara lebih objektif menggunakan metode IQR.
Q1 <- quantile(
pelanggan$pendapatan_imputasi,
0.25
)
Q3 <- quantile(
pelanggan$pendapatan_imputasi,
0.75
)
Q1
## 25%
## 4750000
Q3
## 75%
## 5250000
Q1 merupakan kuartil pertama, yaitu titik yang membatasi sekitar 25% data terendah. Q3 merupakan kuartil ketiga yang membatasi sekitar 75% data.
Kedua nilai tersebut digunakan untuk menghitung IQR.
IQR_pendapatan <- Q3 - Q1
IQR_pendapatan
## 75%
## 5e+05
IQR merupakan selisih antara Q3 dan Q1. Nilai ini menunjukkan penyebaran 50% data yang berada di bagian tengah distribusi.
IQR selanjutnya digunakan untuk menentukan batas bawah dan batas atas dalam identifikasi outlier.
batas_bawah <- Q1 -
1.5 * IQR_pendapatan
batas_atas <- Q3 +
1.5 * IQR_pendapatan
batas_bawah
## 25%
## 4e+06
batas_atas
## 75%
## 6e+06
Berdasarkan metode IQR, observasi yang berada di bawah batas bawah atau di atas batas atas dikategorikan sebagai outlier.
Batas tersebut menjadi dasar untuk menentukan apakah nilai pendapatan tertentu merupakan nilai ekstrem.
pelanggan$outlier_pendapatan <-
pelanggan$pendapatan_imputasi <
batas_bawah |
pelanggan$pendapatan_imputasi >
batas_atas
pelanggan[
pelanggan$outlier_pendapatan,
c(
"customer_id",
"nama",
"pendapatan_imputasi"
)
]
## customer_id nama pendapatan_imputasi
## 7 C007 Gilang 5e+08
Output menampilkan observasi yang berada di luar batas IQR.
Nilai pendapatan yang sangat tinggi ditandai sebagai outlier. Namun, outlier tidak secara otomatis berarti data tersebut salah. Nilai tersebut perlu diperiksa berdasarkan sumber data dan konteks penelitian sebelum diputuskan untuk dihapus, dipertahankan, atau ditransformasi.
Normalisasi Min-Max digunakan untuk mengubah nilai ke dalam rentang 0 sampai 1.
Rumus yang digunakan adalah:
\[ X' = \frac{X-X_{min}} {X_{max}-X_{min}} \]
minmax <- function(x) {
(x - min(x)) /
(max(x) - min(x))
}
Fungsi tersebut kemudian diterapkan pada variabel pendapatan.
pelanggan$pendapatan_minmax <-
minmax(
pelanggan$pendapatan_imputasi
)
Hasil normalisasi ditampilkan berikut.
pelanggan[
,
c(
"customer_id",
"pendapatan_imputasi",
"pendapatan_minmax"
)
]
## customer_id pendapatan_imputasi pendapatan_minmax
## 1 C001 4.5e+06 0.0002017756
## 2 C002 5.0e+06 0.0012106538
## 3 C003 5.2e+06 0.0016142050
## 4 C004 4.8e+06 0.0008071025
## 5 C005 4.9e+06 0.0010088781
## 6 C006 5.1e+06 0.0014124294
## 7 C007 5.0e+08 1.0000000000
## 8 C008 4.7e+06 0.0006053269
## 9 C009 4.6e+06 0.0004035513
## 10 C010 5.3e+06 0.0018159806
## 11 C011 5.0e+06 0.0012106538
## 12 C012 4.4e+06 0.0000000000
## 13 C013 5.6e+06 0.0024213075
## 14 C014 6.0e+06 0.0032284100
## 15 C015 5.0e+06 0.0012106538
Hasil menunjukkan bahwa pendapatan telah diubah ke skala 0 sampai 1.
Observasi dengan pendapatan paling rendah memiliki nilai yang mendekati 0, sedangkan pendapatan paling tinggi memiliki nilai mendekati 1. Transformasi ini berguna ketika suatu metode analisis membutuhkan variabel dengan skala yang relatif seragam.
Selain Min-Max, dilakukan standardisasi menggunakan Z-Score.
Rumus Z-Score adalah:
\[ Z = \frac{X-\bar{X}}{s} \]
pelanggan$pendapatan_z <-
as.numeric(
scale(
pelanggan$pendapatan_imputasi
)
)
Hasil standardisasi ditampilkan sebagai berikut.
pelanggan[
,
c(
"customer_id",
"pendapatan_imputasi",
"pendapatan_z"
)
]
## customer_id pendapatan_imputasi pendapatan_z
## 1 C001 4.5e+06 -0.2621656
## 2 C002 5.0e+06 -0.2582534
## 3 C003 5.2e+06 -0.2566886
## 4 C004 4.8e+06 -0.2598183
## 5 C005 4.9e+06 -0.2590358
## 6 C006 5.1e+06 -0.2574710
## 7 C007 5.0e+08 3.6147654
## 8 C008 4.7e+06 -0.2606007
## 9 C009 4.6e+06 -0.2613831
## 10 C010 5.3e+06 -0.2559061
## 11 C011 5.0e+06 -0.2582534
## 12 C012 4.4e+06 -0.2629480
## 13 C013 5.6e+06 -0.2535588
## 14 C014 6.0e+06 -0.2504291
## 15 C015 5.0e+06 -0.2582534
Nilai Z-Score menunjukkan posisi setiap pendapatan terhadap rata-rata.
Nilai positif menunjukkan pendapatan berada di atas rata-rata, sedangkan nilai negatif menunjukkan pendapatan berada di bawah rata-rata. Semakin besar nilai absolut Z-Score, semakin jauh observasi tersebut dari rata-rata.
Untuk melakukan integrasi data, dibuat dataset transaksi yang
memiliki customer_id sebagai kunci penggabungan.
transaksi_raw <- data.frame(
customer_id = c(
"C001","C002","C003","C004","C005",
"C006","C007","C008","C009","C010",
"C012","C013","C014","C015"
),
jumlah_transaksi = c(
5,3,7,2,6,
4,20,5,3,8,
4,9,6,7
),
total_purchase = c(
1500000,
900000,
2700000,
600000,
2100000,
1300000,
25000000,
1700000,
800000,
3200000,
1400000,
4200000,
3100000,
3600000
),
stringsAsFactors = FALSE
)
transaksi_raw
## customer_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 4 1.4e+06
## 12 C013 9 4.2e+06
## 13 C014 6 3.1e+06
## 14 C015 7 3.6e+06
Dataset transaksi terdiri dari tiga variabel, yaitu
customer_id, jumlah_transaksi, dan
total_purchase.
Variabel customer_id digunakan sebagai kunci karena
terdapat pada kedua dataset. Dengan adanya kunci yang sama, informasi
transaksi dapat dikaitkan dengan karakteristik pelanggan.
data_terintegrasi <- merge(
pelanggan,
transaksi_raw,
by = "customer_id",
all.x = TRUE
)
Data digabungkan berdasarkan customer_id. Argumen
all.x = TRUE digunakan agar seluruh observasi dari dataset
pelanggan tetap dipertahankan.
Dengan demikian, apabila terdapat pelanggan yang tidak memiliki data transaksi, pelanggan tersebut tetap berada dalam dataset hasil integrasi.
data_terintegrasi
## customer_id nama usia pendapatan kota status usia_imputasi
## 1 C001 Ani 21 4.5e+06 PEKANBARU AKTIF 21.0
## 2 C002 Budi 25 NA PEKANBARU AKTIF 25.0
## 3 C003 Citra 23 5.2e+06 PEKANBARU AKTIF 23.0
## 4 C004 Dodi 50 4.8e+06 DUMAI AKTIF 50.0
## 5 C005 Eka 27 4.9e+06 PEKANBARU TIDAK AKTIF 27.0
## 6 C006 Fani NA 5.1e+06 DUMAI TIDAK AKTIF 27.5
## 7 C007 Gilang 31 5.0e+08 PEKANBARU AKTIF 31.0
## 8 C008 Hana 29 4.7e+06 PEKANBARU AKTIF 29.0
## 9 C009 Indra 22 4.6e+06 PEKANBARU AKTIF 22.0
## 10 C010 Joko 35 5.3e+06 DUMAI TIDAK AKTIF 35.0
## 11 C011 Kiki 28 NA <NA> AKTIF 28.0
## 12 C012 Lala 24 4.4e+06 PEKANBARU AKTIF 24.0
## 13 C013 Mira 26 5.6e+06 DUMAI TIDAK AKTIF 26.0
## 14 C014 Nanda 30 6.0e+06 PEKANBARU AKTIF 30.0
## 15 C015 Oki 33 5.0e+06 PEKANBARU AKTIF 33.0
## pendapatan_imputasi outlier_pendapatan pendapatan_minmax pendapatan_z
## 1 4.5e+06 FALSE 0.0002017756 -0.2621656
## 2 5.0e+06 FALSE 0.0012106538 -0.2582534
## 3 5.2e+06 FALSE 0.0016142050 -0.2566886
## 4 4.8e+06 FALSE 0.0008071025 -0.2598183
## 5 4.9e+06 FALSE 0.0010088781 -0.2590358
## 6 5.1e+06 FALSE 0.0014124294 -0.2574710
## 7 5.0e+08 TRUE 1.0000000000 3.6147654
## 8 4.7e+06 FALSE 0.0006053269 -0.2606007
## 9 4.6e+06 FALSE 0.0004035513 -0.2613831
## 10 5.3e+06 FALSE 0.0018159806 -0.2559061
## 11 5.0e+06 FALSE 0.0012106538 -0.2582534
## 12 4.4e+06 FALSE 0.0000000000 -0.2629480
## 13 5.6e+06 FALSE 0.0024213075 -0.2535588
## 14 6.0e+06 FALSE 0.0032284100 -0.2504291
## 15 5.0e+06 FALSE 0.0012106538 -0.2582534
## 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
## 12 4 1.4e+06
## 13 9 4.2e+06
## 14 6 3.1e+06
## 15 7 3.6e+06
Output menunjukkan bahwa informasi pelanggan dan informasi transaksi telah berada dalam satu dataset.
Dataset tersebut sekarang memiliki informasi seperti identitas pelanggan, usia, pendapatan, kota, status, jumlah transaksi, dan total pembelian.
data_terintegrasi[
,
c(
"customer_id",
"nama",
"usia_imputasi",
"pendapatan_imputasi",
"kota",
"status",
"jumlah_transaksi",
"total_purchase"
)
]
## customer_id nama usia_imputasi pendapatan_imputasi kota status
## 1 C001 Ani 21.0 4.5e+06 PEKANBARU AKTIF
## 2 C002 Budi 25.0 5.0e+06 PEKANBARU AKTIF
## 3 C003 Citra 23.0 5.2e+06 PEKANBARU AKTIF
## 4 C004 Dodi 50.0 4.8e+06 DUMAI AKTIF
## 5 C005 Eka 27.0 4.9e+06 PEKANBARU TIDAK AKTIF
## 6 C006 Fani 27.5 5.1e+06 DUMAI TIDAK AKTIF
## 7 C007 Gilang 31.0 5.0e+08 PEKANBARU AKTIF
## 8 C008 Hana 29.0 4.7e+06 PEKANBARU AKTIF
## 9 C009 Indra 22.0 4.6e+06 PEKANBARU AKTIF
## 10 C010 Joko 35.0 5.3e+06 DUMAI TIDAK AKTIF
## 11 C011 Kiki 28.0 5.0e+06 <NA> AKTIF
## 12 C012 Lala 24.0 4.4e+06 PEKANBARU AKTIF
## 13 C013 Mira 26.0 5.6e+06 DUMAI TIDAK AKTIF
## 14 C014 Nanda 30.0 6.0e+06 PEKANBARU AKTIF
## 15 C015 Oki 33.0 5.0e+06 PEKANBARU AKTIF
## 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
## 12 4 1.4e+06
## 13 9 4.2e+06
## 14 6 3.1e+06
## 15 7 3.6e+06
Tabel tersebut menunjukkan variabel utama yang digunakan setelah proses preprocessing.
Usia dan pendapatan telah menggunakan hasil imputasi, kota dan status telah diseragamkan, sedangkan informasi transaksi telah ditambahkan melalui proses integrasi.
dim(data_terintegrasi)
## [1] 15 13
Output menunjukkan ukuran dataset setelah proses integrasi.
Jumlah observasi tetap mempertahankan data pelanggan utama karena
proses penggabungan menggunakan all.x = TRUE. Jumlah kolom
bertambah karena adanya variabel yang berasal dari dataset
transaksi.
str(data_terintegrasi)
## 'data.frame': 15 obs. of 13 variables:
## $ customer_id : chr "C001" "C002" "C003" "C004" ...
## $ nama : chr "Ani" "Budi" "Citra" "Dodi" ...
## $ usia : num 21 25 23 50 27 NA 31 29 22 35 ...
## $ pendapatan : num 4.5e+06 NA 5.2e+06 4.8e+06 4.9e+06 5.1e+06 5.0e+08 4.7e+06 4.6e+06 5.3e+06 ...
## $ kota : chr "PEKANBARU" "PEKANBARU" "PEKANBARU" "DUMAI" ...
## $ status : chr "AKTIF" "AKTIF" "AKTIF" "AKTIF" ...
## $ usia_imputasi : num 21 25 23 50 27 27.5 31 29 22 35 ...
## $ pendapatan_imputasi: num 4.5e+06 5.0e+06 5.2e+06 4.8e+06 4.9e+06 5.1e+06 5.0e+08 4.7e+06 4.6e+06 5.3e+06 ...
## $ outlier_pendapatan : logi FALSE FALSE FALSE FALSE FALSE FALSE ...
## $ pendapatan_minmax : num 0.000202 0.001211 0.001614 0.000807 0.001009 ...
## $ pendapatan_z : num -0.262 -0.258 -0.257 -0.26 -0.259 ...
## $ 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 ...
Struktur dataset akhir menunjukkan bahwa variabel numerik dan kategorik masih memiliki tipe data yang sesuai.
Variabel seperti usia, pendapatan, jumlah transaksi, dan total pembelian dapat digunakan dalam analisis numerik. Sementara itu, variabel identitas dan kategori tetap digunakan sebagai informasi karakteristik pelanggan.
colSums(
is.na(data_terintegrasi)
)
## customer_id nama usia pendapatan
## 0 0 1 2
## kota status usia_imputasi pendapatan_imputasi
## 1 0 0 0
## outlier_pendapatan pendapatan_minmax pendapatan_z jumlah_transaksi
## 0 0 0 1
## total_purchase
## 1
Pemeriksaan ini dilakukan untuk mengetahui apakah masih terdapat nilai kosong setelah seluruh proses preprocessing.
Variabel usia dan pendapatan telah ditangani melalui proses imputasi.
Jika masih terdapat NA pada variabel lain, nilai tersebut
perlu diperiksa kembali berdasarkan kebutuhan analisis.
summary(
data_terintegrasi
)
## customer_id nama usia pendapatan
## Length:15 Length:15 Min. :21.00 Min. : 4400000
## Class :character Class :character 1st Qu.:24.25 1st Qu.: 4700000
## Mode :character Mode :character Median :27.50 Median : 5000000
## Mean :28.86 Mean : 43084615
## 3rd Qu.:30.75 3rd Qu.: 5300000
## Max. :50.00 Max. :500000000
## NA's :1 NA's :2
## kota status usia_imputasi pendapatan_imputasi
## Length:15 Length:15 Min. :21.00 Min. : 4400000
## Class :character Class :character 1st Qu.:24.50 1st Qu.: 4750000
## Mode :character Mode :character Median :27.50 Median : 5000000
## Mean :28.77 Mean : 38006667
## 3rd Qu.:30.50 3rd Qu.: 5250000
## Max. :50.00 Max. :500000000
##
## outlier_pendapatan pendapatan_minmax pendapatan_z jumlah_transaksi
## Mode :logical Min. :0.0000000 Min. :-0.2629 Min. : 2.000
## FALSE:14 1st Qu.:0.0007062 1st Qu.:-0.2602 1st Qu.: 4.000
## TRUE :1 Median :0.0012107 Median :-0.2583 Median : 5.500
## Mean :0.0678101 Mean : 0.0000 Mean : 6.357
## 3rd Qu.:0.0017151 3rd Qu.:-0.2563 3rd Qu.: 7.000
## Max. :1.0000000 Max. : 3.6148 Max. :20.000
## NA's :1
## total_purchase
## Min. : 600000
## 1st Qu.: 1325000
## Median : 1900000
## Mean : 3721429
## 3rd Qu.: 3175000
## Max. :25000000
## NA's :1
Statistik deskriptif akhir memberikan gambaran kondisi data setelah preprocessing.
Hasil ini dapat digunakan untuk membandingkan kondisi dataset sebelum dan sesudah preprocessing. Perubahan terutama terlihat pada variabel yang mengalami imputasi dan perbaikan nilai.
Untuk melihat perubahan data secara langsung, dibuat tabel perbandingan.
data_perbandingan <- data.frame(
Customer_ID =
pelanggan$customer_id,
Usia_Sebelum =
pelanggan$usia,
Usia_Sesudah =
pelanggan$usia_imputasi,
Pendapatan_Sebelum =
pelanggan$pendapatan,
Pendapatan_Sesudah =
pelanggan$pendapatan_imputasi
)
data_perbandingan
## Customer_ID Usia_Sebelum Usia_Sesudah Pendapatan_Sebelum Pendapatan_Sesudah
## 1 C001 21 21.0 4.5e+06 4.5e+06
## 2 C002 25 25.0 NA 5.0e+06
## 3 C003 23 23.0 5.2e+06 5.2e+06
## 4 C004 50 50.0 4.8e+06 4.8e+06
## 5 C005 27 27.0 4.9e+06 4.9e+06
## 6 C006 NA 27.5 5.1e+06 5.1e+06
## 7 C007 31 31.0 5.0e+08 5.0e+08
## 8 C008 29 29.0 4.7e+06 4.7e+06
## 9 C009 22 22.0 4.6e+06 4.6e+06
## 10 C010 35 35.0 5.3e+06 5.3e+06
## 11 C011 28 28.0 NA 5.0e+06
## 12 C012 24 24.0 4.4e+06 4.4e+06
## 13 C013 26 26.0 5.6e+06 5.6e+06
## 14 C014 30 30.0 6.0e+06 6.0e+06
## 15 C015 33 33.0 5.0e+06 5.0e+06
Tabel tersebut memperlihatkan perubahan pada variabel usia dan pendapatan.
Pada observasi yang memiliki nilai kosong, nilai setelah preprocessing telah digantikan menggunakan median. Selain itu, nilai usia C004 yang sebelumnya 150 tahun telah diperbaiki menjadi 50 tahun.
Perbandingan ini menunjukkan bahwa preprocessing tidak hanya membersihkan data, tetapi juga menghasilkan versi data yang lebih siap digunakan dalam analisis.
ringkasan <- data.frame(
Tahapan = c(
"Pemeriksaan awal",
"Data cleaning",
"Pemeriksaan nilai tidak logis",
"Penanganan missing value",
"Deteksi outlier",
"Normalisasi",
"Standardisasi",
"Integrasi data"
),
Metode = c(
"dim(), str(), summary()",
"Penyeragaman kategori",
"Pemeriksaan dan koreksi usia",
"Imputasi median",
"Metode IQR",
"Min-Max",
"Z-Score",
"Merge berdasarkan customer_id"
)
)
ringkasan
## Tahapan Metode
## 1 Pemeriksaan awal dim(), str(), summary()
## 2 Data cleaning Penyeragaman kategori
## 3 Pemeriksaan nilai tidak logis Pemeriksaan dan koreksi usia
## 4 Penanganan missing value Imputasi median
## 5 Deteksi outlier Metode IQR
## 6 Normalisasi Min-Max
## 7 Standardisasi Z-Score
## 8 Integrasi data Merge berdasarkan customer_id
Tabel tersebut merangkum seluruh proses yang telah dilakukan. Dataset terlebih dahulu diperiksa untuk mengetahui struktur dan permasalahannya.
Selanjutnya dilakukan cleaning untuk menyeragamkan kategori. Nilai tidak logis diperiksa dan diperbaiki, sedangkan missing value numerik ditangani menggunakan median.
Setelah itu dilakukan deteksi outlier dengan metode IQR, transformasi Min-Max, standardisasi Z-Score, serta integrasi dengan data transaksi.
data_akhir <- data_terintegrasi[
,
c(
"customer_id",
"nama",
"usia_imputasi",
"pendapatan_imputasi",
"kota",
"status",
"jumlah_transaksi",
"total_purchase"
)
]
data_akhir
## customer_id nama usia_imputasi pendapatan_imputasi kota status
## 1 C001 Ani 21.0 4.5e+06 PEKANBARU AKTIF
## 2 C002 Budi 25.0 5.0e+06 PEKANBARU AKTIF
## 3 C003 Citra 23.0 5.2e+06 PEKANBARU AKTIF
## 4 C004 Dodi 50.0 4.8e+06 DUMAI AKTIF
## 5 C005 Eka 27.0 4.9e+06 PEKANBARU TIDAK AKTIF
## 6 C006 Fani 27.5 5.1e+06 DUMAI TIDAK AKTIF
## 7 C007 Gilang 31.0 5.0e+08 PEKANBARU AKTIF
## 8 C008 Hana 29.0 4.7e+06 PEKANBARU AKTIF
## 9 C009 Indra 22.0 4.6e+06 PEKANBARU AKTIF
## 10 C010 Joko 35.0 5.3e+06 DUMAI TIDAK AKTIF
## 11 C011 Kiki 28.0 5.0e+06 <NA> AKTIF
## 12 C012 Lala 24.0 4.4e+06 PEKANBARU AKTIF
## 13 C013 Mira 26.0 5.6e+06 DUMAI TIDAK AKTIF
## 14 C014 Nanda 30.0 6.0e+06 PEKANBARU AKTIF
## 15 C015 Oki 33.0 5.0e+06 PEKANBARU AKTIF
## 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
## 12 4 1.4e+06
## 13 9 4.2e+06
## 14 6 3.1e+06
## 15 7 3.6e+06
Dataset akhir merupakan hasil dari seluruh rangkaian preprocessing.
Data telah melalui proses pemeriksaan, cleaning, penanganan missing value, perbaikan nilai tidak logis, serta integrasi dengan data transaksi.
Dengan kondisi tersebut, dataset menjadi lebih terstruktur dan konsisten sehingga dapat digunakan sebagai dasar untuk analisis selanjutnya.
Berdasarkan seluruh tahapan yang telah dilakukan, data preprocessing merupakan proses penting untuk memastikan data memiliki kualitas yang baik sebelum digunakan dalam analisis.
Dataset awal terdiri dari 15 observasi dan 6 variabel. Sebanyak 11 observasi utama, yaitu C001 sampai C011, tetap dipertahankan, sedangkan beberapa observasi tambahan digunakan untuk memperluas proses praktikum.
Pemeriksaan awal menunjukkan adanya beberapa masalah pada data, seperti missing value, ketidakkonsistenan penulisan kategori, nilai usia yang tidak logis, serta nilai pendapatan yang sangat tinggi.
Ketidakkonsistenan pada variabel kota dan status diperbaiki dengan menyeragamkan format penulisan. Nilai usia 150 tahun pada C004 diperiksa dan diperbaiki menjadi 50 tahun karena tidak sesuai dengan konteks data.
Missing value pada variabel numerik ditangani menggunakan median. Setelah dilakukan imputasi, variabel usia dan pendapatan tidak lagi memiliki nilai kosong.
Pemeriksaan outlier dilakukan menggunakan metode IQR. Nilai pendapatan yang berada di luar batas IQR ditandai sebagai outlier. Nilai tersebut tidak langsung dihapus karena diperlukan pemeriksaan lebih lanjut untuk menentukan apakah nilai tersebut merupakan kesalahan atau kondisi yang sebenarnya.
Transformasi Min-Max dilakukan untuk mengubah pendapatan ke dalam skala 0 sampai 1, sedangkan Z-Score digunakan untuk mengetahui posisi setiap observasi terhadap rata-rata.
Pada tahap akhir dilakukan integrasi antara data pelanggan dan data
transaksi berdasarkan customer_id. Hasilnya adalah dataset
yang memiliki informasi pelanggan dan transaksi secara bersamaan.
Secara keseluruhan, proses preprocessing menghasilkan data yang lebih bersih, konsisten, terstruktur, dan lebih siap digunakan untuk analisis atau pemodelan pada tahap selanjutnya.