1 Tujuan Praktikum

Pada pertemuan ini, kita akan melakukan Exploratory Data Analysis (EDA) untuk memahami karakteristik data sebelum masuk ke analisis lebih lanjut.

Setelah praktikum, mahasiswa diharapkan mampu:

  1. mengenali struktur dataset;
  2. memeriksa kualitas data;
  3. mengeksplorasi distribusi satu peubah;
  4. membandingkan distribusi antar kelompok;
  5. mendeteksi kandidat pencilan (outlier);
  6. mengeksplorasi hubungan dua peubah;
  7. memilih visualisasi berdasarkan pertanyaan analisis;
  8. menginterpretasikan grafik, bukan hanya membuat grafik.

Alur utama yang digunakan:

Pertanyaan → Data → Visualisasi → Interpretasi


2 Persiapan

2.1 Package

Pada praktikum ini kita menggunakan dplyr untuk pengolahan/ringkasan data dan ggplot2 untuk visualisasi.

Jika package belum terpasang, jalankan satu kali:

install.packages("dplyr")
install.packages("ggplot2")

Kemudian aktifkan package:

library(dplyr)
library(ggplot2)

options(scipen = 999)

2.2 Dataset

Dataset yang digunakan adalah Mall Customer Segmentation Data dengan lima peubah:

  • CustomerID: ID pelanggan;
  • Gender: jenis kelamin pelanggan;
  • Age: umur pelanggan;
  • AnnualIncome: pendapatan tahunan dalam ribuan dolar;
  • SpendingScore: skor perilaku/pengeluaran pelanggan (1–100).

Simpan file Mall_Customers.csv pada folder yang sama dengan file R Markdown ini.

Sumber dataset: Customer Segmentation Tutorial in Python (Kaggle).


3 Membaca dan Mengenal Data

3.1 Import data

