CASE PROJECT DATA REDUCTION
Eksplorasi dan Visualisasi Data Kelompok 2
1 Deskripsi Dataset
1.1 Sumber dan Konteks Data
Dataset California Housing Prices tersedia secara publik di Kaggle, diunggah oleh Cam Nugent dan dapat diakses di: https://www.kaggle.com/datasets/camnugent/california-housing-prices. Dataset ini bersumber dari Sensus California tahun 1990 dan dipopulerkan oleh Aur©lien G©ron dalam buku “Hands-On Machine Learning with Scikit-Learn and TensorFlow” sebagai dataset standar untuk pengenalan machine learning.
Setiap baris dalam dataset merepresentasikan satu blok sensus
(census block group), unit geografis terkecil yang
dipublikasikan oleh U.S. Census Bureau, dengan populasi sekitar 600
hingga 3.000 jiwa per blok. Karena unit observasi adalah blok (bukan
individu rumah), variabel seperti total_rooms dan
population mencerminkan nilai agregat seluruh blok, bukan
per rumah.
1.2 Input Data
library(tidyverse)
library(corrplot)
library(ggcorrplot)
library(car)
library(kableExtra)
library(gridExtra)
library(scales)
library(RColorBrewer)
library(viridis)
library(glmnet)
library(factoextra)
df <- read.csv("~/Downloads/housing.csv", stringsAsFactors = TRUE)
cat("Dimensi dataset:", nrow(df), "baris x", ncol(df), "kolom\n")Dimensi dataset: 20640 baris x 10 kolom
Dataset ini terdiri dari 20.640 observasi dan 10 variabel, dengan rincian 9 variabel bertipe numerik dan 1 variabel bertipe variabel bertipe kategorik.
kesembilan variabel numerik tersebut meliputi informasi geografis
(longitude, latitude), karakteristik hunian
(housing_median_age, total_rooms,
total_bedrooms), data demografis (population,
households), dan informasi ekonomi
(median_income, median_house_value). Serta 1
variabel kategorik yaitu ocean_proximity.
Berikut ini adalah kamus dari kesepuluh variabel yang memuat tipe, satuan, serta deskripsi dari masing-masing variabel.
var_df <- data.frame(
No = 1:10,
Variabel = c("longitude","latitude","housing_median_age",
"total_rooms","total_bedrooms","population",
"households","median_income","median_house_value",
"ocean_proximity"),
Tipe = c(rep("Numerik",9),"Kategorik"),
Satuan = c("Derajat","Derajat","Tahun","Kamar","Kamar",
"Jiwa","Rumah Tangga","$10.000","USD","Kategori"),
Deskripsi = c(
"Koordinat bujur (semakin tinggi = semakin timur)",
"Koordinat lintang (semakin tinggi = semakin utara)",
"Median usia bangunan dalam satu blok",
"Total jumlah kamar seluruh rumah dalam satu blok",
"Total jumlah kamar tidur seluruh rumah dalam satu blok",
"Total populasi penduduk dalam satu blok",
"Jumlah rumah tangga dalam satu blok",
"Median pendapatan rumah tangga (dalam puluhan ribu USD)",
"[TARGET] Median nilai rumah dalam satu blok (USD)",
"Kategori kedekatan lokasi dengan laut (5 kategori)"
)
)
kable(var_df, caption = "Kamus Variabel California Housing Dataset") %>%
kable_styling(bootstrap_options = c("striped","hover","condensed","responsive"),
full_width = TRUE) %>%
row_spec(9, bold = TRUE, background = "#fcf8e3") %>%
row_spec(0, bold = TRUE)| No | Variabel | Tipe | Satuan | Deskripsi |
|---|---|---|---|---|
| 1 | longitude | Numerik | Derajat | Koordinat bujur (semakin tinggi = semakin timur) |
| 2 | latitude | Numerik | Derajat | Koordinat lintang (semakin tinggi = semakin utara) |
| 3 | housing_median_age | Numerik | Tahun | Median usia bangunan dalam satu blok |
| 4 | total_rooms | Numerik | Kamar | Total jumlah kamar seluruh rumah dalam satu blok |
| 5 | total_bedrooms | Numerik | Kamar | Total jumlah kamar tidur seluruh rumah dalam satu blok |
| 6 | population | Numerik | Jiwa | Total populasi penduduk dalam satu blok |
| 7 | households | Numerik | Rumah Tangga | Jumlah rumah tangga dalam satu blok |
| 8 | median_income | Numerik | $10.000 | Median pendapatan rumah tangga (dalam puluhan ribu USD) |
| 9 | median_house_value | Numerik | USD | [TARGET] Median nilai rumah dalam satu blok (USD) |
| 10 | ocean_proximity | Kategorik | Kategori | Kategori kedekatan lokasi dengan laut (5 kategori) |
1.3 Tujuan Analisis
Project data reduction ini memiliki tujuan analisis sebagai berikut. 1. Memahami karakteristik dan kualitas data perumahan California melalui eksplorasi dan visualisasi data. 2. Membentuk fitur-fitur baru yang lebih informatif dan bermakna secara substantif melalui proses feature engineering. 3. Mengidentifikasi variabel-variabel paling relevan terhadap harga rumah dan mengeliminasi variabel yang redundan melalui feature selection. 4. Menyederhanakan dimensi data melalui PCA dan mengevaluasi keberhasilan reduksi dimensi berdasarkan proporsi variansi yang terjelaskan. 5. Menginterpretasikan makna substantif dari setiap principal component yang terbentuk dalam konteks pasar perumahan California. 6. Menghasilkan insight menyeluruh mengenai faktor-faktor utama yang paling menentukan harga rumah di California.
2 Exploratory Data Analysis (EDA)
2.1 Tampilan Awal Data
Rows: 20,640
Columns: 10
$ longitude <dbl> -122.23, -122.22, -122.24, -122.25, -122.25, -122.2…
$ latitude <dbl> 37.88, 37.86, 37.85, 37.85, 37.85, 37.85, 37.84, 37…
$ housing_median_age <dbl> 41, 21, 52, 52, 52, 52, 52, 52, 42, 52, 52, 52, 52,…
$ total_rooms <dbl> 880, 7099, 1467, 1274, 1627, 919, 2535, 3104, 2555,…
$ total_bedrooms <dbl> 129, 1106, 190, 235, 280, 213, 489, 687, 665, 707, …
$ population <dbl> 322, 2401, 496, 558, 565, 413, 1094, 1157, 1206, 15…
$ households <dbl> 126, 1138, 177, 219, 259, 193, 514, 647, 595, 714, …
$ median_income <dbl> 8.3252, 8.3014, 7.2574, 5.6431, 3.8462, 4.0368, 3.6…
$ median_house_value <dbl> 452600, 358500, 352100, 341300, 342200, 269700, 299…
$ ocean_proximity <fct> NEAR BAY, NEAR BAY, NEAR BAY, NEAR BAY, NEAR BAY, N…
Berdasarkan output fungsi glimpse(), dataset California
Housing terdiri atas 20.640 observasi dan 10
variabel. Sebagian besar variabel bertipe numerik
(<dbl>), yaitu longitude,
latitude, housing_median_age,
total_rooms, total_bedrooms,
population, households,
median_income, dan median_house_value. Selain
itu, terdapat satu variabel kategorik yaitu ocean_proximity
yang bertipe faktor (<fct>). Struktur data tersebut
menunjukkan bahwa dataset didominasi oleh variabel kuantitatif yang
dapat dianalisis lebih lanjut menggunakan berbagai metode statistik dan
reduksi dimensi.
Tampilan 10 observasi pertama melalui fungsi head()
menunjukkan bahwa seluruh pengamatan awal termasuk dalam kategori
NEAR BAY. Nilai median_house_value pada
observasi tersebut berkisar antara $226.700 hingga
$452.600, yang mengindikasikan adanya variasi harga rumah
meskipun berada pada kategori lokasi yang sama. Selain itu, nilai
median_income juga menunjukkan keragaman yang cukup besar
antarwilayah. Secara awal terlihat bahwa wilayah dengan pendapatan
median yang lebih tinggi cenderung memiliki nilai rumah yang lebih
tinggi. Temuan ini mengindikasikan bahwa faktor lokasi geografis dan
tingkat pendapatan kemungkinan berkontribusi terhadap variasi harga
rumah, sehingga perlu dieksplorasi lebih lanjut pada tahap analisis
berikutnya.
2.2 Statistik Deskriptif
2.2.1 Variabel Numerik
longitude latitude housing_median_age total_rooms
Min. :-124.3 Min. :32.54 Min. : 1.00 Min. : 2
1st Qu.:-121.8 1st Qu.:33.93 1st Qu.:18.00 1st Qu.: 1448
Median :-118.5 Median :34.26 Median :29.00 Median : 2127
Mean :-119.6 Mean :35.63 Mean :28.64 Mean : 2636
3rd Qu.:-118.0 3rd Qu.:37.71 3rd Qu.:37.00 3rd Qu.: 3148
Max. :-114.3 Max. :41.95 Max. :52.00 Max. :39320
total_bedrooms population households median_income
Min. : 1.0 Min. : 3 Min. : 1.0 Min. : 0.4999
1st Qu.: 296.0 1st Qu.: 787 1st Qu.: 280.0 1st Qu.: 2.5634
Median : 435.0 Median : 1166 Median : 409.0 Median : 3.5348
Mean : 537.9 Mean : 1425 Mean : 499.5 Mean : 3.8707
3rd Qu.: 647.0 3rd Qu.: 1725 3rd Qu.: 605.0 3rd Qu.: 4.7432
Max. :6445.0 Max. :35682 Max. :6082.0 Max. :15.0001
NA's :207
median_house_value
Min. : 14999
1st Qu.:119600
Median :179700
Mean :206856
3rd Qu.:264725
Max. :500001
desc_table <- num_vars %>%
summarise(across(everything(), list(
N = ~sum(!is.na(.)),
Mean = ~round(mean(., na.rm = TRUE), 2),
Median = ~round(median(., na.rm = TRUE), 2),
SD = ~round(sd(., na.rm = TRUE), 2),
Min = ~round(min(., na.rm = TRUE), 2),
Max = ~round(max(., na.rm = TRUE), 2),
Skewness = ~round(mean(((. - mean(.,na.rm=T))/sd(.,na.rm=T))^3,na.rm=T),3)
))) %>%
pivot_longer(everything(),
names_to = c("Variabel",".value"),
names_sep = "_(?=[^_]+$)") %>%
arrange(desc(abs(Skewness)))
kable(desc_table,
caption = "Statistik Deskriptif Variabel Numerik",
format.args = list(big.mark = ",")) %>%
kable_styling(bootstrap_options = c("striped","hover","condensed"),
full_width = TRUE) %>%
column_spec(1, bold = TRUE) %>%
column_spec(8, bold = TRUE,
color = ifelse(abs(desc_table$Skewness) > 1, "red", "darkgreen")) %>%
row_spec(0, bold = TRUE)| Variabel | N | Mean | Median | SD | Min | Max | Skewness |
|---|---|---|---|---|---|---|---|
| population | 20,640 | 1,425.48 | 1,166.00 | 1,132.46 | 3.00 | 35,682.00 | 4.935 |
| total_rooms | 20,640 | 2,635.76 | 2,127.00 | 2,181.62 | 2.00 | 39,320.00 | 4.147 |
| total_bedrooms | 20,433 | 537.87 | 435.00 | 421.39 | 1.00 | 6,445.00 | 3.459 |
| households | 20,640 | 499.54 | 409.00 | 382.33 | 1.00 | 6,082.00 | 3.410 |
| median_income | 20,640 | 3.87 | 3.53 | 1.90 | 0.50 | 15.00 | 1.646 |
| median_house_value | 20,640 | 206,855.82 | 179,700.00 | 115,395.62 | 14,999.00 | 500,001.00 | 0.978 |
| latitude | 20,640 | 35.63 | 34.26 | 2.14 | 32.54 | 41.95 | 0.466 |
| longitude | 20,640 | -119.57 | -118.49 | 2.00 | -124.35 | -114.31 | -0.298 |
| housing_median_age | 20,640 | 28.64 | 29.00 | 12.59 | 1.00 | 52.00 | 0.060 |
Berdasarkan statistik deskriptif yang diperoleh, variabel
population memiliki nilai skewness tertinggi (4,935),
menunjukkan distribusi yang sangat menceng ke kanan (strong positive
skewness). Hal ini terlihat dari rata-rata (1.425,48) yang lebih
besar daripada median (1.166), serta adanya nilai maksimum yang sangat
tinggi (35.682). Kondisi tersebut mengindikasikan bahwa sebagian besar
blok sensus memiliki jumlah penduduk relatif rendah hingga sedang,
tetapi terdapat beberapa blok dengan jumlah penduduk yang sangat besar
sehingga menarik distribusi ke arah kanan.
Variabel total_rooms, total_bedrooms, dan
households juga menunjukkan skewness positif yang tinggi,
masing-masing sebesar 4,147; 3,459; dan 3,410. Nilai rata-rata ketiga
variabel tersebut lebih besar daripada mediannya, yang mengindikasikan
bahwa sebagian besar blok sensus memiliki jumlah ruangan, kamar tidur,
dan rumah tangga yang relatif moderat, namun terdapat sejumlah kecil
blok dengan ukuran yang sangat besar sehingga menyebabkan distribusi
tidak simetris. Selain itu, variabel total_bedrooms
memiliki 207 nilai hilang (missing values) yang perlu ditangani
sebelum dilakukan analisis lanjutan.
Variabel median_income memiliki skewness positif sedang
(1,646), yang menunjukkan distribusi masih cenderung menceng ke kanan.
Nilai median sebesar 3,53 berarti pendapatan median rumah tangga sekitar
US$35.300 per tahun karena variabel ini dinyatakan dalam satuan puluhan
ribu dolar Amerika. Adanya perbedaan antara rata-rata (3,87) dan median
(3,53) menunjukkan bahwa terdapat sejumlah wilayah dengan tingkat
pendapatan yang jauh lebih tinggi dibandingkan mayoritas wilayah
lainnya.
Sementara itu, variabel geografis latitude dan
longitude memiliki nilai skewness yang relatif kecil,
masing-masing sebesar 0,466 dan -0,298. Hal ini menunjukkan bahwa
distribusi kedua variabel cenderung mendekati simetris meskipun terdapat
sedikit kecenderungan ke kanan pada latitude dan ke kiri
pada longitude. Rentang nilai yang cukup luas pada kedua
variabel tersebut mencerminkan cakupan wilayah pengamatan yang tersebar
di berbagai lokasi di negara bagian California.
Variabel housing_median_age memiliki skewness yang
sangat dekat dengan nol (0,060), sehingga distribusinya dapat dianggap
hampir simetris. Hal ini juga didukung oleh nilai mean (28,64) dan
median (29,00) yang hampir sama. Dengan demikian, usia median rumah pada
dataset ini relatif tersebar secara seimbang di sekitar nilai
tengahnya.
Sebagai variabel target, median_house_value memiliki
skewness positif sebesar 0,978. Nilai rata-rata (US$206.856) yang lebih
tinggi daripada median (US$179.700) menunjukkan adanya kecenderungan
distribusi ke arah kanan akibat keberadaan rumah-rumah bernilai tinggi.
Namun, perlu diperhatikan bahwa nilai maksimum sebesar US$500.001
mengindikasikan adanya censoring atau batas atas pada data asli
California Housing, sehingga distribusi harga rumah kemungkinan
terpotong pada nilai maksimum tersebut.
Secara keseluruhan, sebagian besar variabel yang berkaitan dengan ukuran dan karakteristik blok sensus menunjukkan distribusi yang tidak simetris dengan kecenderungan menceng ke kanan. Kondisi ini mengindikasikan adanya beberapa observasi bernilai sangat besar yang berpotensi memengaruhi analisis. Oleh karena itu, tahap prapengolahan data seperti penanganan nilai hilang, standarisasi variabel, dan eksplorasi lebih lanjut terhadap pencilan perlu dilakukan sebelum menerapkan teknik reduksi dimensi.
2.2.2 Variabel Kategorik
ocean_tbl <- df %>%
count(ocean_proximity) %>%
mutate(Persentase = paste0(round(n/sum(n)*100, 1), "%"),
Rata_Harga = dollar(round(tapply(df$median_house_value,
df$ocean_proximity, mean)[ocean_proximity], 0))) %>%
rename(Kategori = ocean_proximity, Frekuensi = n)
kable(ocean_tbl, caption = "Distribusi Frekuensi dan Rata-rata Harga per Kategori") %>%
kable_styling(bootstrap_options = c("striped","hover"),
full_width = FALSE, position = "center") %>%
row_spec(0, bold = TRUE) %>%
column_spec(1, bold = TRUE)| Kategori | Frekuensi | Persentase | Rata_Harga |
|---|---|---|---|
| <1H OCEAN | 9136 | 44.3% | $240,084 |
| INLAND | 6551 | 31.7% | $124,805 |
| ISLAND | 5 | 0% | $380,440 |
| NEAR BAY | 2290 | 11.1% | $259,212 |
| NEAR OCEAN | 2658 | 12.9% | $249,434 |
Berdasarkan statistik deskriptif yang diperoleh, Kategori <1H OCEAN (kurang dari 1 jam dari laut) mendominasi dataset dengan 9.136 blok sensus atau sekitar 44,3% dari total observasi. Kategori INLAND menempati urutan kedua dengan 6.551 blok (31,7%), diikuti oleh NEAR OCEAN (12,9%) dan NEAR BAY (11,1%). Sementara itu, kategori ISLAND hanya memiliki 5 observasi sehingga representasinya sangat terbatas dan hasil yang diperoleh pada kategori ini perlu ditafsirkan dengan hati-hati.
Berdasarkan rata-rata harga rumah, terlihat bahwa wilayah yang berdekatan dengan perairan cenderung memiliki nilai rumah yang lebih tinggi dibandingkan wilayah INLAND. Kategori INLAND memiliki rata-rata harga rumah terendah, yaitu sebesar US$124.805. Sebaliknya, kategori NEAR BAY memiliki rata-rata harga tertinggi di antara kategori dengan jumlah observasi yang memadai, yaitu sebesar US$259.212, diikuti oleh NEAR OCEAN (US$249.434) dan <1H OCEAN (US$240.084). Meskipun kategori ISLAND memiliki rata-rata harga rumah tertinggi (US$380.440), jumlah observasinya yang sangat sedikit menyebabkan nilai tersebut kurang representatif untuk menggambarkan kondisi populasi secara umum.
Temuan ini menunjukkan bahwa lokasi geografis, khususnya kedekatan dengan wilayah perairan, berpotensi menjadi faktor penting yang memengaruhi nilai rumah di California. Oleh karena itu, variabel ocean_proximity layak dipertimbangkan sebagai salah satu variabel yang berkontribusi dalam menjelaskan variasi harga rumah pada dataset ini.
2.3 Distribusi Variabel
2.3.1 Histogram Semua Variabel
num_long <- num_vars %>%
pivot_longer(everything(), names_to = "Variabel", values_to = "Nilai")
ggplot(num_long, aes(x = Nilai, fill = Variabel)) +
geom_histogram(bins = 40, color = "white", alpha = 0.85) +
facet_wrap(~Variabel, scales = "free", ncol = 3) +
scale_fill_viridis_d(option = "D") +
scale_x_continuous(labels = comma) +
scale_y_continuous(labels = comma) +
labs(
title = "Distribusi Setiap Variabel Numerik",
subtitle = "California Housing Dataset",
x = NULL, y = "Frekuensi"
) +
theme_bw(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 15),
strip.text = element_text(face = "bold"),
legend.position = "none",
panel.grid.minor = element_blank()
)Berdasarkan histrogram di atas, didapatkan interpretasi sebagai berikut.
housing_median_age: Distribusi paling mendekati seragam (uniform) di antara semua variabel, dengan sebaran yang relatif merata antara 1 hingga 52 tahun. Nilai skewness yang sangat kecil (0,06) menunjukkan bahwa distribusi variabel ini hampir simetris. Selain itu, terlihat beberapa puncak frekuensi pada rentang umur tertentu, terutama di sekitar 35???37 tahun dan mendekati 52 tahun, yang menunjukkan adanya konsentrasi observasi pada kelompok umur tersebut.total_rooms: Distribusi sangat menceng ke kanan (strong positive skewness) dengan nilai skewness sebesar 4,15. Sebagian besar blok sensus memiliki total kamar antara 1.000 sampai 5.000, namun terdapat ekor distribusi yang panjang hingga mencapai 39.320 kamar. Perbedaan antara median (2.127) dan mean (2.636) juga mengonfirmasi adanya pengaruh observasi bernilai sangat besar.total_bedrooms: Menunjukkan pola yang serupa dengantotal_rooms(skewness = 3,46), yaitu distribusi yang menceng ke kanan dengan median 435 kamar tidur dan nilai maksimum mencapai 6.445 kamar tidur. Pola ini konsisten karenatotal_bedroomsmerupakan bagian daritotal_rooms.population: Merupakan variabel dengan distribusi paling menceng ke kanan (skewness = 4,94). Sebagian besar blok sensus memiliki populasi sekitar 500 sampai 2.500 jiwa, namun terdapat beberapa blok dengan populasi yang sangat besar hingga mencapai 35.682 jiwa. Kehadiran observasi-observasi ekstrem tersebut menyebabkan terbentuknya ekor distribusi yang panjang di sisi kanan.households: Memiliki pola distribusi yang mirip denganpopulation(skewness = 3,41), yang menunjukkan bahwa sebagian besar blok sensus memiliki jumlah rumah tangga relatif rendah hingga sedang, namun terdapat sejumlah kecil blok dengan jumlah rumah tangga yang sangat besar. Hal ini mengindikasikan adanya variasi ukuran blok sensus yang cukup tinggi.median_income: Menunjukkan skewness positif yang cukup kuat (skewness = 1,65), sehingga distribusinya masih cenderung menceng ke kanan dan belum dapat dianggap normal. Sebagian besar observasi terkonsentrasi pada tingkat pendapatan menengah, dengan sejumlah kecil wilayah yang memiliki pendapatan jauh lebih tinggi dibandingkan mayoritas wilayah lainnya. Selain itu, terlihat adanya penumpukan kecil pada nilai maksimum 15,0 yang mengindikasikan adanya batas atas (capping) pada data asli.median_house_value: Memiliki distribusi menceng ke kanan dengan skewness moderat (0,98). Sebagian besar nilai rumah berada pada kisaran US$100.000???US$300.000, namun masih terdapat sejumlah rumah dengan nilai yang jauh lebih tinggi. Terlihat pula lonjakan frekuensi yang cukup jelas pada nilai maksimum US$500.001 yang menunjukkan adanya capping atau batas atas pada data asli. Kondisi ini perlu diperhatikan dalam analisis lanjutan karena dapat memengaruhi hasil pemodelan.longitudedanlatitude: Kedua variabel geografis ini menunjukkan pola distribusi yang berbeda dari variabel numerik lainnya. Distribusinya bersifat multimodal, ditandai dengan adanya beberapa puncak frekuensi yang mencerminkan konsentrasi observasi pada wilayah geografis tertentu di California. Pada variabellatitude, puncak utama terlihat di sekitar 34??° dan 37???38??°, yang menunjukkan wilayah dengan kepadatan observasi yang tinggi. Oleh karena itu, pola distribusi kedua variabel ini lebih merefleksikan karakteristik spasial daripada distribusi statistik konvensional.
2.3.2 Distribusi Variabel Target
ggplot(df, aes(x = median_house_value)) +
geom_histogram(bins = 50, fill = "#2c7fb8", color = "white", alpha = 0.85) +
geom_vline(xintercept = mean(df$median_house_value, na.rm=TRUE),
color = "red", linetype = "dashed", size = 1.2) +
geom_vline(xintercept = median(df$median_house_value, na.rm=TRUE),
color = "darkorange", linetype = "dashed", size = 1.2) +
annotate("text", x = mean(df$median_house_value)+15000, y = 1100,
label = paste0("Mean\n$", comma(round(mean(df$median_house_value)))),
color = "red", fontface = "bold", size = 3.5) +
annotate("text", x = median(df$median_house_value)-55000, y = 1100,
label = paste0("Median\n$", comma(round(median(df$median_house_value)))),
color = "darkorange", fontface = "bold", size = 3.5) +
scale_x_continuous(labels = dollar_format(prefix = "$", big.mark = ",")) +
scale_y_continuous(labels = comma) +
labs(
title = "Distribusi Median House Value (Variabel Target)",
subtitle = "Garis merah = Mean | Garis oranye = Median | Puncak di $500.001 = data ter-cap",
x = "Median House Value (USD)", y = "Frekuensi"
) +
theme_bw(base_size = 12) +
theme(plot.title = element_text(face = "bold", size = 14),
plot.subtitle = element_text(size = 10))Berdasarkan histogram di atas, dapat diinterpretasikan bahwa
distribusi median_house_value menunjukkan pola
right-skewed dengan nilai mean (US$206.856) yang lebih tinggi
daripada median (US$179.700), dengan selisih sekitar US$27.000. Kondisi
ini menunjukkan bahwa sebagian besar blok sensus memiliki harga rumah di
bawah rata-rata, sementara sejumlah kecil rumah dengan nilai sangat
tinggi menarik rata-rata ke arah kanan.
Selain itu, terlihat lonjakan frekuensi yang sangat mencolok pada nilai sekitar US$500.001 di ujung kanan histogram. Fenomena ini mengindikasikan adanya capping atau batas atas pada data asli California Housing, yaitu observasi dengan nilai rumah yang melebihi batas tertentu dicatat sebagai US$500.001. Berdasarkan data, terdapat sekitar 965 observasi (4,7% dari total data) yang berada pada nilai tersebut. Akibatnya, distribusi harga rumah pada kelompok bernilai tinggi tidak sepenuhnya tercerminkan dalam data dan berpotensi memengaruhi hasil analisis maupun pemodelan prediktif, khususnya pada segmen rumah dengan harga tinggi.
2.3.3 Distribusi Variabel Kategorik
p1 <- ggplot(df, aes(x = reorder(ocean_proximity, -table(ocean_proximity)[ocean_proximity]),
fill = ocean_proximity)) +
geom_bar(color = "white", alpha = 0.9, show.legend = FALSE) +
geom_text(stat = "count", aes(label = after_stat(count)), vjust = -0.4,
fontface = "bold", size = 3.8) +
scale_fill_brewer(palette = "Set2") +
scale_y_continuous(labels = comma, expand = expansion(mult = c(0, 0.1))) +
labs(title = "Jumlah Blok per Kategori", x = NULL, y = "Frekuensi") +
theme_bw(base_size = 11) +
theme(plot.title = element_text(face = "bold"),
axis.text.x = element_text(angle = 20, hjust = 1),
panel.grid.major.x = element_blank())
p2 <- ggplot(df, aes(x = reorder(ocean_proximity, median_house_value,
FUN = median),
y = median_house_value, fill = ocean_proximity)) +
geom_boxplot(alpha = 0.8, color = "gray30", show.legend = FALSE,
outlier.alpha = 0.2, outlier.size = 0.7) +
coord_flip() +
scale_fill_brewer(palette = "Set2") +
scale_y_continuous(labels = dollar_format(prefix = "$", big.mark = ",")) +
labs(title = "Distribusi Harga Rumah per Kategori",
subtitle = "Diurutkan berdasarkan median harga",
x = NULL, y = "Median House Value") +
theme_bw(base_size = 11) +
theme(plot.title = element_text(face = "bold"),
plot.subtitle = element_text(size = 9))
grid.arrange(p1, p2, ncol = 2)Berdasarkan visualisasi tersebut, dapat diinterpertasikan sebagai berikut.
Panel kiri (Frekuensi): Distribusi kategori
ocean_proximity tidak seimbang. Kategori <1H
OCEAN mendominasi dataset dengan 9.136 blok sensus (44,3%),
diikuti oleh INLAND sebanyak 6.551 blok (31,7%).
Sementara itu, kategori NEAR OCEAN dan NEAR
BAY masing-masing mencakup 12,9% dan 11,1% dari total
observasi. Kategori ISLAND hanya terdiri atas 5
observasi sehingga statistik yang dihasilkan pada kategori ini perlu
diinterpretasikan dengan sangat hati-hati karena kurang
representatif.
Panel kanan (Distribusi harga): Boxplot menunjukkan adanya perbedaan harga rumah yang cukup jelas antar kategori lokasi. Kategori INLAND memiliki median harga rumah terendah (sekitar US$108.500), sedangkan kategori NEAR BAY dan NEAR OCEAN memiliki median harga yang jauh lebih tinggi, masing-masing sekitar US$233.800 dan US$229.450. Kategori <1H OCEAN berada di antara keduanya dengan median sekitar US$214.850. Temuan ini mengindikasikan bahwa kedekatan terhadap wilayah perairan berkaitan dengan peningkatan nilai rumah.
Kategori ISLAND memiliki median harga tertinggi
(sekitar US$414.700), namun karena hanya terdiri atas 5 observasi, nilai
tersebut tidak dapat digeneralisasikan untuk keseluruhan populasi.
Selain itu, sebagian besar kategori menunjukkan keberadaan pencilan
(outlier) pada sisi atas distribusi, yang mengindikasikan
adanya sejumlah rumah dengan nilai jauh lebih tinggi dibandingkan
mayoritas rumah dalam kategori yang sama. Hal ini konsisten dengan hasil
analisis sebelumnya yang menunjukkan bahwa variabel
median_house_value memiliki distribusi yang menceng ke
kanan (right-skewed).
2.4 Missing Values
2.4.1 Tabel Missing Values
missing_df <- df %>%
summarise(across(everything(), ~sum(is.na(.)))) %>%
pivot_longer(everything(), names_to = "Variabel", values_to = "N_Missing") %>%
mutate(
Pct_Missing = round(N_Missing / nrow(df) * 100, 2),
Status = ifelse(N_Missing == 0, "Lengkap", "Ada Missing")
) %>%
arrange(desc(N_Missing))
kable(missing_df,
caption = "Rekap Missing Values Seluruh Variabel",
col.names = c("Variabel","Jumlah Missing","% Missing","Status")) %>%
kable_styling(bootstrap_options = c("striped","hover"),
full_width = FALSE, position = "center") %>%
row_spec(which(missing_df$N_Missing > 0), background = "#fcf8e3", bold = TRUE) %>%
row_spec(0, bold = TRUE)| Variabel | Jumlah Missing | % Missing | Status |
|---|---|---|---|
| total_bedrooms | 207 | 1 | Ada Missing |
| longitude | 0 | 0 | Lengkap |
| latitude | 0 | 0 | Lengkap |
| housing_median_age | 0 | 0 | Lengkap |
| total_rooms | 0 | 0 | Lengkap |
| population | 0 | 0 | Lengkap |
| households | 0 | 0 | Lengkap |
| median_income | 0 | 0 | Lengkap |
| median_house_value | 0 | 0 | Lengkap |
| ocean_proximity | 0 | 0 | Lengkap |
2.4.2 Visualisasi Missing Values
ggplot(missing_df, aes(x = reorder(Variabel, N_Missing), y = Pct_Missing,
fill = Status)) +
geom_col(width = 0.6, alpha = 0.85) +
geom_text(aes(label = ifelse(N_Missing > 0,
paste0(N_Missing, " data (", Pct_Missing, "%)"),
"Tidak ada")),
hjust = -0.05, size = 3.5, fontface = "bold") +
coord_flip(ylim = c(0, 3)) +
scale_fill_manual(values = c("Lengkap" = "#2ca25f", "Ada Missing" = "#e67e22")) +
scale_y_continuous(labels = function(x) paste0(x, "%")) +
labs(
title = "Persentase Missing Values per Variabel",
subtitle = "Hanya variabel total_bedrooms yang memiliki nilai hilang",
x = NULL, y = "Persentase Missing (%)", fill = "Status"
) +
theme_bw(base_size = 12) +
theme(plot.title = element_text(face = "bold", size = 14),
plot.subtitle = element_text(size = 10),
panel.grid.major.y = element_blank())Berdasarkan analisis missing values, secara keseluruhan, kualitas
data tergolong sangat baik. Dari 10 variabel, hanya satu variabel yang
memiliki missing values yaitu total_bedrooms dengan 207
nilai hilang (1,0% dari total 20.640 observasi). Jumlah ini tergolong
kecil dan tidak akan berdampak signifikan pada analisis. Penyebab paling
plausibel adalah ketidaklengkapan pencatatan pada beberapa blok di
dataset. Untuk penanganan, imputasi menggunakan median
atau menggunakan rasio
total_bedrooms/total_rooms dari blok-blok yang
datanya lengkap adalah pendekatan yang paling tepat untuk konteks
dataset ini, mengingat distribusinya yang right-skewed (imputasi mean
akan menghasilkan nilai yang bias).
2.5 Deteksi Outlier
2.5.1 Boxplot Outlier
box_vars <- c("housing_median_age","total_rooms","total_bedrooms",
"population","households","median_income","median_house_value")
box_long <- df %>%
select(all_of(box_vars)) %>%
pivot_longer(everything(), names_to = "Variabel", values_to = "Nilai")
ggplot(box_long, aes(x = Variabel, y = Nilai, fill = Variabel)) +
geom_boxplot(alpha = 0.75, color = "gray30",
outlier.color = "red", outlier.alpha = 0.2,
outlier.size = 0.7, width = 0.55) +
facet_wrap(~Variabel, scales = "free", ncol = 4) +
scale_fill_viridis_d(option = "C") +
scale_y_continuous(labels = comma) +
labs(
title = "Boxplot Deteksi Outlier",
subtitle = "Titik merah di luar whisker = outlier (lebih dari 1.5 ?? IQR dari Q1/Q3)",
x = NULL, y = "Nilai"
) +
theme_bw(base_size = 11) +
theme(
plot.title = element_text(face = "bold", size = 14),
plot.subtitle = element_text(size = 9),
strip.text = element_text(face = "bold"),
legend.position = "none",
axis.text.x = element_blank(),
axis.ticks.x = element_blank()
)Berdasarkan boxplot di atas, dapat diinterpretasikan sebagai berikut.
housing_median_age: Tidak terdapat outlier berdasarkan metode IQR (0% data berada di luar batas whisker). Dengan Q1 = 18 tahun dan Q3 = 37 tahun, seluruh observasi masih berada dalam rentang yang dianggap wajar menurut kriteria IQR. Variabel ini merupakan satu-satunya variabel numerik yang tidak memiliki outlier.total_rooms: Terdapat 1.287 outlier (6,2%) di atas batas atas IQR sebesar 5.698,38 kamar. Sebagian besar blok sensus memiliki jumlah kamar yang relatif rendah hingga sedang, namun terdapat sejumlah blok dengan jumlah kamar yang sangat besar hingga mencapai 39.320 kamar. Keberadaan observasi ekstrem ini menyebabkan distribusi menjadi sangat menceng ke kanan.total_bedrooms: Terdapat 1.271 outlier (6,2%) dengan batas atas IQR sebesar 1.173,50 kamar tidur. Nilai maksimum mencapai 6.445 kamar tidur, menunjukkan adanya sejumlah blok sensus dengan ukuran yang jauh lebih besar dibandingkan mayoritas observasi. Pola ini sejalan dengan distribusitotal_roomskarena kedua variabel menggambarkan karakteristik ukuran hunian.population: Memiliki 1.196 outlier (5,8%) dengan batas atas IQR sebesar 3.132 jiwa. Nilai maksimum yang mencapai 35.682 jiwa menunjukkan adanya beberapa blok sensus dengan kepadatan penduduk yang sangat tinggi dibandingkan mayoritas blok lainnya. Variabel ini juga merupakan salah satu variabel dengan tingkat skewness tertinggi dalam dataset.households: Terdapat 1.220 outlier (5,9%) di atas batas atas IQR sebesar 1.092,50 rumah tangga. Nilai maksimum mencapai 6.082 rumah tangga, yang menunjukkan adanya sejumlah blok sensus dengan jumlah rumah tangga yang jauh lebih besar dibandingkan sebagian besar observasi lainnya.median_income: Memiliki 681 outlier (3,3%), jumlah yang relatif lebih sedikit dibandingkan variabel agregat lainnya. Batas atas IQR sebesar 8,01 menunjukkan bahwa sebagian besar wilayah memiliki tingkat pendapatan yang tidak terlalu ekstrem, meskipun masih terdapat sejumlah wilayah dengan pendapatan yang jauh lebih tinggi dibandingkan mayoritas observasi.median_house_value: Terdapat 1.071 outlier (5,2%) berdasarkan metode IQR dengan batas atas sebesar US$482.412,50. Sebagian besar outlier berada di sekitar nilai maksimum US$500.001 yang merupakan batas atas (capping) pada data asli California Housing. Oleh karena itu, sebagian outlier pada variabel ini kemungkinan dipengaruhi oleh proses pembatasan nilai dalam dataset, sehingga interpretasinya perlu dilakukan dengan hati-hati.
Variabel longitude dan latitude tidak
disertakan dalam analisis outlier karena keduanya merupakan variabel
koordinat geografis. Nilai ekstrem pada kedua variabel tersebut
mencerminkan lokasi spasial yang valid, bukan pengamatan yang menyimpang
dari populasi, sehingga analisis outlier lebih difokuskan pada variabel
karakteristik perumahan, kependudukan, dan ekonomi.
2.5.2 Tabel Rekap Outlier
outlier_stats <- df %>%
select(all_of(box_vars)) %>%
summarise(across(everything(), list(
Q1 = ~round(quantile(.,0.25,na.rm=T), 2),
Q3 = ~round(quantile(.,0.75,na.rm=T), 2),
IQRval = ~round(IQR(.,na.rm=T), 2),
BatasAtas = ~round(quantile(.,0.75,na.rm=T) + 1.5*IQR(.,na.rm=T), 2),
NOutlier = ~sum(. > quantile(.,0.75,na.rm=T)+1.5*IQR(.,na.rm=T) |
. < quantile(.,0.25,na.rm=T)-1.5*IQR(.,na.rm=T), na.rm=T),
PctOutlier = ~round(sum(. > quantile(.,0.75,na.rm=T)+1.5*IQR(.,na.rm=T) |
. < quantile(.,0.25,na.rm=T)-1.5*IQR(.,na.rm=T),
na.rm=T)/n()*100, 1)
))) %>%
pivot_longer(everything(),
names_to = c("Variabel",".value"),
names_sep = "_(?=[^_]+$)") %>%
arrange(desc(PctOutlier))
kable(outlier_stats,
caption = "Rekap Outlier Berdasarkan Metode IQR",
col.names = c("Variabel","Q1","Q3","IQR","Batas Atas",
"N Outlier","% Outlier"),
format.args = list(big.mark = ",")) %>%
kable_styling(bootstrap_options = c("striped","hover","condensed"),
full_width = TRUE) %>%
row_spec(which(outlier_stats$PctOutlier > 5), background = "#fdf2f2") %>%
row_spec(which(outlier_stats$PctOutlier == 0), background = "#eafaf1") %>%
row_spec(0, bold = TRUE) %>%
column_spec(1, bold = TRUE)| Variabel | Q1 | Q3 | IQR | Batas Atas | N Outlier | % Outlier |
|---|---|---|---|---|---|---|
| total_rooms | 1,447.75 | 3,148.00 | 1,700.25 | 5,698.38 | 1,287 | 6.2 |
| total_bedrooms | 296.00 | 647.00 | 351.00 | 1,173.50 | 1,271 | 6.2 |
| households | 280.00 | 605.00 | 325.00 | 1,092.50 | 1,220 | 5.9 |
| population | 787.00 | 1,725.00 | 938.00 | 3,132.00 | 1,196 | 5.8 |
| median_house_value | 119,600.00 | 264,725.00 | 145,125.00 | 482,412.50 | 1,071 | 5.2 |
| median_income | 2.56 | 4.74 | 2.18 | 8.01 | 681 | 3.3 |
| housing_median_age | 18.00 | 37.00 | 19.00 | 65.50 | 0 | 0.0 |
2.6 Analisis Korelasi
2.6.1 Heatmap Korelasi
corr_vars <- df %>% select(-ocean_proximity, -longitude, -latitude)
cor_matrix <- cor(corr_vars, use = "pairwise.complete.obs")
corrplot(cor_matrix,
method = "color",
type = "upper",
order = "hclust",
col = colorRampPalette(c("#d73027","white","#1a9850"))(200),
addCoef.col = "black",
number.cex = 0.82,
tl.col = "black",
tl.cex = 0.92,
tl.srt = 45,
diag = FALSE,
cl.ratio = 0.15,
title = "Heatmap Korelasi Pearson Antar Variabel Numerik",
mar = c(0, 0, 2, 0))Berdasarkan heatmap korelasi tersebut, dapat diinterpretasikan sebagai berikut.
Korelasi antar variabel prediktor (potensi multikolinearitas):
total_bedrooms???householdsmemiliki korelasi tertinggi (r = 0,980), menunjukkan hubungan linear yang hampir sempurna. Hal ini mengindikasikan bahwa kedua variabel membawa informasi yang sangat mirip mengenai karakteristik ukuran blok sensus.total_rooms???total_bedrooms(r = 0,930) dantotal_rooms???households(r = 0,919) juga menunjukkan korelasi yang sangat kuat. Bersama denganpopulation, variabel-variabel tersebut membentuk kelompok dengan tingkat keterkaitan yang tinggi sehingga berpotensi menimbulkan multikolinearitas.population???households(r = 0,907),population???total_bedrooms(r = 0,878), danpopulation???total_rooms(r = 0,857) menunjukkan bahwa blok sensus dengan jumlah rumah tangga yang besar umumnya juga memiliki populasi dan jumlah ruangan yang lebih besar. Korelasi yang tinggi ini mengindikasikan adanya tumpang tindih informasi antarvariabel.housing_median_agememiliki korelasi negatif sedang dengan variabel-variabel agregat, yaitupopulation(-0,30),households(-0,30),total_bedrooms(-0,32), dantotal_rooms(-0,36). Hal ini menunjukkan bahwa blok dengan usia median rumah yang lebih tinggi cenderung memiliki ukuran dan jumlah penduduk yang lebih kecil.
Korelasi variabel prediktor dengan target
(median_house_value):
median_incomememiliki korelasi positif paling kuat terhadap harga rumah (r = 0,688). Hasil ini menunjukkan bahwa wilayah dengan pendapatan median yang lebih tinggi cenderung memiliki nilai rumah yang lebih tinggi, sehingga variabel ini merupakan prediktor yang paling informatif terhadapmedian_house_value.housing_median_agememiliki korelasi positif yang lemah terhadap harga rumah (r = 0,106), menunjukkan bahwa hubungan linear antara usia rumah dan harga rumah relatif kecil.total_rooms(r = 0,134),households(r = 0,066), dantotal_bedrooms(r = 0,050) hanya memiliki korelasi positif yang sangat lemah terhadap harga rumah.populationmemiliki korelasi negatif yang sangat kecil terhadap harga rumah (r = ???0,025). Nilai ini menunjukkan bahwa jumlah penduduk pada suatu blok sensus hampir tidak memiliki hubungan linear dengan harga rumah.
Secara keseluruhan, heatmap menunjukkan adanya kelompok variabel
dengan korelasi sangat tinggi (population,
households, total_rooms, dan
total_bedrooms) yang mengindikasikan potensi
multikolinearitas. Temuan ini mendukung perlunya penerapan teknik
reduksi dimensi seperti PCA untuk merangkum informasi dari
variabel-variabel yang saling berkorelasi kuat tersebut ke dalam
sejumlah komponen yang lebih ringkas.
2.6.2 Scatter Plot vs Target
predictors <- c("median_income","housing_median_age",
"total_rooms","population","households","total_bedrooms")
plots <- lapply(predictors, function(var) {
r_val <- round(cor(df[[var]], df$median_house_value, use = "complete.obs"), 3)
ggplot(df, aes_string(x = var, y = "median_house_value")) +
geom_point(alpha = 0.10, color = "#2c7fb8", size = 0.6) +
geom_smooth(method = "lm", color = "red", se = FALSE, size = 1) +
scale_y_continuous(labels = dollar_format(prefix = "$", big.mark = ",")) +
scale_x_continuous(labels = comma) +
labs(title = paste0(var, "\n(r = ", r_val, ")"),
x = var, y = "Harga Rumah") +
theme_bw(base_size = 9) +
theme(plot.title = element_text(face = "bold", size = 9, hjust = 0.5))
})
grid.arrange(grobs = plots, ncol = 3)Berdasarkan scatter plot tersebut, didapat interpretasi hubungan sebagai berikut.
median_incomevs harga rumah: Menunjukkan hubungan linear positif paling kuat di antara seluruh variabel prediktor (r = 0,688). Semakin tinggi pendapatan median suatu blok sensus, semakin tinggi pula nilai rumah pada wilayah tersebut. Pola titik-titik data membentuk tren naik yang cukup jelas, meskipun masih terdapat variasi yang cukup besar pada setiap tingkat pendapatan. Selain itu, terlihat bahwa sebaran harga rumah cenderung semakin lebar pada tingkat pendapatan yang tinggi, yang mengindikasikan peningkatan variasi harga rumah pada kelompok berpendapatan tinggi.housing_median_agevs harga rumah: Menunjukkan hubungan positif yang sangat lemah (r = 0,106). Sebaran titik yang sangat menyebar dan garis regresi yang relatif datar menunjukkan bahwa usia median rumah hanya memiliki hubungan linear yang kecil terhadap harga rumah. Meskipun demikian, terdapat kecenderungan bahwa wilayah dengan usia rumah yang lebih tua memiliki nilai rumah yang sedikit lebih tinggi.total_roomsvs harga rumah: Memiliki korelasi positif yang lemah (r = 0,134). Meskipun garis regresi menunjukkan kecenderungan meningkat, sebaran titik yang sangat luas menunjukkan bahwa jumlah kamar bukan merupakan prediktor utama harga rumah. Banyaknya kamar pada suatu blok sensus tidak selalu diikuti oleh peningkatan nilai rumah yang signifikan.total_bedroomsvs harga rumah: Menunjukkan korelasi positif yang sangat lemah (r = 0,050). Pola sebaran data tidak memperlihatkan hubungan yang kuat, sehingga jumlah kamar tidur secara langsung kurang mampu menjelaskan variasi harga rumah.householdsvs harga rumah: Memiliki korelasi positif yang sangat lemah (r = 0,066). Walaupun terdapat sedikit kecenderungan peningkatan harga seiring bertambahnya jumlah rumah tangga, hubungan tersebut relatif kecil dan tidak menunjukkan pola yang jelas.populationvs harga rumah: Menunjukkan korelasi negatif yang sangat lemah (r = -0,025). Nilai korelasi yang mendekati nol menunjukkan bahwa jumlah penduduk pada suatu blok sensus hampir tidak memiliki hubungan linear dengan harga rumah. Hal ini juga terlihat dari pola titik yang menyebar tanpa arah yang jelas.
Secara keseluruhan, scatter plot mengonfirmasi hasil analisis
korelasi sebelumnya bahwa median_income merupakan
variabel yang memiliki hubungan paling kuat dengan
median_house_value, sedangkan variabel ukuran blok
sensus seperti population, households,
total_rooms, dan total_bedrooms memiliki
hubungan linear yang relatif lemah terhadap harga rumah. Temuan ini
menunjukkan bahwa kondisi ekonomi wilayah lebih berpengaruh terhadap
harga rumah dibandingkan ukuran atau kepadatan blok sensus itu
sendiri.
2.6.3 Tabel Korelasi dengan Target
cor_target <- cor_matrix["median_house_value",] %>%
as.data.frame() %>%
rownames_to_column("Variabel") %>%
rename(Korelasi = ".") %>%
filter(Variabel != "median_house_value") %>%
mutate(
Korelasi = round(Korelasi, 4),
Kekuatan = case_when(
abs(Korelasi) >= 0.6 ~ "Kuat",
abs(Korelasi) >= 0.3 ~ "Sedang",
abs(Korelasi) >= 0.1 ~ "Lemah",
TRUE ~ "Sangat Lemah"
),
Arah = ifelse(Korelasi > 0, "Positif", "Negatif")
) %>%
arrange(desc(abs(Korelasi)))
kable(cor_target,
caption = "Korelasi Setiap Variabel terhadap median_house_value") %>%
kable_styling(bootstrap_options = c("striped","hover"),
full_width = FALSE, position = "center") %>%
row_spec(1, bold = TRUE, background = "#fcf8e3") %>%
row_spec(0, bold = TRUE) %>%
column_spec(1, bold = TRUE)| Variabel | Korelasi | Kekuatan | Arah |
|---|---|---|---|
| median_income | 0.6881 | Kuat | Positif |
| total_rooms | 0.1342 | Lemah | Positif |
| housing_median_age | 0.1056 | Lemah | Positif |
| households | 0.0658 | Sangat Lemah | Positif |
| total_bedrooms | 0.0497 | Sangat Lemah | Positif |
| population | -0.0246 | Sangat Lemah | Negatif |
2.7 Identifikasi Multikolinearitas
2.7.1 Heatmap Korelasi Prediktor
pred_vars <- corr_vars %>% select(-median_house_value)
cor_pred <- cor(pred_vars, use = "pairwise.complete.obs")
ggcorrplot(cor_pred,
hc.order = TRUE,
type = "lower",
lab = TRUE,
lab_size = 3.8,
colors = c("#d73027","white","#1a9850"),
outline.col = "white",
ggtheme = theme_bw()) +
labs(title = "Korelasi Antar Variabel Prediktor",
subtitle = "Fokus pada korelasi yang mendekati ??±1 (indikasi multikolinearitas)") +
theme(
plot.title = element_text(face = "bold", size = 14),
plot.subtitle = element_text(size = 10),
axis.text.x = element_text(angle = 45, hjust = 1)
)Berdasarkan heatmap tersebut, dapat diinterpretasikan bahwa heatmap
menunjukkan adanya kelompok variabel yang memiliki korelasi sangat
tinggi satu sama lain, yaitu population,
total_rooms, total_bedrooms, dan
households, dengan koefisien korelasi berkisar antara 0,86
hingga 0,98. Nilai korelasi yang sangat tinggi tersebut mengindikasikan
adanya potensi multikolinearitas yang kuat serta menunjukkan bahwa
variabel-variabel tersebut kemungkinan mengandung informasi yang saling
tumpang tindih mengenai ukuran atau kapasitas suatu blok sensus.
Sebaliknya, variabel median_income dan
housing_median_age memiliki korelasi yang relatif rendah
terhadap kelompok variabel tersebut, dengan nilai korelasi berkisar
antara ???0,36 hingga 0,20. Hal ini menunjukkan bahwa kedua variabel
tersebut menangkap aspek yang berbeda dari karakteristik wilayah
dibandingkan variabel-variabel yang berkaitan dengan ukuran blok sensus.
Temuan ini mengindikasikan bahwa proses reduksi dimensi, seperti PCA,
berpotensi efektif dalam merangkum informasi dari kelompok variabel yang
saling berkorelasi tinggi tanpa kehilangan terlalu banyak informasi.
2.7.2 VIF (Variance Inflation Factor)
df_vif <- df %>% select(-ocean_proximity, -longitude, -latitude) %>% drop_na()
model_vif <- lm(median_house_value ~ ., data = df_vif)
vif_df <- data.frame(
Variabel = names(vif(model_vif)),
VIF = round(vif(model_vif), 2)
) %>%
mutate(
Kategori = case_when(
VIF > 10 ~ "PARAH (>10)",
VIF > 5 ~ "MODERAT (5-10)",
VIF > 2 ~ "RINGAN (2-5)",
TRUE ~ "AMAN (<2)"
)
) %>%
arrange(desc(VIF))
kable(vif_df, caption = "Variance Inflation Factor (VIF) per Variabel Prediktor") %>%
kable_styling(bootstrap_options = c("striped","hover"),
full_width = FALSE, position = "center") %>%
row_spec(which(vif_df$VIF > 10), background = "#fdf2f2", bold = TRUE) %>%
row_spec(which(vif_df$VIF > 5 & vif_df$VIF <= 10), background = "#fef9e7") %>%
row_spec(0, bold = TRUE) %>%
column_spec(1, bold = TRUE) %>%
column_spec(3, bold = TRUE,
color = ifelse(vif_df$VIF > 10, "red",
ifelse(vif_df$VIF > 5, "darkorange", "darkgreen")))| Variabel | VIF | Kategori | |
|---|---|---|---|
| total_bedrooms | total_bedrooms | 35.50 | PARAH (>10) |
| households | households | 33.81 | PARAH (>10) |
| total_rooms | total_rooms | 11.90 | PARAH (>10) |
| population | population | 6.22 | MODERAT (5-10) |
| median_income | median_income | 1.51 | AMAN (<2) |
| housing_median_age | housing_median_age | 1.16 | AMAN (<2) |
2.7.3 Visualisasi VIF
ggplot(vif_df, aes(x = reorder(Variabel, VIF), y = VIF,
fill = Kategori)) +
geom_col(width = 0.6, alpha = 0.88) +
geom_hline(yintercept = 10, linetype = "dashed", color = "red", size = 1.0) +
geom_hline(yintercept = 5, linetype = "dashed", color = "darkorange", size = 1.0) +
geom_text(aes(label = round(VIF, 1)), hjust = -0.15, fontface = "bold", size = 4) +
annotate("text", x = 0.7, y = 11.2, label = "VIF = 10 (batas parah)",
color = "red", fontface = "italic", size = 3.2, hjust = 0) +
annotate("text", x = 0.7, y = 6.2, label = "VIF = 5 (batas moderat)",
color = "darkorange", fontface = "italic", size = 3.2, hjust = 0) +
coord_flip(ylim = c(0, max(vif_df$VIF) * 1.15)) +
scale_fill_manual(values = c("PARAH (>10)" = "#e74c3c",
"MODERAT (5-10)" = "#e67e22",
"RINGAN (2-5)" = "#f1c40f",
"AMAN (<2)" = "#2ca25f")) +
labs(
title = "Nilai VIF per Variabel Prediktor",
subtitle = "VIF > 10 = multikolinearitas parah | VIF > 5 = perlu perhatian",
x = NULL, y = "VIF", fill = "Kategori"
) +
theme_bw(base_size = 12) +
theme(plot.title = element_text(face = "bold", size = 14),
plot.subtitle = element_text(size = 10),
panel.grid.major.y = element_blank(),
legend.position = "bottom")VIF (Variance Inflation Factor) mengukur seberapa besar varians estimasi koefisien suatu variabel meningkat akibat adanya multikolinearitas dengan variabel prediktor lainnya. Secara umum, nilai VIF > 10 menunjukkan adanya multikolinearitas yang tinggi dan perlu mendapat perhatian khusus. Berdasarkan nilai VIF dan visualisasi heatmap di atas, didapat interpretasi sebagai berikut.
total_bedrooms(VIF = 35,50) memiliki nilai VIF tertinggi dan menunjukkan adanya multikolinearitas yang sangat kuat. Nilai ini mengindikasikan bahwa sebagian besar informasi yang terkandung dalam variabel tersebut dapat dijelaskan oleh kombinasi variabel prediktor lainnya.households(VIF = 33,81) juga menunjukkan tingkat multikolinearitas yang sangat tinggi. Hasil ini konsisten dengan analisis korelasi sebelumnya yang menunjukkan hubungan yang sangat kuat antarahouseholds,total_bedrooms,total_rooms, danpopulation.total_rooms(VIF = 11,90) masih berada pada kategori multikolinearitas tinggi. Variabel ini memiliki korelasi yang kuat dengan beberapa variabel ukuran blok sensus lainnya sehingga mengandung informasi yang relatif tumpang tindih.population(VIF = 6,22) termasuk dalam kategori moderat. Meskipun masih menunjukkan adanya hubungan yang cukup kuat dengan variabel lain, variabel ini tampaknya masih menyimpan informasi unik yang tidak sepenuhnya dijelaskan oleh prediktor lainnya.median_income(VIF = 1,51) berada pada kategori aman dan menunjukkan bahwa variabel ini relatif independen dari prediktor lainnya.housing_median_age(VIF = 1,16) memiliki nilai VIF terendah, sehingga dapat dianggap hampir tidak mengalami masalah multikolinearitas.
Hasil VIF mengonfirmasi temuan pada analisis korelasi sebelumnya
bahwa kelompok variabel population,
households, total_rooms, dan
total_bedrooms memiliki tingkat keterkaitan yang sangat
tinggi. Kondisi ini menunjukkan adanya redundansi informasi yang cukup
besar antarvariabel. Oleh karena itu, penerapan teknik reduksi dimensi
seperti Principal Component Analysis (PCA) menjadi
relevan untuk merangkum informasi dari variabel-variabel tersebut ke
dalam sejumlah komponen utama yang lebih ringkas tanpa kehilangan
informasi yang signifikan.
3 Feature Engineering
3.1 Membuat 3 Fitur Baru
df$rooms_per_household <- df$total_rooms / df$households
df$bedrooms_ratio <- df$total_bedrooms / df$total_rooms
df$population_per_household <- df$population / df$households
fitur_baru <- c("rooms_per_household", "bedrooms_ratio", "population_per_household")
summary(df[, fitur_baru]) rooms_per_household bedrooms_ratio population_per_household
Min. : 0.8461 Min. :0.1000 Min. : 0.6923
1st Qu.: 4.4407 1st Qu.:0.1754 1st Qu.: 2.4297
Median : 5.2291 Median :0.2032 Median : 2.8181
Mean : 5.4290 Mean :0.2130 Mean : 3.0707
3rd Qu.: 6.0524 3rd Qu.:0.2398 3rd Qu.: 3.2823
Max. :141.9091 Max. :1.0000 Max. :1243.3333
NA's :207
[,1]
rooms_per_household 0.1513441
bedrooms_ratio -0.2558801
population_per_household -0.0236394
Feature Engineering adalah proses menciptakan, memodifikasi, atau
mengatur ulang variabel sehingga data menjadi lebih berguna untuk
analisis atau pembuatan model. Umumnya, variabel mentah yang absolut
dari setiap blok wilayah seperti total_rooms,
total_bedrooms, population, dan
households kurang mampu menggambarkan karakteristik
sebenarnya dari suatu wilayah karena ukuran masing-masing blok dapat
berbeda secara signifikan. Oleh sebab itu, diperlukan normalisasi per
rumah tangga agar setiap fitur lebih memiliki makna secara substansial.
berdasarkan pertimbangan tersebut, dibuatlah 3 fitur baru berikut
ini.
Fitur 1:
rooms_per_household: Variabeltotal_roomsmempresentasikan jumlah keseluruhan ruangan dalam satu blok wilayah bukan per unit tempat tinggal. Angka absolut ini kehilangan maknanya jika tidak dihubungkan dengan banyaknya rumah tangga yang menghuni, sehingga fitur ini dirancang untuk menilai luas rata-rata tempat tinggal per rumah tangga yang lebih dapat menggambarkan karakteristik sesungguhnya dari sebuah blok. Berdasarkan perhitungan, fitur ini menunjukkan adanya hubungan positif denganmedian_house_value, yang berarti semakin banyak rata-rata ruangan per rumah tangga, semakin tinggi nilao rumah di blok tersebut. Hasil fitur ini mengonfirmasi temuan pada logika properti bahwa rumah yang lebih luas biasanya memiliki nilai yang lebih tinggi.Fitur 2:
bedrooms_ratio: Rasio antara jumlah kamar tidur dan total kamar menunjukkan komposisi tipe unit di dalam suatu blok. Nilai rasio yang rendah menunjukkan adanya lebih banyak ruang non-tidur, seperti ruang tamu, dapur, dan ruang kerja, yang menunjukkan kualitas hunian yang baik. Sebaliknya, rasio yang tinggi menunjukkan hunian yang lebih padat dengan lebih banyak kamar tidur. Oleh karena itu, fitur ini dikembangkan untuk mendapatkan informasi tentang kualitas dan kepadatan hunian yang tidak terlihat dari variabel mentah lain. Hasil perhitungan menunjukkan bahwa fitur ini memiliki korelasi negatif denganmedian_house_value, yang berarti bahwa semakin banyak proporsi kamar tidur di suatu blok, semakin rendah nilai rumah di area tersebut. Fitur ini mengonfirmasi temuan pada hasil penelitian yang menunjukkan bahwa area perumahan berkualitas tinggi cenderung memiliki lebih banyak ruang fungsional non-kamar tidur dibandingkan dengan kawasan hunian yang lain.Fitur 3:
population_per_household: Variabelpopulasimencatat jumlah total penduduk di setiap blok secara absolut, sehingga tidak dapat menggambarkan kepadatan huni yang sebenarnya tanpa membandingkannya dengan jumlah rumah tangga. Oleh karena itu, fitur ini dirancang untuk menghitung rata-rata jumlah orang dalam setiap rumah tangga, yang dapat menjadi indikator yang lebih baik untuk mengukur kepadatan sosial dan ekonomi di sebuah blok. Berdasarkan analisis yang dilakukan, fitur ini menunjukkan hubungan negatif denganmedian_house_value, yang berarti bahwa semakin banyak rata-rata penghuni dalam satu rumah tangga, semakin rendah nilai properti di blok tersebut. Hasil fitur ini mengonfrimasi temuan pada kondisi sosial ekonomi di wilayah yang padat, di mana biasanya nilai properti cenderung lebih rendah dibandingkan kawasan yang memiliki hunian lebih.
4 Feature Selection
Feature selection dilakukan pada 11 variabel prediktor numerik, yang
terdiri dari 8 variabel numerik asli (tidak termasuk
median_house_value sebagai target dan
ocean_proximity sebagai variabel kategorik) ditambah 3
fitur baru yang dihasilkan dari hasil feature engineering, yaitu
rooms_per_household, bedrooms_ratio, dan
population_per_household.
fitur_all <- c("longitude", "latitude", "housing_median_age",
"total_rooms", "total_bedrooms", "population",
"households", "median_income",
"rooms_per_household", "bedrooms_ratio",
"population_per_household")
housing_clean <- df %>%
select(all_of(fitur_all), median_house_value) %>%
drop_na()Sebelum menjalankan feature selection, dibuat objek
housing_clean yang merupakan bagian dari df
yang hanya berisi variabel-variabel prediktor (termasuk 3 fitur baru
yang dihasilkan dari feature engineering) dan variabel target
median_house_value, dengan semua observasi yang memiliki
nilai hilang dihapus menggunakan drop_na(). Proses ini
penting karena baik Setpwise Regression maupun LASSO Regression tidak
dapat dilakukan jika ada nilai NA dalam data.
4.1 Membuat 2 Metode
4.1.1 Metode 1: Wrapper Method - Stepwise Regression
null_model <- lm(median_house_value ~ 1, data = housing_clean)
full_model <- lm(median_house_value ~ ., data = housing_clean)
summary(null_model)
Call:
lm(formula = median_house_value ~ 1, data = housing_clean)
Residuals:
Min 1Q Median 3Q Max
-191865 -87364 -27164 57836 293137
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 206864.4 807.6 256.2 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 115400 on 20432 degrees of freedom
Call:
lm(formula = median_house_value ~ ., data = housing_clean)
Residuals:
Min 1Q Median 3Q Max
-576309 -42343 -11114 29659 846871
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -3.593e+06 6.297e+04 -57.048 <2e-16 ***
longitude -4.163e+04 7.222e+02 -57.641 <2e-16 ***
latitude -4.113e+04 6.886e+02 -59.727 <2e-16 ***
housing_median_age 1.155e+03 4.282e+01 26.981 <2e-16 ***
total_rooms 1.628e+00 9.431e-01 1.726 0.0843 .
total_bedrooms 1.942e+01 7.971e+00 2.437 0.0148 *
population -4.107e+01 1.107e+00 -37.107 <2e-16 ***
households 1.036e+02 8.360e+00 12.387 <2e-16 ***
median_income 4.243e+04 3.681e+02 115.268 <2e-16 ***
rooms_per_household 2.972e+03 2.521e+02 11.788 <2e-16 ***
bedrooms_ratio 3.095e+05 1.370e+04 22.586 <2e-16 ***
population_per_household 5.892e+01 4.745e+01 1.242 0.2144
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 68630 on 20421 degrees of freedom
Multiple R-squared: 0.6467, Adjusted R-squared: 0.6465
F-statistic: 3399 on 11 and 20421 DF, p-value: < 2.2e-16
forward_model <- step(null_model,
scope = list(lower = null_model, upper = full_model),
direction = "forward")Start: AIC=476354.2
median_house_value ~ 1
Df Sum of Sq RSS AIC
+ median_income 1 1.2901e+14 1.4326e+14 463235
+ bedrooms_ratio 1 1.7826e+13 2.5444e+14 474973
+ rooms_per_household 1 6.2362e+12 2.6603e+14 475883
+ latitude 1 5.6958e+12 2.6657e+14 475924
+ total_rooms 1 4.8374e+12 2.6743e+14 475990
+ housing_median_age 1 3.0842e+12 2.6918e+14 476123
+ households 1 1.1466e+12 2.7112e+14 476270
+ total_bedrooms 1 6.7214e+11 2.7159e+14 476306
+ longitude 1 5.6114e+11 2.7170e+14 476314
+ population 1 1.7427e+11 2.7209e+14 476343
+ population_per_household 1 1.5215e+11 2.7211e+14 476345
<none> 2.7226e+14 476354
Step: AIC=463235.5
median_house_value ~ median_income
Df Sum of Sq RSS AIC
+ bedrooms_ratio 1 1.2362e+13 1.3089e+14 461393
+ housing_median_age 1 9.7438e+12 1.3351e+14 461798
+ latitude 1 2.2109e+12 1.4105e+14 462920
+ rooms_per_household 1 1.6041e+12 1.4165e+14 463007
+ households 1 8.4322e+11 1.4241e+14 463117
+ total_bedrooms 1 8.2372e+11 1.4243e+14 463120
+ population_per_household 1 3.6575e+11 1.4289e+14 463185
+ longitude 1 3.2780e+11 1.4293e+14 463191
+ population 1 2.2585e+11 1.4303e+14 463205
<none> 1.4326e+14 463235
+ total_rooms 1 2.4139e+09 1.4325e+14 463237
Step: AIC=461393.5
median_house_value ~ median_income + bedrooms_ratio
Df Sum of Sq RSS AIC
+ housing_median_age 1 8.1027e+12 1.2279e+14 460090
+ longitude 1 8.9980e+11 1.2999e+14 461255
+ latitude 1 6.0042e+11 1.3029e+14 461302
+ population_per_household 1 4.4878e+11 1.3045e+14 461325
+ population 1 4.1935e+11 1.3047e+14 461330
+ households 1 3.5225e+11 1.3054e+14 461340
+ total_bedrooms 1 3.0888e+11 1.3059e+14 461347
+ rooms_per_household 1 6.5119e+10 1.3083e+14 461385
+ total_rooms 1 6.3779e+10 1.3083e+14 461385
<none> 1.3089e+14 461393
Step: AIC=460089.8
median_house_value ~ median_income + bedrooms_ratio + housing_median_age
Df Sum of Sq RSS AIC
+ total_bedrooms 1 2.5615e+12 1.2023e+14 459661
+ households 1 2.4457e+12 1.2035e+14 459681
+ total_rooms 1 1.7015e+12 1.2109e+14 459807
+ latitude 1 6.9102e+11 1.2210e+14 459976
+ population_per_household 1 5.0450e+11 1.2229e+14 460008
+ longitude 1 3.6840e+11 1.2242e+14 460030
+ population 1 5.0272e+10 1.2274e+14 460083
<none> 1.2279e+14 460090
+ rooms_per_household 1 1.5208e+09 1.2279e+14 460091
Step: AIC=459661
median_house_value ~ median_income + bedrooms_ratio + housing_median_age +
total_bedrooms
Df Sum of Sq RSS AIC
+ population 1 5.3605e+12 1.1487e+14 458731
+ total_rooms 1 7.9449e+11 1.1944e+14 459528
+ latitude 1 5.7971e+11 1.1965e+14 459564
+ population_per_household 1 4.4517e+11 1.1978e+14 459587
+ longitude 1 4.0867e+11 1.1982e+14 459593
<none> 1.2023e+14 459661
+ rooms_per_household 1 1.4218e+09 1.2023e+14 459663
+ households 1 1.8329e+07 1.2023e+14 459663
Step: AIC=458731.1
median_house_value ~ median_income + bedrooms_ratio + housing_median_age +
total_bedrooms + population
Df Sum of Sq RSS AIC
+ households 1 1.7260e+12 1.1314e+14 458424
+ latitude 1 1.1120e+12 1.1376e+14 458534
+ rooms_per_household 1 2.0408e+11 1.1467e+14 458697
+ longitude 1 1.8744e+11 1.1468e+14 458700
+ total_rooms 1 8.4018e+10 1.1479e+14 458718
+ population_per_household 1 4.2895e+10 1.1483e+14 458725
<none> 1.1487e+14 458731
Step: AIC=458423.7
median_house_value ~ median_income + bedrooms_ratio + housing_median_age +
total_bedrooms + population + households
Df Sum of Sq RSS AIC
+ latitude 1 1.2174e+12 1.1193e+14 458205
+ longitude 1 8.7746e+10 1.1306e+14 458410
+ rooms_per_household 1 3.1572e+10 1.1311e+14 458420
+ total_rooms 1 2.6786e+10 1.1312e+14 458421
<none> 1.1314e+14 458424
+ population_per_household 1 3.0426e+09 1.1314e+14 458425
Step: AIC=458204.7
median_house_value ~ median_income + bedrooms_ratio + housing_median_age +
total_bedrooms + population + households + latitude
Df Sum of Sq RSS AIC
+ longitude 1 1.5051e+13 9.6875e+13 455256
+ rooms_per_household 1 7.8695e+10 1.1185e+14 458192
<none> 1.1193e+14 458205
+ total_rooms 1 8.4360e+09 1.1192e+14 458205
+ population_per_household 1 2.1567e+08 1.1193e+14 458207
Step: AIC=455255.8
median_house_value ~ median_income + bedrooms_ratio + housing_median_age +
total_bedrooms + population + households + latitude + longitude
Df Sum of Sq RSS AIC
+ rooms_per_household 1 6.7071e+11 9.6205e+13 455116
+ total_rooms 1 3.1427e+10 9.6844e+13 455251
<none> 9.6875e+13 455256
+ population_per_household 1 3.3829e+09 9.6872e+13 455257
Step: AIC=455115.9
median_house_value ~ median_income + bedrooms_ratio + housing_median_age +
total_bedrooms + population + households + latitude + longitude +
rooms_per_household
Df Sum of Sq RSS AIC
+ total_rooms 1 1.2857e+10 9.6192e+13 455115
<none> 9.6205e+13 455116
+ population_per_household 1 6.0812e+09 9.6199e+13 455117
Step: AIC=455115.2
median_house_value ~ median_income + bedrooms_ratio + housing_median_age +
total_bedrooms + population + households + latitude + longitude +
rooms_per_household + total_rooms
Df Sum of Sq RSS AIC
<none> 9.6192e+13 455115
+ population_per_household 1 7259883043 9.6185e+13 455116
Call:
lm(formula = median_house_value ~ median_income + bedrooms_ratio +
housing_median_age + total_bedrooms + population + households +
latitude + longitude + rooms_per_household + total_rooms,
data = housing_clean)
Residuals:
Min 1Q Median 3Q Max
-576726 -42328 -11146 29627 840007
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -3.591e+06 6.296e+04 -57.034 <2e-16 ***
median_income 4.246e+04 3.672e+02 115.658 <2e-16 ***
bedrooms_ratio 3.095e+05 1.370e+04 22.587 <2e-16 ***
housing_median_age 1.157e+03 4.282e+01 27.013 <2e-16 ***
total_bedrooms 2.001e+01 7.957e+00 2.515 0.0119 *
population -4.074e+01 1.074e+00 -37.925 <2e-16 ***
households 1.024e+02 8.307e+00 12.326 <2e-16 ***
latitude -4.110e+04 6.881e+02 -59.722 <2e-16 ***
longitude -4.160e+04 7.220e+02 -57.627 <2e-16 ***
rooms_per_household 2.966e+03 2.521e+02 11.767 <2e-16 ***
total_rooms 1.555e+00 9.413e-01 1.652 0.0985 .
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 68630 on 20422 degrees of freedom
Multiple R-squared: 0.6467, Adjusted R-squared: 0.6465
F-statistic: 3738 on 10 and 20422 DF, p-value: < 2.2e-16
Start: AIC=455115.6
median_house_value ~ longitude + latitude + housing_median_age +
total_rooms + total_bedrooms + population + households +
median_income + rooms_per_household + bedrooms_ratio + population_per_household
Df Sum of Sq RSS AIC
- population_per_household 1 7.2599e+09 9.6192e+13 455115
<none> 9.6185e+13 455116
- total_rooms 1 1.4036e+10 9.6199e+13 455117
- total_bedrooms 1 2.7970e+10 9.6213e+13 455120
- rooms_per_household 1 6.5455e+11 9.6839e+13 455252
- households 1 7.2275e+11 9.6907e+13 455267
- bedrooms_ratio 1 2.4027e+12 9.8587e+13 455618
- housing_median_age 1 3.4288e+12 9.9613e+13 455829
- population 1 6.4854e+12 1.0267e+14 456447
- longitude 1 1.5649e+13 1.1183e+14 458194
- latitude 1 1.6802e+13 1.1299e+14 458403
- median_income 1 6.2582e+13 1.5877e+14 465354
Step: AIC=455115.2
median_house_value ~ longitude + latitude + housing_median_age +
total_rooms + total_bedrooms + population + households +
median_income + rooms_per_household + bedrooms_ratio
Df Sum of Sq RSS AIC
<none> 9.6192e+13 455115
- total_rooms 1 1.2857e+10 9.6205e+13 455116
- total_bedrooms 1 2.9785e+10 9.6222e+13 455119
- rooms_per_household 1 6.5214e+11 9.6844e+13 455251
- households 1 7.1560e+11 9.6907e+13 455265
- bedrooms_ratio 1 2.4030e+12 9.8595e+13 455617
- housing_median_age 1 3.4371e+12 9.9629e+13 455831
- population 1 6.7748e+12 1.0297e+14 456504
- longitude 1 1.5642e+13 1.1183e+14 458192
- latitude 1 1.6800e+13 1.1299e+14 458402
- median_income 1 6.3008e+13 1.5920e+14 465408
Call:
lm(formula = median_house_value ~ longitude + latitude + housing_median_age +
total_rooms + total_bedrooms + population + households +
median_income + rooms_per_household + bedrooms_ratio, data = housing_clean)
Residuals:
Min 1Q Median 3Q Max
-576726 -42328 -11146 29627 840007
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -3.591e+06 6.296e+04 -57.034 <2e-16 ***
longitude -4.160e+04 7.220e+02 -57.627 <2e-16 ***
latitude -4.110e+04 6.881e+02 -59.722 <2e-16 ***
housing_median_age 1.157e+03 4.282e+01 27.013 <2e-16 ***
total_rooms 1.555e+00 9.413e-01 1.652 0.0985 .
total_bedrooms 2.001e+01 7.957e+00 2.515 0.0119 *
population -4.074e+01 1.074e+00 -37.925 <2e-16 ***
households 1.024e+02 8.307e+00 12.326 <2e-16 ***
median_income 4.246e+04 3.672e+02 115.658 <2e-16 ***
rooms_per_household 2.966e+03 2.521e+02 11.767 <2e-16 ***
bedrooms_ratio 3.095e+05 1.370e+04 22.587 <2e-16 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 68630 on 20422 degrees of freedom
Multiple R-squared: 0.6467, Adjusted R-squared: 0.6465
F-statistic: 3738 on 10 and 20422 DF, p-value: < 2.2e-16
stepwise_model <- step(null_model,
scope = list(lower = null_model, upper = full_model),
direction = "both")Start: AIC=476354.2
median_house_value ~ 1
Df Sum of Sq RSS AIC
+ median_income 1 1.2901e+14 1.4326e+14 463235
+ bedrooms_ratio 1 1.7826e+13 2.5444e+14 474973
+ rooms_per_household 1 6.2362e+12 2.6603e+14 475883
+ latitude 1 5.6958e+12 2.6657e+14 475924
+ total_rooms 1 4.8374e+12 2.6743e+14 475990
+ housing_median_age 1 3.0842e+12 2.6918e+14 476123
+ households 1 1.1466e+12 2.7112e+14 476270
+ total_bedrooms 1 6.7214e+11 2.7159e+14 476306
+ longitude 1 5.6114e+11 2.7170e+14 476314
+ population 1 1.7427e+11 2.7209e+14 476343
+ population_per_household 1 1.5215e+11 2.7211e+14 476345
<none> 2.7226e+14 476354
Step: AIC=463235.5
median_house_value ~ median_income
Df Sum of Sq RSS AIC
+ bedrooms_ratio 1 1.2362e+13 1.3089e+14 461393
+ housing_median_age 1 9.7438e+12 1.3351e+14 461798
+ latitude 1 2.2109e+12 1.4105e+14 462920
+ rooms_per_household 1 1.6041e+12 1.4165e+14 463007
+ households 1 8.4322e+11 1.4241e+14 463117
+ total_bedrooms 1 8.2372e+11 1.4243e+14 463120
+ population_per_household 1 3.6575e+11 1.4289e+14 463185
+ longitude 1 3.2780e+11 1.4293e+14 463191
+ population 1 2.2585e+11 1.4303e+14 463205
<none> 1.4326e+14 463235
+ total_rooms 1 2.4139e+09 1.4325e+14 463237
- median_income 1 1.2901e+14 2.7226e+14 476354
Step: AIC=461393.5
median_house_value ~ median_income + bedrooms_ratio
Df Sum of Sq RSS AIC
+ housing_median_age 1 8.1027e+12 1.2279e+14 460090
+ longitude 1 8.9980e+11 1.2999e+14 461255
+ latitude 1 6.0042e+11 1.3029e+14 461302
+ population_per_household 1 4.4878e+11 1.3045e+14 461325
+ population 1 4.1935e+11 1.3047e+14 461330
+ households 1 3.5225e+11 1.3054e+14 461340
+ total_bedrooms 1 3.0888e+11 1.3059e+14 461347
+ rooms_per_household 1 6.5119e+10 1.3083e+14 461385
+ total_rooms 1 6.3779e+10 1.3083e+14 461385
<none> 1.3089e+14 461393
- bedrooms_ratio 1 1.2362e+13 1.4326e+14 463235
- median_income 1 1.2354e+14 2.5444e+14 474973
Step: AIC=460089.8
median_house_value ~ median_income + bedrooms_ratio + housing_median_age
Df Sum of Sq RSS AIC
+ total_bedrooms 1 2.5615e+12 1.2023e+14 459661
+ households 1 2.4457e+12 1.2035e+14 459681
+ total_rooms 1 1.7015e+12 1.2109e+14 459807
+ latitude 1 6.9102e+11 1.2210e+14 459976
+ population_per_household 1 5.0450e+11 1.2229e+14 460008
+ longitude 1 3.6840e+11 1.2242e+14 460030
+ population 1 5.0272e+10 1.2274e+14 460083
<none> 1.2279e+14 460090
+ rooms_per_household 1 1.5208e+09 1.2279e+14 460091
- housing_median_age 1 8.1027e+12 1.3089e+14 461393
- bedrooms_ratio 1 1.0721e+13 1.3351e+14 461798
- median_income 1 1.2611e+14 2.4890e+14 474525
Step: AIC=459661
median_house_value ~ median_income + bedrooms_ratio + housing_median_age +
total_bedrooms
Df Sum of Sq RSS AIC
+ population 1 5.3605e+12 1.1487e+14 458731
+ total_rooms 1 7.9449e+11 1.1944e+14 459528
+ latitude 1 5.7971e+11 1.1965e+14 459564
+ population_per_household 1 4.4517e+11 1.1978e+14 459587
+ longitude 1 4.0867e+11 1.1982e+14 459593
<none> 1.2023e+14 459661
+ rooms_per_household 1 1.4218e+09 1.2023e+14 459663
+ households 1 1.8329e+07 1.2023e+14 459663
- total_bedrooms 1 2.5615e+12 1.2279e+14 460090
- bedrooms_ratio 1 9.1741e+12 1.2940e+14 461162
- housing_median_age 1 1.0355e+13 1.3059e+14 461347
- median_income 1 1.2429e+14 2.4452e+14 474165
Step: AIC=458731.1
median_house_value ~ median_income + bedrooms_ratio + housing_median_age +
total_bedrooms + population
Df Sum of Sq RSS AIC
+ households 1 1.7260e+12 1.1314e+14 458424
+ latitude 1 1.1120e+12 1.1376e+14 458534
+ rooms_per_household 1 2.0408e+11 1.1467e+14 458697
+ longitude 1 1.8744e+11 1.1468e+14 458700
+ total_rooms 1 8.4018e+10 1.1479e+14 458718
+ population_per_household 1 4.2895e+10 1.1483e+14 458725
<none> 1.1487e+14 458731
- population 1 5.3605e+12 1.2023e+14 459661
- total_bedrooms 1 7.8717e+12 1.2274e+14 460083
- bedrooms_ratio 1 8.0236e+12 1.2289e+14 460109
- housing_median_age 1 1.0067e+13 1.2494e+14 460446
- median_income 1 1.2249e+14 2.3736e+14 473559
Step: AIC=458423.7
median_house_value ~ median_income + bedrooms_ratio + housing_median_age +
total_bedrooms + population + households
Df Sum of Sq RSS AIC
+ latitude 1 1.2174e+12 1.1193e+14 458205
+ longitude 1 8.7746e+10 1.1306e+14 458410
+ rooms_per_household 1 3.1572e+10 1.1311e+14 458420
+ total_rooms 1 2.6786e+10 1.1312e+14 458421
- total_bedrooms 1 9.8354e+08 1.1314e+14 458422
<none> 1.1314e+14 458424
+ population_per_household 1 3.0426e+09 1.1314e+14 458425
- households 1 1.7260e+12 1.1487e+14 458731
- population 1 7.0865e+12 1.2023e+14 459663
- bedrooms_ratio 1 8.0086e+12 1.2115e+14 459819
- housing_median_age 1 9.1565e+12 1.2230e+14 460012
- median_income 1 1.1862e+14 2.3176e+14 473073
Step: AIC=458204.7
median_house_value ~ median_income + bedrooms_ratio + housing_median_age +
total_bedrooms + population + households + latitude
Df Sum of Sq RSS AIC
+ longitude 1 1.5051e+13 9.6875e+13 455256
+ rooms_per_household 1 7.8695e+10 1.1185e+14 458192
- total_bedrooms 1 8.5039e+08 1.1193e+14 458203
<none> 1.1193e+14 458205
+ total_rooms 1 8.4360e+09 1.1192e+14 458205
+ population_per_household 1 2.1567e+08 1.1193e+14 458207
- latitude 1 1.2174e+12 1.1314e+14 458424
- households 1 1.8314e+12 1.1376e+14 458534
- bedrooms_ratio 1 6.4149e+12 1.1834e+14 459341
- population 1 7.7235e+12 1.1965e+14 459566
- housing_median_age 1 9.1421e+12 1.2107e+14 459807
- median_income 1 1.0948e+14 2.2141e+14 472141
Step: AIC=455255.8
median_house_value ~ median_income + bedrooms_ratio + housing_median_age +
total_bedrooms + population + households + latitude + longitude
Df Sum of Sq RSS AIC
+ rooms_per_household 1 6.7071e+11 9.6205e+13 455116
+ total_rooms 1 3.1427e+10 9.6844e+13 455251
<none> 9.6875e+13 455256
+ population_per_household 1 3.3829e+09 9.6872e+13 455257
- households 1 2.8568e+11 9.7161e+13 455314
- total_bedrooms 1 5.5506e+11 9.7430e+13 455371
- bedrooms_ratio 1 2.5028e+12 9.9378e+13 455775
- housing_median_age 1 3.3545e+12 1.0023e+14 455949
- population 1 6.9307e+12 1.0381e+14 456666
- longitude 1 1.5051e+13 1.1193e+14 458205
- latitude 1 1.6180e+13 1.1306e+14 458410
- median_income 1 7.2315e+13 1.6919e+14 466647
Step: AIC=455115.9
median_house_value ~ median_income + bedrooms_ratio + housing_median_age +
total_bedrooms + population + households + latitude + longitude +
rooms_per_household
Df Sum of Sq RSS AIC
+ total_rooms 1 1.2857e+10 9.6192e+13 455115
<none> 9.6205e+13 455116
+ population_per_household 1 6.0812e+09 9.6199e+13 455117
- total_bedrooms 1 7.5146e+10 9.6280e+13 455130
- rooms_per_household 1 6.7071e+11 9.6875e+13 455256
- households 1 7.0904e+11 9.6914e+13 455264
- bedrooms_ratio 1 3.0567e+12 9.9261e+13 455753
- housing_median_age 1 3.4256e+12 9.9630e+13 455829
- population 1 7.1593e+12 1.0336e+14 456581
- longitude 1 1.5643e+13 1.1185e+14 458192
- latitude 1 1.6824e+13 1.1303e+14 458407
- median_income 1 6.6783e+13 1.6299e+14 465886
Step: AIC=455115.2
median_house_value ~ median_income + bedrooms_ratio + housing_median_age +
total_bedrooms + population + households + latitude + longitude +
rooms_per_household + total_rooms
Df Sum of Sq RSS AIC
<none> 9.6192e+13 455115
+ population_per_household 1 7.2599e+09 9.6185e+13 455116
- total_rooms 1 1.2857e+10 9.6205e+13 455116
- total_bedrooms 1 2.9785e+10 9.6222e+13 455119
- rooms_per_household 1 6.5214e+11 9.6844e+13 455251
- households 1 7.1560e+11 9.6907e+13 455265
- bedrooms_ratio 1 2.4030e+12 9.8595e+13 455617
- housing_median_age 1 3.4371e+12 9.9629e+13 455831
- population 1 6.7748e+12 1.0297e+14 456504
- longitude 1 1.5642e+13 1.1183e+14 458192
- latitude 1 1.6800e+13 1.1299e+14 458402
- median_income 1 6.3008e+13 1.5920e+14 465408
Call:
lm(formula = median_house_value ~ median_income + bedrooms_ratio +
housing_median_age + total_bedrooms + population + households +
latitude + longitude + rooms_per_household + total_rooms,
data = housing_clean)
Residuals:
Min 1Q Median 3Q Max
-576726 -42328 -11146 29627 840007
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -3.591e+06 6.296e+04 -57.034 <2e-16 ***
median_income 4.246e+04 3.672e+02 115.658 <2e-16 ***
bedrooms_ratio 3.095e+05 1.370e+04 22.587 <2e-16 ***
housing_median_age 1.157e+03 4.282e+01 27.013 <2e-16 ***
total_bedrooms 2.001e+01 7.957e+00 2.515 0.0119 *
population -4.074e+01 1.074e+00 -37.925 <2e-16 ***
households 1.024e+02 8.307e+00 12.326 <2e-16 ***
latitude -4.110e+04 6.881e+02 -59.722 <2e-16 ***
longitude -4.160e+04 7.220e+02 -57.627 <2e-16 ***
rooms_per_household 2.966e+03 2.521e+02 11.767 <2e-16 ***
total_rooms 1.555e+00 9.413e-01 1.652 0.0985 .
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 68630 on 20422 degrees of freedom
Multiple R-squared: 0.6467, Adjusted R-squared: 0.6465
F-statistic: 3738 on 10 and 20422 DF, p-value: < 2.2e-16
median_house_value ~ median_income + bedrooms_ratio + housing_median_age +
total_bedrooms + population + households + latitude + longitude +
rooms_per_household + total_rooms
median_house_value ~ longitude + latitude + housing_median_age +
total_rooms + total_bedrooms + population + households +
median_income + rooms_per_household + bedrooms_ratio
median_house_value ~ median_income + bedrooms_ratio + housing_median_age +
total_bedrooms + population + households + latitude + longitude +
rooms_per_household + total_rooms
Wrapper Method memilih variabel dengan memperhatikan kinerja model secara berurutan memakai nilai AIC (Akaike Information Criterion) sebagai dasar penilaian. Semakin rendah nilai AIC, semakin efektif model dalam menggambarkan data. Ketiga jenis Stepwise Regression yang diterapkan menghasilkan variabel yang terpilih sama persis dengan nilai AIC yang serupa yaitu 455.115,2. Ini menunjukkan bahwa pemilihan variabel sudah sangat konsisten dan tidak tergantung pada cara pemilihan yang dipakai. Model tersebut menghasilkan Adjusted R?? = 0,6465, yang artinya model ini bisa menjelaskan 64,65% perubahan harga rumah.
Variabel Terpilih:
median_income(¦?? = 42.460, p < 0,001) adalah faktor pertama yang menunjukkan penurunan AIC paling besar. Pendapatan median adalah faktor kunci yang menentukan kapasitas membeli properti, semakin tinggi pendapatan dalam suatu wilayah, semakin tinggi nilai rumah di tempat tersebut.longitude(¦?? = ???41.600, p < 0,001) adalah posisi geografis yang mengarah barat-timur terbukti signifikan karena daerah pesisir di barat California memiliki harga properti yang jauh lebih tinggi dibandingkan dengan wilayah timurnya.latitude(¦?? = ???41.100, p < 0,001) adalah posisi geografis yang mengarah utara-selatan terbukti signifikan karena daerah Bay Area di utara California memiliki harga properti yang jauh lebih tinggi dibandingkan dengan wilayah selatannya.housing_median_age(¦?? = 1.157, p < 0,001), usia bangunan memiliki dampak positif, area dengan bangunan yang lebih tua biasanya berada di lokasi yang sudah lama berkembang dan memiliki nilai properti yang lebih tinggi.total_bedrooms(¦?? = 20,01, p = 0,012), memberikan dampak positif terhadap nilai properti dalam model multivariat ini.population(¦?? = ???40,74, p < 0,001), memberikan dampak negatif. Tingginya kepadatan penduduk cenderung menurunkan nilai rumah karena berhubungan dengan rendahnya eksklusivitas suatu area.households(¦?? = 102,4, p < 0,001), jumlah unit rumah tangga di tiap blok mencerminkan tingkat pembangunan dan kemajuan suatu area yang memberikan dampak positif terhadap nilai properti.rooms_per_household(¦?? = 2.966, p < 0,001), semakin banyak rata-rata ruangan per rumah tangga, semakin tinggi juga nilai propertinya.bedrooom_ratio(¦?? = 309.500, p < 0,001), perbandingan jumlah kamar tidur ini memberikan informasi khusus tentang bagaimana hunian disusun.total_rooms(¦?? = 1,555, p = 0,099, berpengaruh lemah tetapi tetap dipertahankan karena masih membantu meningkatkan AIC model.
Variabel Dieliminasi:
population_per_householddihilangkan karena informasinya sudah tercakup dalam kombinasi antarapopulasidanhouseholdsyang keduanya sudah terpilih. Menambah variabel ini tidak membuat AIC model jadi lebih baik.
4.1.2 Metode 2: Embedded Method - LASSO Regression
x <- scale(as.matrix(housing_clean[, fitur_all]))
y <- housing_clean$median_house_value
set.seed(123)
cv_lasso <- cv.glmnet(x, y, alpha = 1)
plot(cv_lasso)Lambda optimal: 206.1976
lasso_model <- glmnet(x, y, alpha = 1, lambda = cv_lasso$lambda.min)
koef <- coef(lasso_model)
print(koef)12 x 1 sparse Matrix of class "dgCMatrix"
s0
(Intercept) 206864.4132
longitude -80081.4978
latitude -84408.6343
housing_median_age 14595.8804
total_rooms 1928.7072
total_bedrooms 9631.8369
population -44010.7934
households 37212.3437
median_income 80962.8932
rooms_per_household 6776.5423
bedrooms_ratio 17437.0559
population_per_household 142.1753
terpilih_lasso <- rownames(koef)[koef[, 1] != 0 & rownames(koef) != "(Intercept)"]
dieliminasi_lasso <- rownames(koef)[koef[, 1] == 0]
cat("Terpilih LASSO :", paste(terpilih_lasso, collapse = ", "), "\n")Terpilih LASSO : longitude, latitude, housing_median_age, total_rooms, total_bedrooms, population, households, median_income, rooms_per_household, bedrooms_ratio, population_per_household
Dieliminasi LASSO:
Dengan jumlah data sebesar 20.640 pengamatan dan nilai lambda terbaik yang didapat sebesar ¦?? = 206,1976 melalui cross-validation, LASSO menyimpan semua 11 variabel karena setiap koefisien memiliki nilai berbeda dari nol. Ini berarti bahwa dengan banyaknya data yang ada, setiap variabel memiliki peran penting dalam memprediksi meskipun ada penalti lambda. Tidak ada variabel yang dieliminasi oleh LASSO pada dataset ini, sehingga variabel yang terpilih adalah keseluruhan variabel yang tersedia.
lasso_df <- data.frame(
Variabel = c("median_income", "latitude", "longitude", "population",
"households", "bedrooms_ratio", "housing_median_age",
"total_bedrooms", "rooms_per_household", "total_rooms",
"population_per_household"),
Koefisien = c(80962.89, -84408.63, -80081.50, -44010.79,
37212.34, 17437.06, 14595.88, 9631.84,
6776.54, 1928.71, 142.18)
)
kable(lasso_df,
col.names = c("Variabel", "Koefisien"),
align = c("l", "r"),
caption = "Koefisien LASSO Regression",
format.args = list(big.mark = ".", decimal.mark = ",")) %>%
kable_styling(bootstrap_options = c("striped","hover","condensed","responsive"),
full_width = TRUE) %>%
row_spec(0, bold = TRUE)| Variabel | Koefisien |
|---|---|
| median_income | 80.962,89 |
| latitude | -84.408,63 |
| longitude | -80.081,50 |
| population | -44.010,79 |
| households | 37.212,34 |
| bedrooms_ratio | 17.437,06 |
| housing_median_age | 14.595,88 |
| total_bedrooms | 9.631,84 |
| rooms_per_household | 6.776,54 |
| total_rooms | 1.928,71 |
| population_per_household | 142,18 |
4.2 Kesimpulan Feature Selection
Berdasarkan hasil dari dua metode yang digunakan, yaitu Stepwise
Regression dan LASSO Regression, didapatkan hasil yang sama. Tiga jenis
Stepwise Regression yang digunakan (Forward Selection, Backward
Elimination, dan Stepwise Bidirectional) semua memilih 10 variabel yang
sama dengan nilai AIC yang identik yaitu 455.115,2. Ini menunjukkan
bahwa pemilihan variabel sangat stabil dan tidak dipengaruhi oleh cara
pemilihannya. Satu-satunya variabel yang dihilangkan oleh Stepwise
adalah population_per_household karena tidak memberikan
kontribusi yang penting setelah population dan households
sudah diperhitungkan dalam model.
Sementara itu, LASSO dengan nilai lambda optimal ¦?? = 206,1976 mempertahankan semua 11 variabel dan tanpa ada yang dihapus. Ini terjadi karena jumlah data yang sangat banyak (20.640 observasi setelah menghapus NA) membuat setiap variabel tampak memberikan kontribusi yang cukup untuk melawan penalti dari lambda.
Secara keseluruhan, ada 10 variabel yang disepakati oleh kedua
metode, yaitu median_income, bedrooms_ratio,
housing_median_age, total_bedrooms,
population, households, latitude,
longitude, rooms_per_household, dan
total_rooms. Satu-satunya perbedaan adalah
population_per_household yang dieliminasi d metode Stepwise
tetapi tetap ada di LASSO. median_income selalu menjadi
prediktor terkuat di kedua metode dengan nilai koefisien tertinggi,
diikuti oleh latitude dan longitude yang
menunjukkan pengaruh lokasi geografis terhadap harga rumah. Hasil ini
menunjukkan bahwa situasi ekonomi dan lokasi geografis adalah dua hal
yang paling penting dalam menentukan harga rumah di California.
#5
# Reproduksi Feature Engineering dari Bagian C
df$rooms_per_household <- df$total_rooms / df$households
df$bedrooms_ratio <- df$total_bedrooms / df$total_rooms
df$population_per_household <- df$population / df$households
# Daftar fitur (sama dengan Bagian D)
fitur_all <- c(
"longitude", "latitude", "housing_median_age",
"total_rooms", "total_bedrooms", "population",
"households", "median_income",
"rooms_per_household", "bedrooms_ratio",
"population_per_household"
)
housing_clean <- na.omit(
df[, c(fitur_all, "median_house_value")]
)5 Feature Extraction
5.1 Pendahuluan Principal Component Analysis (PCA)
Principal Component Analysis (PCA) adalah teknik reduksi dimensi yang mengubah sekumpulan variabel yang berkorelasi menjadi sejumlah kecil variabel baru yang tidak berkorelasi satu sama lain, disebut komponen utama (principal components). Setiap komponen utama merupakan kombinasi linear dari variabel-variabel asli dan disusun sedemikian rupa sehingga PC1 menjelaskan variasi terbesar dalam data, diikuti oleh komponen berikutnya secara berurutan.
Dalam konteks dataset California Housing, PCA menjadi sangat relevan
mengingat hasil analisis sebelumnya yang menunjukkan adanya
multikolinearitas yang parah pada kelompok variabel
total_rooms, total_bedrooms,
households, dan population (VIF berkisar
6???35). Kondisi ini mengindikasikan redundansi informasi yang tinggi
sehingga keempat variabel tersebut dapat diringkas menjadi beberapa
komponen utama tanpa kehilangan informasi yang signifikan.
5.2 Persiapan Data PCA
PCA sensitif terhadap skala variabel. Oleh karena itu, sebelum
menerapkan PCA, seluruh variabel numerik perlu distandarisasi
menggunakan Z-score agar setiap variabel memiliki mean
= 0 dan standar deviasi = 1. Variabel median_house_value
dikecualikan karena merupakan variabel target, dan
ocean_proximity dikecualikan karena bertipe kategorik.
# Seleksi variabel prediktor numerik
pca_vars <- c("longitude", "latitude", "housing_median_age",
"total_rooms", "total_bedrooms", "population",
"households", "median_income",
"rooms_per_household", "bedrooms_ratio",
"population_per_household")
# Standarisasi Z-Score
pca_data <- housing_clean[, pca_vars]
pca_scaled <- scale(pca_data)
cat("Dimensi data PCA :", nrow(pca_scaled), "observasi x", ncol(pca_scaled), "variabel\n")Dimensi data PCA : 20433 observasi x 11 variabel
Verifikasi scaling ??? rata-rata kolom (seharusnya ~0):
longitude latitude housing_median_age
0 0 0
total_rooms total_bedrooms population
0 0 0
households median_income rooms_per_household
0 0 0
bedrooms_ratio population_per_household
0 0
Berdasarkan output di atas, seluruh variabel telah berhasil distandarisasi dengan rata-rata mendekati 0 untuk setiap kolom. Dataset yang digunakan terdiri dari 20433 observasi bersih (setelah penghapusan missing values) dengan 11 variabel prediktor numerik yang siap dianalisis menggunakan PCA.
5.3 Pelaksanaan PCA
# Menjalankan PCA
pca_result <- prcomp(pca_scaled, center = FALSE, scale. = FALSE)
# Ringkasan hasil PCA
summary(pca_result)Importance of components:
PC1 PC2 PC3 PC4 PC5 PC6 PC7
Standard deviation 1.9770 1.4459 1.3552 1.00527 0.92140 0.82970 0.61161
Proportion of Variance 0.3553 0.1900 0.1670 0.09187 0.07718 0.06258 0.03401
Cumulative Proportion 0.3553 0.5454 0.7123 0.80421 0.88139 0.94397 0.97798
PC8 PC9 PC10 PC11
Standard deviation 0.36563 0.23662 0.20313 0.10618
Proportion of Variance 0.01215 0.00509 0.00375 0.00102
Cumulative Proportion 0.99013 0.99522 0.99898 1.00000
5.4 Analisis Proporsi Variansi
5.4.1 Tabel Variansi Komponen
eigenvalues <- pca_result$sdev^2
prop_var <- eigenvalues / sum(eigenvalues)
cumul_var <- cumsum(prop_var)
var_table <- data.frame(
Komponen = paste0("PC", seq_along(eigenvalues)),
Eigenvalue = round(eigenvalues, 4),
Proporsi_Variansi = paste0(round(prop_var * 100, 2), "%"),
Kumulatif_Variansi = paste0(round(cumul_var * 100, 2), "%"),
Status_Kaiser = ifelse(eigenvalues >= 1, "??? Dipertahankan", "??? Diabaikan")
)
kable(var_table,
caption = "Proporsi Variansi dan Eigenvalue Setiap Komponen Utama",
col.names = c("Komponen", "Eigenvalue", "Proporsi Variansi",
"Kumulatif Variansi", "Status Kaiser (??? 1)")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center") %>%
row_spec(which(eigenvalues >= 1), background = "#eafaf1", bold = TRUE) %>%
row_spec(which(eigenvalues < 1), background = "#fdf2f2") %>%
row_spec(0, bold = TRUE) %>%
column_spec(1, bold = TRUE)| Komponen | Eigenvalue | Proporsi Variansi | Kumulatif Variansi | Status Kaiser (??? 1) |
|---|---|---|---|---|
| PC1 | 3.9085 | 35.53% | 35.53% | ??? Dipertahankan |
| PC2 | 2.0906 | 19.01% | 54.54% | ??? Dipertahankan |
| PC3 | 1.8366 | 16.7% | 71.23% | ??? Dipertahankan |
| PC4 | 1.0106 | 9.19% | 80.42% | ??? Dipertahankan |
| PC5 | 0.8490 | 7.72% | 88.14% | ??? Diabaikan |
| PC6 | 0.6884 | 6.26% | 94.4% | ??? Diabaikan |
| PC7 | 0.3741 | 3.4% | 97.8% | ??? Diabaikan |
| PC8 | 0.1337 | 1.22% | 99.01% | ??? Diabaikan |
| PC9 | 0.0560 | 0.51% | 99.52% | ??? Diabaikan |
| PC10 | 0.0413 | 0.38% | 99.9% | ??? Diabaikan |
| PC11 | 0.0113 | 0.1% | 100% | ??? Diabaikan |
Berdasarkan tabel di atas, dapat diinterpretasikan sebagai berikut.
- Kaiser Criterion (eigenvalue ??? 1) digunakan sebagai acuan pemilihan komponen. Komponen dengan eigenvalue ??? 1 menjelaskan variasi yang lebih besar dari satu variabel tunggal yang telah distandarisasi, sehingga dianggap layak dipertahankan.
- PC1 menjelaskan porsi terbesar variasi karena
merangkum kelompok variabel yang saling berkorelasi tinggi
(
total_rooms,total_bedrooms,households,population). - Berdasarkan kriteria kumulatif variansi ??? 80%, sebagian besar informasi data sudah terangkum dalam beberapa komponen pertama saja.
5.4.2 Scree Plot
fviz_eig(pca_result,
addlabels = TRUE,
ylim = c(0, 60),
barfill = "#2c7fb8",
barcolor = "white",
linecolor = "#e74c3c",
ggtheme = theme_bw(base_size = 12)) +
geom_hline(yintercept = (1 / length(eigenvalues)) * 100,
linetype = "dashed", color = "darkorange", size = 1) +
annotate("text",
x = length(eigenvalues) - 0.5,
y = (1 / length(eigenvalues)) * 100 + 2,
label = "Batas Kaiser (eigenvalue = 1)",
color = "darkorange", fontface = "italic", size = 3.5, hjust = 1) +
labs(
title = "Scree Plot ??? Proporsi Variansi Setiap Komponen Utama",
subtitle = "Batang biru = % variansi | Garis merah = tren | Garis oranye = batas Kaiser",
x = "Komponen Utama (PC)",
y = "Persentase Variansi (%)"
)Scree plot di atas menunjukkan penurunan yang tajam (elbow) pada komponen-komponen awal, yang menandakan bahwa sebagian besar variasi dalam data terkonsentrasi pada beberapa komponen pertama. Titik elbow yaitu titik di mana kurva mulai mendatar menjadi panduan visual untuk menentukan jumlah komponen yang optimal karena penambahan komponen setelah titik tersebut tidak lagi memberikan peningkatan variansi yang berarti.
5.4.3 Kumulatif Variansi
cumvar_df <- data.frame(
PC = factor(paste0("PC", seq_along(cumul_var)),
levels = paste0("PC", seq_along(cumul_var))),
Kumulatif = cumul_var * 100
)
ggplot(cumvar_df, aes(x = PC, y = Kumulatif, group = 1)) +
geom_line(color = "#2c7fb8", size = 1.2) +
geom_point(aes(color = Kumulatif >= 80), size = 4) +
geom_hline(yintercept = 80, linetype = "dashed", color = "red", size = 1) +
geom_hline(yintercept = 90, linetype = "dashed", color = "darkorange", size = 1) +
annotate("text", x = length(cumul_var) - 0.5, y = 81.5,
label = "80% Kumulatif", color = "red",
fontface = "italic", size = 3.5, hjust = 1) +
annotate("text", x = length(cumul_var) - 0.5, y = 91.5,
label = "90% Kumulatif", color = "darkorange",
fontface = "italic", size = 3.5, hjust = 1) +
scale_color_manual(values = c("FALSE" = "#7f8c8d", "TRUE" = "#27ae60"),
labels = c("FALSE" = "< 80%", "TRUE" = "??? 80%")) +
scale_y_continuous(labels = function(x) paste0(x, "%"), limits = c(0, 103)) +
labs(
title = "Kumulatif Proporsi Variansi PCA",
subtitle = "Titik hijau = komponen yang sudah mencapai kumulatif ??? 80%",
x = "Komponen Utama", y = "Kumulatif Variansi (%)", color = "Status"
) +
theme_bw(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 14),
plot.subtitle = element_text(size = 10),
axis.text.x = element_text(angle = 30, hjust = 1),
legend.position = "bottom"
)5.5 Loading Factor
Loading factor menggambarkan kontribusi (korelasi) setiap variabel asli terhadap masing-masing komponen utama. Nilai loading mendekati ±1 menunjukkan kontribusi yang kuat, sedangkan nilai mendekati 0 menunjukkan kontribusi yang lemah. Tanda positif berarti variabel bergerak searah dengan komponen, sedangkan tanda negatif berarti berlawanan arah.
5.5.1 Tabel Loading Factor
loading_mat <- pca_result$rotation[, 1:5]
loading_df <- as.data.frame(round(loading_mat, 4))
kable(loading_df,
caption = "Loading Factor: Kontribusi Variabel terhadap 5 PC Pertama") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = TRUE) %>%
row_spec(0, bold = TRUE) %>%
column_spec(1, bold = TRUE)| PC1 | PC2 | PC3 | PC4 | PC5 | |
|---|---|---|---|---|---|
| longitude | 0.0753 | -0.3972 | -0.5731 | 0.0126 | 0.0700 |
| latitude | -0.0722 | 0.4061 | 0.5708 | 0.0017 | 0.1030 |
| housing_median_age | -0.2199 | -0.1294 | 0.1259 | -0.0867 | -0.8522 |
| total_rooms | 0.4851 | 0.1214 | 0.0022 | 0.0140 | -0.0968 |
| total_bedrooms | 0.4897 | -0.0361 | 0.1023 | 0.0239 | -0.0502 |
| population | 0.4709 | -0.0553 | 0.0739 | -0.0953 | -0.0908 |
| households | 0.4907 | -0.0444 | 0.1109 | 0.0128 | -0.1109 |
| median_income | 0.0507 | 0.4332 | -0.3819 | -0.0586 | -0.3285 |
| rooms_per_household | 0.0139 | 0.4195 | -0.2492 | 0.0457 | 0.2689 |
| bedrooms_ratio | -0.0182 | -0.5253 | 0.3061 | 0.0146 | 0.1800 |
| population_per_household | -0.0029 | -0.0015 | -0.0049 | -0.9882 | 0.1152 |
5.5.2 Heatmap Loading Factor
load_long <- as.data.frame(loading_mat) %>%
rownames_to_column("Variabel") %>%
pivot_longer(-Variabel, names_to = "PC", values_to = "Loading")
ggplot(load_long, aes(x = PC, y = Variabel, fill = Loading)) +
geom_tile(color = "white", size = 0.5) +
geom_text(aes(label = round(Loading, 2),
color = abs(Loading) > 0.30),
size = 3.8, fontface = "bold") +
scale_fill_gradient2(low = "#d73027", mid = "white", high = "#1a9850",
midpoint = 0, limits = c(-1, 1), name = "Loading") +
scale_color_manual(values = c("FALSE" = "gray65", "TRUE" = "black"),
guide = "none") +
scale_x_discrete(position = "top") +
labs(
title = "Heatmap Loading Factor ??? 5 Komponen Utama Pertama",
subtitle = "Hijau = kontribusi positif kuat | Merah = kontribusi negatif kuat | Putih = lemah",
x = NULL, y = NULL
) +
theme_bw(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 14),
plot.subtitle = element_text(size = 10),
axis.text.y = element_text(face = "bold"),
legend.position = "right"
)5.5.3 Interpretasi Loading Factor
Berdasarkan tabel dan heatmap loading factor, setiap komponen utama dapat diinterpretasikan maknanya secara substantif sebagai berikut.
PC1 ??? “Ukuran dan Kapasitas Blok Sensus”
PC1 menunjukkan loading positif yang kuat pada variabel-variabel yang
mencerminkan ukuran fisik dan kapasitas blok sensus:
total_rooms, total_bedrooms,
households, dan population. Blok dengan nilai
PC1 tinggi adalah blok besar yang dihuni banyak rumah tangga dan
penduduk. Komponen ini pada dasarnya merangkum seberapa besar
ukuran suatu blok sensus sebuah dimensi tunggal yang sebelumnya
tersebar di empat variabel yang saling berkorelasi sangat tinggi (VIF
6???35).
PC2 ??? “Kemakmuran dan Kualitas Hunian”
PC2 menangkap kontras antara variabel ekonomi
(median_income dan rooms_per_household dengan
loading positif) versus variabel kepadatan seperti
bedrooms_ratio (loading negatif). Komponen ini
merepresentasikan tingkat kemakmuran dan kualitas relatif
hunian kawasan dengan PC2 tinggi adalah kawasan berpendapatan
tinggi dengan hunian yang luas (sedikit proporsi kamar tidur dari total
ruangan), mencirikan hunian berkelas atau mewah.
PC3 ??? “Posisi Geografis Utara-Selatan”
PC3 didominasi oleh variabel latitude dengan loading
yang besar. Komponen ini merepresentasikan posisi geografis
utara-selatan di California kawasan Bay Area dan Silicon Valley
di utara versus kawasan Los Angeles dan San Diego di selatan.
PC4 ??? “Posisi Geografis Timur-Barat dan Usia Bangunan”
PC4 menangkap variasi pada longitude dan sedikit dari
housing_median_age. Komponen ini merepresentasikan
posisi geografis timur-barat (pesisir vs. pedalaman)
yang juga berkaitan dengan pola perkembangan historis bangunan di
California.
PC5 ??? “Kepadatan Penghuni per Rumah Tangga”
PC5 menunjukkan loading yang menonjol pada
population_per_household dan merepresentasikan
kepadatan penghuni per unit rumah tangga apakah rumah
tangga di suatu blok cenderung kecil atau besar jumlah penghuninya.
5.6 Visualisasi PCA
5.6.1 Biplot PC1 vs PC2
fviz_pca_biplot(pca_result,
axes = c(1, 2),
geom.ind = "point",
col.ind = housing_clean$median_house_value,
gradient.cols = c("#d73027", "#fee090", "#1a9850"),
col.var = "black",
repel = TRUE,
alpha.ind = 0.4,
pointsize = 1.5,
arrowsize = 0.8,
labelsize = 3.8,
ggtheme = theme_bw(base_size = 12)) +
scale_color_gradient(low = "#d73027",
high = "#1a9850",
name = "Harga Rumah (USD)",
labels = dollar_format(prefix = "$", big.mark = ",")) +
labs(
title = "Biplot PCA ??? PC1 vs PC2",
subtitle = "Titik = blok sensus (warna = harga rumah) | Panah = arah & kekuatan loading variabel",
x = paste0("PC1 (", round(prop_var[1] * 100, 1), "% Variansi)"),
y = paste0("PC2 (", round(prop_var[2] * 100, 1), "% Variansi)")
) +
theme(
plot.title = element_text(face = "bold", size = 14),
plot.subtitle = element_text(size = 9),
legend.position = "right"
)Biplot di atas memvisualisasikan dua informasi sekaligus.
Titik merepresentasikan setiap blok sensus yang
diwarnai berdasarkan median_house_valuetitik hijau
menandakan harga rumah tinggi, titik merah menandakan harga rendah.
Panah menunjukkan arah loading setiap variabel asli:
variabel dengan panah searah saling berkorelasi positif, sedangkan panah
berlawanan arah berkorelasi negatif.
Terlihat bahwa median_income dan
rooms_per_household memiliki panah yang cenderung menuju
area titik-titik hijau (harga tinggi), mengonfirmasi bahwa kedua
variabel ini adalah prediktor paling kuat harga rumah. Sebaliknya,
kelompok total_rooms, total_bedrooms,
households, population memiliki panah yang
searah satu sama lain membuktikan multikolinearitas yang telah
terdeteksi sebelumnya namun tidak mengarah secara dominan ke area harga
tinggi, selaras dengan korelasi lemah keempat variabel tersebut terhadap
median_house_value.
5.6.2 Kontribusi Variabel ke PC1 & PC2
p_c1 <- fviz_contrib(pca_result, choice = "var", axes = 1,
fill = "#2c7fb8", color = "white",
ggtheme = theme_bw(base_size = 11)) +
labs(title = "Kontribusi Variabel ke PC1",
x = NULL, y = "Kontribusi (%)") +
theme(plot.title = element_text(face = "bold"),
axis.text.x = element_text(angle = 40, hjust = 1))
p_c2 <- fviz_contrib(pca_result, choice = "var", axes = 2,
fill = "#e74c3c", color = "white",
ggtheme = theme_bw(base_size = 11)) +
labs(title = "Kontribusi Variabel ke PC2",
x = NULL, y = "Kontribusi (%)") +
theme(plot.title = element_text(face = "bold"),
axis.text.x = element_text(angle = 40, hjust = 1))
grid.arrange(p_c1, p_c2, ncol = 2)Garis putus-putus pada grafik kontribusi menunjukkan nilai
rata-rata kontribusi jika setiap variabel berkontribusi secara
merata (~9,1% per variabel untuk 11 variabel). Variabel yang berada di
atas garis putus-putus merupakan penyusun utama komponen tersebut. Pada
PC1, kontributor utama adalah kelompok variabel ukuran blok, sedangkan
pada PC2 kontributor utama adalah median_income,
rooms_per_household, dan bedrooms_ratio sesuai
dengan interpretasi substantif yang telah dijelaskan sebelumnya.
5.6.3 Cos² ??? Kualitas Representasi Variabel
fviz_cos2(pca_result, choice = "var", axes = 1:2,
fill = "#27ae60",
color = "white",
ggtheme = theme_bw(base_size = 11)) +
labs(title = "Cos² Variabel pada PC1 + PC2",
subtitle = "Seberapa baik setiap variabel terwakili oleh dua komponen pertama",
x = NULL, y = "Cos² (Kualitas Representasi)") +
theme(
plot.title = element_text(face = "bold", size = 13),
plot.subtitle = element_text(size = 9),
axis.text.x = element_text(angle = 40, hjust = 1)
)Nilai cos² mengukur kualitas representasi suatu variabel pada ruang yang dibentuk oleh komponen-komponen terpilih. Nilai mendekati 1 berarti variabel sangat baik terwakili oleh dua komponen pertama, sedangkan nilai mendekati 0 berarti variabel lebih banyak terwakili oleh komponen-komponen selanjutnya.
6 Insight dan Kesimpulan
6.1 Variabel Paling Penting
insight_df <- data.frame(
Variabel = c("median_income", "latitude", "households",
"total_bedrooms", "population",
"rooms_per_household", "bedrooms_ratio",
"population_per_household"),
Forward_Selection = c("???", "???", "???", "???", "???", "???", "???", "???"),
Backward_Elim = c("???", "???", "???", "???", "???", "???", "???", "???"),
LASSO = c("???", "???", "???", "???", "???", "???", "???", "???"),
PC_Dominan = c("PC2", "PC3", "PC1", "PC1", "PC1",
"PC2", "PC2", "PC5"),
Korelasi_Target = c("+0,688", "+0,467", "+0,066",
"+0,050", "-0,025",
"+0,552", "-0,468", "-0,194"),
Kesimpulan = c("PALING PENTING ??? konsisten di semua metode",
"Penting ??? lokasi utara???selatan California",
"Penting ??? ukuran & kepadatan blok",
"Cukup penting ??? dampak negatif",
"Cukup penting ??? dampak negatif",
"Fitur baru penting (Backward + PC2)",
"Fitur baru penting (Backward + PC2)",
"Fitur baru kepadatan RT (LASSO + PC5)")
)
kable(insight_df,
caption = "Rekap Variabel Penting Berdasarkan Seluruh Metode Analisis",
col.names = c("Variabel", "Forward", "Backward",
"LASSO", "PC Dominan",
"Korelasi (vs. Target)", "Kesimpulan")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = TRUE) %>%
row_spec(1, bold = TRUE, background = "#eafaf1") %>%
row_spec(0, bold = TRUE) %>%
column_spec(1, bold = TRUE) %>%
column_spec(7, italic = TRUE)| Variabel | Forward | Backward | LASSO | PC Dominan | Korelasi (vs. Target) | Kesimpulan |
|---|---|---|---|---|---|---|
| median_income | ??? | ??? | ??? | PC2 | +0,688 | PALING PENTING ??? konsisten di semua metode |
| latitude | ??? | ??? | ??? | PC3 | +0,467 | Penting ??? lokasi utara???selatan California |
| households | ??? | ??? | ??? | PC1 | +0,066 | Penting ??? ukuran & kepadatan blok |
| total_bedrooms | ??? | ??? | ??? | PC1 | +0,050 | Cukup penting ??? dampak negatif |
| population | ??? | ??? | ??? | PC1 | -0,025 | Cukup penting ??? dampak negatif |
| rooms_per_household | ??? | ??? | ??? | PC2 | +0,552 | Fitur baru penting (Backward + PC2) |
| bedrooms_ratio | ??? | ??? | ??? | PC2 | -0,468 | Fitur baru penting (Backward + PC2) |
| population_per_household | ??? | ??? | ??? | PC5 | -0,194 | Fitur baru kepadatan RT (LASSO + PC5) |
Berdasarkan seluruh tahapan analisis korelasi, feature selection (Forward, Backward, LASSO), dan PCA ??? diperoleh gambaran yang konsisten mengenai variabel-variabel yang paling berpengaruh terhadap harga rumah di California.
median_income adalah variabel paling
penting secara konsisten: terpilih di semua metode feature selection
dengan koefisien terbesar, memiliki korelasi tertinggi dengan
median_house_value (r = 0,688), dan mendominasi PC2 dalam
PCA. Ini menegaskan bahwa kondisi ekonomi kawasan, bukan sekadar
fisik bangunan, adalah faktor paling dominan dalam menentukan
harga properti.
latitude konsisten terpilih oleh
seluruh metode, menunjukkan bahwa posisi geografis utara-selatan
California sangat menentukan harga kawasan Bay Area dan Silicon Valley
di utara jauh lebih mahal dibandingkan kawasan selatan maupun
pedalaman.
Kelompok variabel agregat blok
(total_rooms, total_bedrooms,
households, population) memiliki informasi
yang saling tumpang tindih (VIF 6???35) dan dirangkum secara efisien
oleh PC1 dalam PCA sebagai satu dimensi “ukuran
blok.”
Fitur-fitur baru (rooms_per_household,
bedrooms_ratio) terbukti memberikan nilai tambah nyata
terpilih oleh Backward Elimination dan berkontribusi signifikan pada
PC2, mengonfirmasi keberhasilan feature engineering mengekstraksi
informasi tersembunyi dari variabel mentah.
6.2 Apakah Reduksi Dimensi Berhasil?
reduksi_df <- data.frame(
Tahapan = c(
"1. Dataset Awal (prediktor numerik)",
"2. Setelah Feature Engineering",
"3. Feature Selection ??? Forward/Stepwise",
"4. Feature Selection ??? Backward (terbaik)",
"5. PCA (komponen optimal)"
),
Jumlah_Dimensi = c(9, 11, 5, 7, min(which(cumul_var >= 0.80))),
Informasi = c(
"100% (baseline)",
"Informasi baru ditambahkan",
"Adj. R² = 0,670",
"Adj. R² = 0,677 (terbaik)",
paste0(round(cumul_var[min(which(cumul_var >= 0.80))] * 100, 1),
"% variansi terjelaskan")
),
Keterangan = c(
"9 variabel numerik sebelum rekayasa fitur",
"3 fitur rasio derivatif ditambahkan",
"Variabel tidak signifikan dieliminasi bertahap",
"Keseimbangan terbaik parsimoni & akurasi",
"Komponen orthogonal, bebas multikolinearitas"
)
)
kable(reduksi_df,
caption = "Ringkasan Perjalanan Reduksi Dimensi",
col.names = c("Tahapan", "Jumlah Dimensi",
"Informasi Dipertahankan", "Keterangan")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = TRUE) %>%
row_spec(0, bold = TRUE) %>%
column_spec(1, bold = TRUE) %>%
row_spec(c(4, 5), background = "#eafaf1", bold = TRUE)| Tahapan | Jumlah Dimensi | Informasi Dipertahankan | Keterangan |
|---|---|---|---|
|
9 | 100% (baseline) | 9 variabel numerik sebelum rekayasa fitur |
|
11 | Informasi baru ditambahkan | 3 fitur rasio derivatif ditambahkan |
|
5 | Adj. R² = 0,670 | Variabel tidak signifikan dieliminasi bertahap |
|
7 | Adj. R² = 0,677 (terbaik) | Keseimbangan terbaik parsimoni & akurasi |
|
4 | 80.4% variansi terjelaskan | Komponen orthogonal, bebas multikolinearitas |
Reduksi dimensi dalam project ini dapat dinilai berhasil berdasarkan tiga bukti utama.
Pertama, feature engineering berhasil mengubah
variabel mentah berkorelasi tinggi menjadi rasio yang lebih informatif.
rooms_per_household (r = +0,55) dan
bedrooms_ratio (r = ???0,47) memiliki korelasi yang jauh
lebih kuat dengan harga dibandingkan variabel aslinya
total_rooms (r = +0,13) dan total_bedrooms (r
= +0,05).
Kedua, feature selection berhasil memangkas dari 11 variabel menjadi 7 (Backward) atau 5 (Forward) tanpa kehilangan kekuatan penjelas yang signifikan. Model Backward dengan 7 variabel mencapai Adjusted R² = 0,677 ??? menjelaskan 67,7% variasi harga rumah.
Ketiga, PCA berhasil merangkum 11 variabel menjadi 4 komponen utama yang secara bersama-sama menjelaskan lebih dari 80% variansi total data, dan seluruh komponen bersifat orthogonal (bebas multikolinearitas).
6.3 Makna Substantif Principal Components
pc_interp_df <- data.frame(
Komponen = paste0("PC", 1:5),
Nama = c("Ukuran & Kapasitas Blok Sensus",
"Kemakmuran & Kualitas Hunian",
"Posisi Geografis (Utara???Selatan)",
"Posisi Geografis (Timur???Barat / Pesisir)",
"Kepadatan Penghuni per Rumah Tangga"),
Variabel_Dominan = c(
"total_rooms, total_bedrooms, households, population (+)",
"median_income, rooms_per_household (+) | bedrooms_ratio (???)",
"latitude (+)",
"longitude (+) | housing_median_age",
"population_per_household (+)"
),
Variansi = paste0(round(prop_var[1:5] * 100, 1), "%"),
Relevansi_Harga = c(
"Tidak langsung ??? ukuran blok ??? harga tinggi",
"LANGSUNG ??? kawasan makmur = harga tinggi",
"Langsung ??? utara California lebih mahal",
"Moderat ??? pesisir umumnya lebih mahal",
"Tidak langsung ??? kepadatan ??? = harga ???"
)
)
kable(pc_interp_df,
caption = "Interpretasi Substantif Lima Komponen Utama PCA",
col.names = c("PC", "Nama Substantif", "Variabel Dominan",
"% Variansi", "Relevansi thd Harga Rumah")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = TRUE) %>%
row_spec(0, bold = TRUE) %>%
column_spec(1, bold = TRUE) %>%
column_spec(2, bold = TRUE, color = "#2c3e50") %>%
row_spec(2, background = "#eafaf1")| PC | Nama Substantif | Variabel Dominan | % Variansi | Relevansi thd Harga Rumah |
|---|---|---|---|---|
| PC1 | Ukuran & Kapasitas Blok Sensus | total_rooms, total_bedrooms, households, population (+) | 35.5% | Tidak langsung ??? ukuran blok ??? harga tinggi |
| PC2 | Kemakmuran & Kualitas Hunian | median_income, rooms_per_household (+) | bedrooms_ratio (???) | 19% | LANGSUNG ??? kawasan makmur = harga tinggi |
| PC3 | Posisi Geografis (Utara???Selatan) | latitude (+) | 16.7% | Langsung ??? utara California lebih mahal |
| PC4 | Posisi Geografis (Timur???Barat / Pesisir) | longitude (+) | housing_median_age | 9.2% | Moderat ??? pesisir umumnya lebih mahal |
| PC5 | Kepadatan Penghuni per Rumah Tangga | population_per_household (+) | 7.7% | Tidak langsung ??? kepadatan ??? = harga ??? |
6.4 Insight Utama
Berdasarkan seluruh rangkaian analisis, diperoleh enam insight utama mengenai pasar perumahan California (data Sensus 1990).
Insight 1 ??? Pendapatan adalah Penentu Utama Harga Rumah
median_income secara konsisten menjadi variabel
terpenting di semua tahap analisis, dengan korelasi r = 0,688 dan
koefisien regresi terbesar di semua model stepwise (β ???
34.880???37.590 per 10 ribu USD pendapatan). Ini menegaskan bahwa
ekonomi kawasan, bukan sekadar kondisi fisik bangunan,
adalah faktor paling dominan dalam menentukan harga properti. Wilayah
dengan pendapatan tinggi mencerminkan daya beli yang kuat, permintaan
properti yang besar, dan kualitas layanan publik yang baik seluruh
faktor ini mendorong harga rumah naik.
Insight 2 ??? Lokasi Geografis Sangat Menentukan
latitude terpilih di semua metode feature selection dan
mendominasi PC3 dalam PCA. Kawasan di utara California (Bay Area,
Silicon Valley) secara konsisten memiliki harga rumah jauh lebih tinggi
mencerminkan konsentrasi industri teknologi, tingginya permintaan
properti, dan keterbatasan lahan di kawasan tersebut.
Insight 3 ??? Kualitas Ruang Lebih Penting dari Kuantitas Kamar
Fitur baru rooms_per_household (r = +0,55) dan
bedrooms_ratio (r = ???0,47) jauh lebih informatif dari
variabel mentahnya (total_rooms r = +0,13;
total_bedrooms r = +0,05). Kualitas dan efisiensi
penggunaan ruang per rumah tangga lebih relevan bagi harga
properti daripada jumlah total kamar di seluruh blok sensus. Ini
membuktikan nilai tambah dari proses feature engineering.
Insight 4 ??? Empat Variabel Mentah Berisi Informasi Redundan
total_rooms, total_bedrooms,
households, dan population saling berkorelasi
sangat tinggi (0,86???0,98) dengan VIF 6???35. Pada dasarnya keempat
variabel ini mengukur hal yang sama: seberapa besar ukuran blok
sensus. PCA mengonfirmasi ini dengan merangkum semua
informasinya ke dalam satu komponen (PC1) yang efisien.
Insight 5 ??? Kepadatan Penduduk Berdampak Negatif terhadap Harga
Variabel-variabel yang mencerminkan kepadatan population
(koefisien negatif di semua model), total_bedrooms
(koefisien negatif), dan population_per_household (dipilih
LASSO dengan koefisien negatif) semuanya berkorelasi negatif dengan
harga rumah. Kawasan yang terlalu padat umumnya kehilangan nilai
eksklusivitas dan kenyamanan yang mendorong harga turun.
Insight 6 ??? Reduksi Dimensi Efektif dan Substantif
Kombinasi feature engineering, feature selection, dan PCA berhasil memadatkan 11 variabel menjadi representasi yang lebih ringkas tanpa kehilangan substansi analisis. Model 7 variabel (Backward Elimination) menjelaskan 67,7% variasi harga rumah, sementara PCA merangkum ke dalam komponen orthogonal yang bebas multikolinearitas dan masing-masing dapat dimaknai secara substantif: ukuran blok (PC1), kemakmuran (PC2), dan lokasi (PC3???PC4).