Praktikum ini membahas penerapan eksplorasi dan visualisasi data menggunakan R, mulai dari pengenalan karakteristik data, eksplorasi univariate dan bivariate, hingga eksplorasi multivariate menggunakan cluster analysis, heatmap korelasi, Principal Component Analysis (PCA), dan Multidimensional Scaling (MDS).
Package yang digunakan pada praktikum ini adalah:
Jika package belum tersedia, jalankan terlebih dahulu:
Fungsi dist(), hclust(),
kmeans(), prcomp(), dan
cmdscale() tersedia pada R sehingga tidak membutuhkan
package tambahan.
Pada praktikum ini digunakan Mall Customer Segmentation Data.
Sumber data: Kaggle
Dataset: Customer Segmentation Tutorial in Python
Download: https://www.kaggle.com/datasets/vjchoudhary7/customer-segmentation-tutorial-in-python
File: Mall_Customers.csv
Simpan file Mall_Customers.csv pada folder yang sama
dengan file R Markdown ini.
customer <- read.csv("Mall_Customers.csv")
names(customer) <- c(
"CustomerID",
"Gender",
"Age",
"AnnualIncome",
"SpendingScore"
)
head(customer)## CustomerID Gender Age AnnualIncome SpendingScore
## 1 1 Male 19 15 39
## 2 2 Male 21 15 81
## 3 3 Female 20 16 6
## 4 4 Female 23 16 77
## 5 5 Female 31 17 40
## 6 6 Female 22 17 76
Kenali datanya sebelum menganalisisnya.
Eksplorasi data dilakukan untuk memperoleh pemahaman awal mengenai karakteristik, kualitas, pola, dan hubungan yang terdapat dalam data sebelum dilakukan analisis lebih lanjut.
## 1. DIMENSI DATA
## [1] 200 5
##
## 2. NAMA PEUBAH
## [1] "CustomerID" "Gender" "Age" "AnnualIncome"
## [5] "SpendingScore"
##
## 3. STRUKTUR DATA
## 'data.frame': 200 obs. of 5 variables:
## $ CustomerID : int 1 2 3 4 5 6 7 8 9 10 ...
## $ Gender : chr "Male" "Male" "Female" "Female" ...
## $ Age : int 19 21 20 23 31 22 35 23 64 30 ...
## $ AnnualIncome : int 15 15 16 16 17 17 18 18 19 19 ...
## $ SpendingScore: int 39 81 6 77 40 76 6 94 3 72 ...
##
## 4. RINGKASAN DATA
## CustomerID Gender Age AnnualIncome
## Min. : 1.00 Length :200 Min. :18.00 Min. : 15.00
## 1st Qu.: 50.75 N.unique : 2 1st Qu.:28.75 1st Qu.: 41.50
## Median :100.50 N.blank : 0 Median :36.00 Median : 61.50
## Mean :100.50 Min.nchar: 4 Mean :38.85 Mean : 60.56
## 3rd Qu.:150.25 Max.nchar: 6 3rd Qu.:49.00 3rd Qu.: 78.00
## Max. :200.00 Max. :70.00 Max. :137.00
## SpendingScore
## Min. : 1.00
## 1st Qu.:34.75
## Median :50.00
## Mean :50.20
## 3rd Qu.:73.00
## Max. :99.00
dim() menunjukkan ukuran dataset, str()
digunakan untuk melihat struktur dan tipe data setiap peubah, sedangkan
summary() memberikan ringkasan statistik awal.
## 1. MISSING VALUE PER PEUBAH
## CustomerID Gender Age AnnualIncome SpendingScore
## 0 0 0 0 0
##
## 2. TOTAL MISSING VALUE
## [1] 0
##
## 3. DATA DUPLIKAT
## [1] 0
Tahap ini digunakan untuk melihat apakah terdapat masalah data yang perlu ditangani sebelum eksplorasi lebih lanjut.
Dari satu peubah menuju hubungan antarpeubah.
Eksplorasi univariate digunakan untuk memahami karakteristik satu peubah, sedangkan eksplorasi bivariate digunakan untuk melihat pola hubungan antara dua peubah.
CustomerID tidak digunakan dalam eksplorasi distribusi
karena hanya berfungsi sebagai identifier.
data_sebaran <- stack(
customer[c(
"Age",
"AnnualIncome",
"SpendingScore"
)]
)
names(data_sebaran) <- c(
"Nilai",
"Peubah"
)
head(data_sebaran)## Nilai Peubah
## 1 19 Age
## 2 21 Age
## 3 20 Age
## 4 23 Age
## 5 31 Age
## 6 22 Age
Bagaimana nilai pada setiap peubah tersebar?
ggplot(
data_sebaran,
aes(x = Nilai)
) +
geom_histogram(
bins = 10,
fill = "steelblue",
color = "white"
) +
facet_wrap(
~ Peubah,
scales = "free",
nrow = 1
) +
labs(
title = "Distribusi Peubah Numerik",
x = "Nilai",
y = "Frekuensi"
) +
theme_minimal()Histogram membantu melihat bentuk distribusi, rentang data, dan konsentrasi observasi.
Di mana pusat data berada dan apakah terdapat nilai yang ekstrem?
ggplot(
data_sebaran,
aes(
x = Peubah,
y = Nilai
)
) +
geom_boxplot(
fill = "lightblue"
) +
facet_wrap(
~ Peubah,
scales = "free_y",
nrow = 1
) +
labs(
title = "Boxplot Peubah Numerik",
x = NULL,
y = "Nilai"
) +
theme_minimal()Boxplot memberikan informasi mengenai median, kuartil, sebaran data, dan kemungkinan pencilan.
Melihat kepadatan data melalui interval nilai.
ggplot(
customer,
aes(x = Age)
) +
geom_histogram(
aes(y = after_stat(density)),
bins = 10,
fill = "lightblue",
color = "white"
) +
labs(
title = "Naive Density Umur Pelanggan",
x = "Age",
y = "Density"
) +
theme_minimal()Melihat pola distribusi secara lebih halus.
ggplot(
data_sebaran,
aes(x = Nilai)
) +
geom_density(
fill = "steelblue",
alpha = 0.4
) +
facet_wrap(
~ Peubah,
scales = "free",
nrow = 1
) +
labs(
title = "Kernel Density Peubah Numerik",
x = "Nilai",
y = "Density"
) +
theme_minimal()Apakah distribusi sebuah peubah berbeda antar kelompok?
Sebagai contoh, SpendingScore dibandingkan berdasarkan
Gender.
customer %>%
group_by(Gender) %>%
summarise(
Jumlah = n(),
Rata_rata = mean(SpendingScore),
Median = median(SpendingScore),
SD = sd(SpendingScore)
)## # A tibble: 2 × 5
## Gender Jumlah Rata_rata Median SD
## <chr> <int> <dbl> <dbl> <dbl>
## 1 Female 112 51.5 50 24.1
## 2 Male 88 48.5 50 27.9
Apakah terdapat observasi yang jauh dari pola umum data?
ggplot(
customer,
aes(y = AnnualIncome)
) +
geom_boxplot(
fill = "lightblue"
) +
labs(
title = "Outlier Detection pada Annual Income",
x = NULL,
y = "Annual Income"
) +
theme_minimal()Q1 <- quantile(
customer$AnnualIncome,
0.25
)
Q3 <- quantile(
customer$AnnualIncome,
0.75
)
IQR_income <- IQR(
customer$AnnualIncome
)
batas_bawah <- Q1 - 1.5 * IQR_income
batas_atas <- Q3 + 1.5 * IQR_income
cat("Batas bawah:", batas_bawah, "\n")## Batas bawah: -13.25
## Batas atas : 132.75
## CustomerID Gender Age AnnualIncome SpendingScore
## 1 199 Male 32 137 18
## 2 200 Male 30 137 83
Tidak ditemukannya pencilan juga merupakan hasil eksplorasi yang valid.
Ketika dua peubah dilihat bersama, pola baru dapat muncul.
ggplot(
customer,
aes(
x = AnnualIncome,
y = SpendingScore
)
) +
geom_point(
size = 2,
alpha = 0.7
) +
labs(
title = "Annual Income dan Spending Score",
x = "Annual Income",
y = "Spending Score"
) +
theme_minimal()## [1] 0.009902848
Scatterplot membantu melihat pola hubungan yang tidak selalu dapat diringkas hanya oleh satu nilai korelasi.
Tambahkan informasi kelompok pada scatterplot.
ggplot(
customer,
aes(
x = AnnualIncome,
y = SpendingScore,
color = Gender,
shape = Gender
)
) +
geom_point(
size = 2.5,
alpha = 0.8
) +
labs(
title = "Plot Tebaran Bertanda Berdasarkan Gender",
x = "Annual Income",
y = "Spending Score"
) +
theme_minimal()Di wilayah mana observasi paling terkonsentrasi?
ggplot(
customer,
aes(
x = AnnualIncome,
y = SpendingScore
)
) +
stat_density_2d(
aes(
fill = after_stat(level)
),
geom = "polygon",
alpha = 0.6
) +
geom_point(
alpha = 0.3,
size = 1
) +
labs(
title = "2D Density Plot",
x = "Annual Income",
y = "Spending Score",
fill = "Density"
) +
theme_minimal()Satu visualisasi dapat membawa lebih dari dua informasi.
ggplot(
customer,
aes(
x = AnnualIncome,
y = SpendingScore,
size = Age
)
) +
geom_point(
alpha = 0.5
) +
labs(
title = "Bubble Plot",
x = "Annual Income",
y = "Spending Score",
size = "Age"
) +
theme_minimal()Hubungan antarpeubah tidak selalu berbentuk garis lurus.
ggplot(
customer,
aes(
x = AnnualIncome,
y = SpendingScore
)
) +
geom_point(
alpha = 0.4
) +
geom_smooth(
method = "loess",
se = FALSE
) +
labs(
title = "Local Regression",
x = "Annual Income",
y = "Spending Score"
) +
theme_minimal()Menemukan struktur yang tidak terlihat ketika peubah dianalisis satu per satu.
## Age AnnualIncome SpendingScore
## 1 19 15 39
## 2 21 15 81
## 3 20 16 6
## 4 23 16 77
## 5 31 17 40
## 6 22 17 76
## Age AnnualIncome SpendingScore
## [1,] -1.4210029 -1.734646 -0.4337131
## [2,] -1.2778288 -1.734646 1.1927111
## [3,] -1.3494159 -1.696572 -1.7116178
## [4,] -1.1346547 -1.696572 1.0378135
## [5,] -0.5619583 -1.658498 -0.3949887
## [6,] -1.2062418 -1.658498 0.9990891
Standardisasi dilakukan agar peubah dengan skala numerik lebih besar tidak mendominasi analisis berbasis jarak.
Apakah terdapat kelompok alami dalam data?
## 1 2 3 4 5
## 1 0.00 1.63 1.28 1.50 0.86
## 2 1.63 0.00 2.91 0.21 1.74
## 3 1.28 2.91 0.00 2.76 1.53
## 4 1.50 0.21 2.76 0.00 1.54
## 5 0.86 1.74 1.53 1.54 0.00
Semakin kecil jarak antara dua observasi, semakin mirip karakteristik keduanya berdasarkan peubah yang digunakan.
## [1] 40 54 39 47 20
## CustomerID Gender Age AnnualIncome SpendingScore Cluster
## 1 1 Male 19 15 39 2
## 2 2 Male 21 15 81 2
## 3 3 Female 20 16 6 5
## 4 4 Female 23 16 77 2
## 5 5 Female 31 17 40 2
## 6 6 Female 22 17 76 2
ggplot(
customer,
aes(
x = AnnualIncome,
y = SpendingScore,
color = Cluster
)
) +
geom_point(
size = 3,
alpha = 0.8
) +
labs(
title = "K-Means Clustering",
x = "Annual Income",
y = "Spending Score",
color = "Cluster"
) +
theme_minimal()Cluster baru menjadi bermakna setelah karakteristiknya diketahui.
customer %>%
group_by(Cluster) %>%
summarise(
Jumlah = n(),
Rata_Umur = mean(Age),
Rata_Income = mean(AnnualIncome),
Rata_Spending = mean(SpendingScore)
)## # A tibble: 5 × 5
## Cluster Jumlah Rata_Umur Rata_Income Rata_Spending
## <fct> <int> <dbl> <dbl> <dbl>
## 1 1 40 32.9 86.1 81.5
## 2 2 54 25.2 41.1 62.2
## 3 3 39 39.9 86.1 19.4
## 4 4 47 55.6 54.4 48.9
## 5 5 20 46.2 26.8 18.4
Melihat banyak hubungan antarpeubah dalam satu visualisasi.
## Age AnnualIncome SpendingScore
## Age 1.00 -0.01 -0.33
## AnnualIncome -0.01 1.00 0.01
## SpendingScore -0.33 0.01 1.00
corrplot(
cor_customer,
method = "color",
type = "upper",
addCoef.col = "black",
tl.col = "black",
tl.srt = 45
)Nilai mendekati 1 menunjukkan hubungan positif kuat,
nilai mendekati -1 menunjukkan hubungan negatif kuat,
sedangkan nilai mendekati 0 menunjukkan hubungan linier
yang lemah.
Merangkum informasi multivariat ke dalam komponen utama.
## Age AnnualIncome SpendingScore
## Min. :18.00 Min. : 15.00 Min. : 1.00
## 1st Qu.:28.75 1st Qu.: 41.50 1st Qu.:34.75
## Median :36.00 Median : 61.50 Median :50.00
## Mean :38.85 Mean : 60.56 Mean :50.20
## 3rd Qu.:49.00 3rd Qu.: 78.00 3rd Qu.:73.00
## Max. :70.00 Max. :137.00 Max. :99.00
Ketiga peubah memiliki skala yang berbeda. Oleh karena itu, PCA dilakukan dengan pemusatan dan standardisasi.
## Standard deviations (1, .., p=3):
## [1] 1.1523823 0.9996256 0.8202217
##
## Rotation (n x k) = (3 x 3):
## PC1 PC2 PC3
## Age 0.70638235 0.03014116 -0.707188441
## AnnualIncome -0.04802398 0.99883160 -0.005397916
## SpendingScore -0.70619946 -0.03777499 -0.707004506
Dengan center = TRUE dan scale. = TRUE, PCA
dilakukan setara dengan menggunakan matriks korelasi.
## Importance of components:
## PC1 PC2 PC3
## Standard deviation 1.1524 0.9996 0.8202
## Proportion of Variance 0.4427 0.3331 0.2243
## Cumulative Proportion 0.4427 0.7758 1.0000
Untuk menampilkan hasil secara lebih terstruktur:
# Menghitung eigenvalue
eigenvalue <- pca_customer$sdev^2
# Menghitung proporsi varians
proporsi_varians <- eigenvalue /
sum(eigenvalue)
# Membuat tabel ringkasan
hasil_varians <- data.frame(
Komponen = paste0(
"PC",
seq_along(eigenvalue)
),
Eigenvalue = eigenvalue,
Persen = proporsi_varians * 100,
Kumulatif = cumsum(
proporsi_varians
) * 100
)
# Membulatkan hanya kolom numerik
hasil_varians %>%
mutate(
across(
where(is.numeric),
~ round(.x, 3)
)
)## Komponen Eigenvalue Persen Kumulatif
## 1 PC1 1.328 44.266 44.266
## 2 PC2 0.999 33.308 77.575
## 3 PC3 0.673 22.425 100.000
Berapa banyak komponen yang masih membawa informasi penting?
Peubah apa yang berkontribusi dalam pembentukan setiap komponen?
## PC1 PC2 PC3
## Age 0.706 0.030 -0.707
## AnnualIncome -0.048 0.999 -0.005
## SpendingScore -0.706 -0.038 -0.707
rotation berisi loading masing-masing peubah. Nilai
absolut loading yang relatif besar menunjukkan kontribusi yang lebih
kuat terhadap pembentukan suatu komponen utama.
Di mana posisi setiap observasi pada sistem koordinat baru?
## PC1 PC2 PC3
## [1,] -0.61417879 -1.759067 1.32091743
## [2,] -1.66162301 -1.816189 0.06977714
## [3,] 0.33701620 -1.670607 2.17357077
## [4,] -1.45292726 -1.767993 0.07783381
## [5,] -0.03836892 -1.658578 0.68562168
## [6,] -1.47797641 -1.730659 0.15563214
## PC1 PC2 PC3
## 1 -0.61417879 -1.759067 1.32091743
## 2 -1.66162301 -1.816189 0.06977714
## 3 0.33701620 -1.670607 2.17357077
## 4 -1.45292726 -1.767993 0.07783381
## 5 -0.03836892 -1.658578 0.68562168
## 6 -1.47797641 -1.730659 0.15563214
Menyederhanakan dimensi dengan mempertahankan kedekatan antarobjek.
MDS menggunakan informasi jarak antarobservasi untuk memetakan data ke ruang berdimensi lebih rendah.
mds_data <- data.frame(
Dimensi1 = mds[, 1],
Dimensi2 = mds[, 2],
Cluster = customer$Cluster
)
head(mds_data)## Dimensi1 Dimensi2 Cluster
## 1 0.61417879 -1.759067 2
## 2 1.66162301 -1.816189 2
## 3 -0.33701620 -1.670607 5
## 4 1.45292726 -1.767993 2
## 5 0.03836892 -1.658578 2
## 6 1.47797641 -1.730659 2
ggplot(
mds_data,
aes(
x = Dimensi1,
y = Dimensi2,
color = Cluster
)
) +
geom_point(
size = 3,
alpha = 0.8
) +
labs(
title = "Multidimensional Scaling",
x = "Dimensi 1",
y = "Dimensi 2",
color = "Cluster"
) +
theme_minimal()Secara praktis, PCA merangkum variasi peubah ke dalam komponen utama, sedangkan MDS memetakan observasi dengan mempertahankan informasi kedekatan atau jarak antarobservasi sejauh mungkin.