customer <- read.csv("C:\\Nedi\\backip\\Magister\\R\\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

Perhatikan:

  • Apakah data berhasil dibaca?
  • Variabel apa saja yang tersedia?
  • Mana variabel numerik?
  • Mana variabel kategorik?
  • Apakah CustomerID layak dianalisis sebagai peubah numerik?

CustomerID memang disimpan sebagai angka, tetapi fungsinya hanya sebagai identifier, bukan ukuran kuantitatif yang perlu dianalisis distribusinya.


3.2 Dimensi data

dim(customer)
## [1] 200   5

Output yang diharapkan: 200 observasi dan 5 peubah.


3.3 Nama peubah

names(customer)
## [1] "CustomerID"    "Gender"        "Age"           "AnnualIncome" 
## [5] "SpendingScore"

3.4 Struktur data

str(customer)
## '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 ...

Hal yang perlu diperhatikan:

  • jumlah observasi;
  • jumlah peubah;
  • tipe data setiap peubah.

Tipe penyimpanan data tidak selalu sama dengan makna analitis peubah. Sebuah ID dapat disimpan sebagai integer, tetapi tidak berarti ID tersebut harus diperlakukan sebagai peubah numerik untuk analisis.


3.5 Ringkasan statistik

summary(customer)
##    CustomerID        Gender               Age         AnnualIncome   
##  Min.   :  1.00   Length:200         Min.   :18.00   Min.   : 15.00  
##  1st Qu.: 50.75   Class :character   1st Qu.:28.75   1st Qu.: 41.50  
##  Median :100.50   Mode  :character   Median :36.00   Median : 61.50  
##  Mean   :100.50                      Mean   :38.85   Mean   : 60.56  
##  3rd Qu.:150.25                      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

Dari summary() kita dapat melihat informasi awal seperti:

  • minimum;
  • kuartil pertama;
  • median;
  • rata-rata;
  • kuartil ketiga;
  • maksimum.

Pertanyaan:

Apakah angka-angka tersebut sudah cukup untuk mengetahui bentuk distribusi data?

Belum. Untuk itu kita memerlukan visualisasi.


4 Eksplorasi Kualitas Data

Sebelum membuat analisis lebih lanjut, kita perlu memastikan kondisi dasar dataset.

4.1 Missing value

colSums(is.na(customer))
##    CustomerID        Gender           Age  AnnualIncome SpendingScore 
##             0             0             0             0             0

Total missing value:

sum(is.na(customer))
## [1] 0

Interpretasi yang diharapkan: dataset ini tidak memiliki missing value.

Jika suatu dataset memiliki missing value, jangan langsung menghapusnya. Kita perlu mempertimbangkan jumlah, proporsi, pola missing, variabel yang terdampak, dan tujuan analisis.


4.2 Data duplikat

sum(duplicated(customer))
## [1] 0

Interpretasi yang diharapkan: tidak terdapat baris yang terduplikasi secara keseluruhan.


5 Eksplorasi Univariate

Eksplorasi univariate mempelajari satu peubah untuk memahami distribusi atau karakteristiknya.

Kita akan memfokuskan eksplorasi numerik pada:

  • Age;
  • AnnualIncome;
  • SpendingScore.

CustomerID tidak dimasukkan karena hanya berfungsi sebagai identifier.

5.1 Menyiapkan data numerik

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

6 Histogram

Histogram digunakan untuk melihat:

  • bentuk distribusi;
  • rentang nilai;
  • konsentrasi observasi;
  • kemungkinan kemencengan (skewness);
  • kemungkinan adanya beberapa kelompok nilai.
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()

6.1 Pertanyaan interpretasi

  1. Apakah ketiga peubah memiliki bentuk distribusi yang sama?
  2. Di bagian mana observasi paling banyak terkonsentrasi?
  3. Apakah ada nilai yang terlihat jauh dari sebagian besar observasi?

7 Boxplot

Boxplot memberikan ringkasan visual mengenai:

  • median;
  • kuartil;
  • rentang antarkuartil (interquartile range/IQR);
  • penyebaran data;
  • kandidat pencilan.
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()

Pertanyaan:

Peubah mana yang tampak memiliki kandidat pencilan?


8 Density Plot

Density plot memberikan representasi distribusi yang lebih halus dibandingkan histogram.

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()

Histogram dan density plot sama-sama membantu memahami distribusi. Perbedaannya terutama terletak pada cara distribusi tersebut direpresentasikan.


9 Eksplorasi Peubah Kategorik (Opsional)

Untuk peubah kategorik seperti Gender, salah satu visualisasi sederhana adalah bar chart.

ggplot(
  customer,
  aes(
    x = Gender,
    fill = Gender
  )
) +
  geom_bar() +
  labs(
    title = "Jumlah Pelanggan Berdasarkan Gender",
    x = "Gender",
    y = "Jumlah Pelanggan"
  ) +
  guides(fill = "none") +
  theme_minimal()


10 Perbandingan Antar Kelompok

Sekarang pertanyaannya berubah dari:

Bagaimana distribusi Spending Score?

menjadi:

Apakah Spending Score berbeda antara kelompok Gender?

10.1 Statistik ringkasan

customer %>%
  group_by(Gender) %>%
  summarise(
    Jumlah = n(),
    Rata_rata = mean(SpendingScore),
    Median = median(SpendingScore),
    SD = sd(SpendingScore),
    .groups = "drop"
  )
## # 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

Hal yang perlu diperhatikan:

  • jumlah pelanggan setiap kelompok;
  • rata-rata;
  • median;
  • standar deviasi.

Perbedaan rata-rata saja belum cukup untuk menyimpulkan bahwa dua kelompok benar-benar memiliki pola yang berbeda. Kita juga perlu melihat distribusinya.


10.2 Boxplot antar kelompok

ggplot(
  customer,
  aes(
    x = Gender,
    y = SpendingScore,
    fill = Gender
  )
) +
  geom_boxplot() +
  labs(
    title = "Spending Score Berdasarkan Gender",
    x = "Gender",
    y = "Spending Score"
  ) +
  guides(fill = "none") +
  theme_minimal()

10.3 Pertanyaan interpretasi

  1. Bagaimana posisi median kedua kelompok?
  2. Bagaimana penyebaran Spending Score pada kedua kelompok?
  3. Apakah perbedaan visualnya tampak besar atau kecil?

11 Deteksi Kandidat Outlier dengan IQR

Boxplot menggunakan konsep IQR untuk membantu mengidentifikasi kandidat pencilan.

Kita gunakan AnnualIncome.

11.1 Lihat boxplot

ggplot(
  customer,
  aes(y = AnnualIncome)
) +
  geom_boxplot(
    fill = "lightblue"
  ) +
  labs(
    title = "Outlier Detection pada Annual Income",
    x = NULL,
    y = "Annual Income"
  ) +
  theme_minimal()

11.2 Menghitung batas IQR

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

Q1
##  25% 
## 41.5
Q3
## 75% 
##  78
IQR_income
## [1] 36.5
batas_bawah
##    25% 
## -13.25
batas_atas
##    75% 
## 132.75

Batas yang diharapkan:

  • batas bawah = -13.25;
  • batas atas = 132.75.

11.3 Menampilkan kandidat outlier

customer %>%
  filter(
    AnnualIncome < batas_bawah |
    AnnualIncome > batas_atas
  )
##   CustomerID Gender Age AnnualIncome SpendingScore
## 1        199   Male  32          137            18
## 2        200   Male  30          137            83

Dataset ini menghasilkan dua kandidat pencilan pada AnnualIncome = 137.

Penting: outlier tidak otomatis berarti data salah. Pencilan harus diperiksa berdasarkan konteks, proses pengumpulan data, dan tujuan analisis sebelum diputuskan untuk dipertahankan, ditransformasi, atau dikeluarkan.


12 Eksplorasi Bivariate

Eksplorasi bivariate mempelajari dua peubah secara bersamaan.

Pertanyaan kita:

Apakah pelanggan dengan Annual Income yang lebih tinggi cenderung memiliki Spending Score yang lebih tinggi?

12.1 Scatterplot

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()

12.2 Pertanyaan interpretasi

  1. Apakah terlihat hubungan linear positif?
  2. Apakah terlihat hubungan linear negatif?
  3. Apakah titik-titik membentuk pola atau kelompok tertentu?
  4. Apakah ada observasi yang tampak jauh dari observasi lain?

13 Korelasi

Koefisien korelasi Pearson digunakan untuk mengukur hubungan linear antara dua peubah numerik.

cor(
  customer$AnnualIncome,
  customer$SpendingScore
)
## [1] 0.009902848

Nilai yang diharapkan sekitar:

0.0099

Nilai tersebut sangat dekat dengan nol.

Interpretasi yang tepat:

Tidak terlihat hubungan linear yang kuat antara AnnualIncome dan SpendingScore.

Hindari pernyataan:

“Tidak ada hubungan sama sekali.”

Koefisien korelasi yang mendekati nol hanya menunjukkan bahwa hubungan linear lemah. Scatterplot tetap diperlukan untuk memeriksa bentuk pola data.


14 Marked Scatterplot (Opsional)

Kita dapat menambahkan informasi kelompok ke dalam scatterplot.

ggplot(
  customer,
  aes(
    x = AnnualIncome,
    y = SpendingScore,
    color = Gender,
    shape = Gender
  )
) +
  geom_point(
    size = 2.5,
    alpha = 0.8
  ) +
  labs(
    title = "Annual Income dan Spending Score Berdasarkan Gender",
    x = "Annual Income",
    y = "Spending Score"
  ) +
  theme_minimal()

Pertanyaan:

Apakah penambahan informasi Gender membantu kita menemukan pola tambahan?

Menambahkan lebih banyak estetika tidak selalu membuat grafik lebih baik. Gunakan warna, bentuk, atau ukuran hanya jika membantu menjawab pertanyaan analisis.


15 Mini Challenge

Tanpa melihat kode, tentukan visualisasi yang menurut kalian paling tepat.

15.0.1 Pertanyaan 1

Bagaimana distribusi umur pelanggan?

Pilihan yang masuk akal: histogram atau density plot.

15.0.2 Pertanyaan 2

Apakah terdapat Annual Income yang ekstrem?

Pilihan yang masuk akal: boxplot.

15.0.3 Pertanyaan 3

Apakah Spending Score berbeda berdasarkan Gender?

Pilihan yang masuk akal: boxplot antar kelompok.

15.0.4 Pertanyaan 4

Apakah Annual Income berhubungan dengan Spending Score?

Pilihan yang masuk akal: scatterplot.

15.0.5 Pertanyaan 5

Berapa jumlah pelanggan Male dan Female?

Pilihan yang masuk akal: bar chart.


16 Recap

EDA pada pertemuan ini dapat diringkas sebagai:

DATA
 │
 ├── Kenali Struktur
 │   ├── dim()
 │   ├── names()
 │   ├── str()
 │   └── summary()
 │
 ├── Periksa Kualitas
 │   ├── Missing value
 │   └── Duplicate
 │
 ├── Univariate
 │   ├── Histogram
 │   ├── Boxplot
 │   └── Density plot
 │
 ├── Perbandingan Antar Kelompok
 │   ├── Statistik ringkasan
 │   └── Boxplot
 │
 └── Bivariate
     ├── Scatterplot
     └── Correlation

Prinsip utama:

Jangan berhenti ketika grafik berhasil dibuat. Tanyakan: grafik ini memberi tahu kita apa tentang data?


17 Tugas Pertemuan 4

Gunakan dataset hasil pengumpulan/web scraping kelompok masing-masing.

17.1 Eksplorasi awal

Minimal tampilkan:

dim(data)
names(data)
str(data)
summary(data)

colSums(is.na(data))
sum(duplicated(data))

17.2 Visualisasi

Buat minimal 3 visualisasi yang relevan dengan karakteristik dataset.

Tidak semua kelompok harus menggunakan jenis grafik yang sama.

Panduan:

Kondisi/Pertanyaan Visualisasi yang dapat digunakan
Distribusi satu peubah numerik Histogram, density, boxplot
Frekuensi satu peubah kategorik Bar chart
Numerik dibandingkan antar kategori Boxplot antar kelompok
Hubungan dua peubah numerik Scatterplot
Perubahan nilai menurut waktu Line plot
Proporsi beberapa kategori Bar chart / pie chart
Data teks Word frequency / word cloud jika relevan

17.3 Interpretasi

Di bawah setiap visualisasi, tuliskan 2–3 kalimat yang menjelaskan:

  1. pola utama yang terlihat;
  2. nilai atau kelompok yang menarik;
  3. insight atau pertanyaan lanjutan yang muncul.

Interpretasikan data, bukan dekorasi grafik.

Contoh yang kurang tepat:

“Grafik di atas menggunakan warna biru dan memiliki beberapa batang.”

Contoh yang lebih tepat:

“Sebagian besar observasi terkonsentrasi pada rentang tertentu, sedangkan hanya sedikit observasi berada pada nilai yang sangat tinggi. Pola ini menunjukkan distribusi yang tidak simetris dan perlu diperiksa lebih lanjut.”

17.4 Kesimpulan EDA

Tuliskan 3 temuan utama dari hasil eksplorasi dataset kelompok.

17.5 Format pengumpulan

Kumpulkan satu file ZIP dengan struktur:

Kelompok_X_Tugas4.zip
│
├── Kelompok_X_Tugas4.Rmd
├── Kelompok_X_Tugas4.html
├── data.csv
└── script.R          # opsional jika kode sudah lengkap di Rmd

Minimal isi laporan HTML:

  1. Identitas kelompok
  2. Deskripsi singkat data
  3. Struktur data
  4. Kualitas data
  5. Visualisasi 1 + interpretasi
  6. Visualisasi 2 + interpretasi
  7. Visualisasi 3 + interpretasi
  8. Kesimpulan eksplorasi

18 Penutup

Pada pertemuan ini fokus utama bukan menghafal syntax ggplot2, tetapi belajar menentukan:

Apa pertanyaannya? → Data apa yang dibutuhkan? → Visualisasi apa yang sesuai? → Apa interpretasinya?