library(ggplot2)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(readxl)
library(cluster)
library(factoextra)
## Welcome to factoextra!
## Want to learn more? See two factoextra-related books at https://www.datanovia.com/en/product/practical-guide-to-principal-component-methods-in-r/
library(dbscan)
## 
## Attaching package: 'dbscan'
## The following object is masked from 'package:stats':
## 
##     as.dendrogram

Load Data

Dataset yang digunakan merupakan data valuasi properti. Data dibaca dari file Excel kemudian ditampilkan sebagian isinya menggunakan fungsi head() serta struktur variabel menggunakan str() untuk memastikan data telah terbaca dengan benar.

data <- read_excel("Real estate valuation data set.xlsx")

head(data)
## # A tibble: 6 × 8
##      No `X1 transaction date` `X2 house age` X3 distance to the nearest MRT st…¹
##   <dbl>                 <dbl>          <dbl>                               <dbl>
## 1     1                 2013.           32                                  84.9
## 2     2                 2013.           19.5                               307. 
## 3     3                 2014.           13.3                               562. 
## 4     4                 2014.           13.3                               562. 
## 5     5                 2013.            5                                 391. 
## 6     6                 2013.            7.1                              2175. 
## # ℹ abbreviated name: ¹​`X3 distance to the nearest MRT station`
## # ℹ 4 more variables: `X4 number of convenience stores` <dbl>,
## #   `X5 latitude` <dbl>, `X6 longitude` <dbl>,
## #   `Y house price of unit area` <dbl>
str(data)
## tibble [414 × 8] (S3: tbl_df/tbl/data.frame)
##  $ No                                    : num [1:414] 1 2 3 4 5 6 7 8 9 10 ...
##  $ X1 transaction date                   : num [1:414] 2013 2013 2014 2014 2013 ...
##  $ X2 house age                          : num [1:414] 32 19.5 13.3 13.3 5 7.1 34.5 20.3 31.7 17.9 ...
##  $ X3 distance to the nearest MRT station: num [1:414] 84.9 306.6 562 562 390.6 ...
##  $ X4 number of convenience stores       : num [1:414] 10 9 5 5 5 3 7 6 1 3 ...
##  $ X5 latitude                           : num [1:414] 25 25 25 25 25 ...
##  $ X6 longitude                          : num [1:414] 122 122 122 122 122 ...
##  $ Y house price of unit area            : num [1:414] 37.9 42.2 47.3 54.8 43.1 32.1 40.3 46.7 18.8 22.1 ...

Rename Kolom

Nama kolom pada dataset diubah agar lebih sederhana dan mudah digunakan pada proses analisis selanjutnya. Penamaan ulang ini juga bertujuan menghindari kesalahan pemanggilan variabel saat pemodelan.

colnames(data) <- c("No","date","age","distance","stores","lat","long","price")

Statistik Deskriptif

Statistik deskriptif dilakukan untuk melihat gambaran umum dataset seperti nilai minimum, maksimum, rata-rata, dan distribusi data. Tahap ini membantu memahami karakteristik awal data sebelum dilakukan proses clustering.

summary(data)
##        No             date           age            distance      
##  Min.   :  1.0   Min.   :2013   Min.   : 0.000   Min.   :  23.38  
##  1st Qu.:104.2   1st Qu.:2013   1st Qu.: 9.025   1st Qu.: 289.32  
##  Median :207.5   Median :2013   Median :16.100   Median : 492.23  
##  Mean   :207.5   Mean   :2013   Mean   :17.713   Mean   :1083.89  
##  3rd Qu.:310.8   3rd Qu.:2013   3rd Qu.:28.150   3rd Qu.:1454.28  
##  Max.   :414.0   Max.   :2014   Max.   :43.800   Max.   :6488.02  
##      stores            lat             long           price       
##  Min.   : 0.000   Min.   :24.93   Min.   :121.5   Min.   :  7.60  
##  1st Qu.: 1.000   1st Qu.:24.96   1st Qu.:121.5   1st Qu.: 27.70  
##  Median : 4.000   Median :24.97   Median :121.5   Median : 38.45  
##  Mean   : 4.094   Mean   :24.97   Mean   :121.5   Mean   : 37.98  
##  3rd Qu.: 6.000   3rd Qu.:24.98   3rd Qu.:121.5   3rd Qu.: 46.60  
##  Max.   :10.000   Max.   :25.01   Max.   :121.6   Max.   :117.50

Prepocessing

preprocessing dilakukan untuk memastikan kualitas data sebelum proses clustering. Tahapan yang dilakukan meliputi pengecekan missing value, pemilihan variabel numerik, serta normalisasi data agar setiap variabel memiliki skala yang sama. Tahapan preprocessing sangat penting karena metode clustering sensitif terhadap skala data dan kualitas data.

Cek Missing Value

Pengecekan missing value dilakukan untuk memastikan tidak terdapat data kosong yang dapat mempengaruhi hasil clustering. Dataset yang baik seharusnya tidak memiliki nilai yang hilang.

colSums(is.na(data))
##       No     date      age distance   stores      lat     long    price 
##        0        0        0        0        0        0        0        0

Hasil pengecekan menunjukkan bahwa tidak terdapat missing value pada dataset sehingga data siap digunakan pada tahap berikutnya.

Pilih Variabel untuk Clustering

Tidak semua variabel digunakan dalam clustering. Variabel yang dipilih adalah variabel numerik yang relevan terhadap harga properti, yaitu usia rumah, jarak ke MRT, jumlah toko, koordinat lokasi, dan harga rumah.

data_clust <- data %>%
  select(age, distance, stores, lat, long, price)

head(data_clust)
## # A tibble: 6 × 6
##     age distance stores   lat  long price
##   <dbl>    <dbl>  <dbl> <dbl> <dbl> <dbl>
## 1  32       84.9     10  25.0  122.  37.9
## 2  19.5    307.       9  25.0  122.  42.2
## 3  13.3    562.       5  25.0  122.  47.3
## 4  13.3    562.       5  25.0  122.  54.8
## 5   5      391.       5  25.0  122.  43.1
## 6   7.1   2175.       3  25.0  122.  32.1

Standardisasi

Standardisasi dilakukan agar seluruh variabel memiliki skala yang sama. Hal ini penting karena metode clustering berbasis jarak sangat dipengaruhi oleh perbedaan skala antar variabel.

data_scaled <- scale(data_clust)

head(data_scaled)
##             age   distance     stores        lat       long       price
## [1,]  1.2541110 -0.7915373  2.0049816  1.1240698  0.4482199 -0.00589375
## [2,]  0.1568964 -0.6158665  1.6654877  0.9113415  0.4006542  0.31013196
## [3,] -0.3873220 -0.4135150  0.3075125  1.4850633  0.6873517  0.68495316
## [4,] -0.3873220 -0.4135150  0.3075125  1.4850633  0.6873517  1.23616080
## [5,] -1.1158725 -0.5493321  0.3075125  0.8331800  0.5922203  0.37627688
## [6,] -0.9315405  0.8645401 -0.3714751 -0.4818677 -1.3566716 -0.43216099

Data hasil standardisasi memiliki rata-rata mendekati 0 dan standar deviasi 1.

Scatter Plot Awal

Visualisasi awal dilakukan untuk melihat hubungan antara jarak ke MRT dan harga rumah.

ggplot(data_clust, aes(x = distance, y = price)) +
  geom_point() +
  labs(title = "Scatter Plot Awal",
       x = "Distance to MRT",
       y = "House Price")

Terlihat kecenderungan hubungan negatif, dimana semakin jauh jarak ke MRT maka harga rumah cenderung menurun.

Clustering KMeans

Metode pertama yang digunakan dalam penelitian ini adalah K-Means Clustering. Algoritma ini mengelompokkan data berdasarkan kedekatan jarak antar objek. Sebelum menentukan jumlah cluster, digunakan Elbow Method untuk menemukan jumlah cluster optimal. Metode ini cocok digunakan untuk segmentasi pasar karena menghasilkan cluster yang jelas dan mudah diinterpretasikan

Elbow Method

set.seed(123)

fviz_nbclust(data_scaled, kmeans, method = "wss") +
  labs(title = "Elbow Method")

Berdasarkan grafik Elbow Method, terlihat bahwa penurunan nilai Within Sum of Squares (WSS) mulai melandai setelah jumlah cluster k = 3. Oleh karena itu, jumlah cluster optimal yang digunakan pada metode K-Means adalah 3 cluster. Penurunan WSS sangat tajam hingga k = 3 kemudian mulai melandai, sehingga k = 3 dipilih sebagai jumlah cluster optimal.

KMeans

Proses K-Means dilakukan dengan jumlah cluster sebanyak 3 dan nstart = 25 untuk mendapatkan hasil cluster yang lebih stabil.

kmeans_result <- kmeans(data_scaled, centers = 3, nstart = 25)

kmeans_result
## K-means clustering with 3 clusters of sizes 226, 151, 37
## 
## Cluster means:
##           age   distance     stores        lat       long      price
## 1  0.01921052 -0.5657083  0.7416440  0.4633728  0.5093507  0.6181579
## 2 -0.08178775  0.2051995 -0.7964044 -0.2204185 -0.2156032 -0.5733091
## 3  0.21644251  2.6179715 -1.2798504 -1.9307852 -2.2312753 -1.4360541
## 
## Clustering vector:
##   [1] 1 1 1 1 1 2 1 1 3 2 2 1 1 2 1 1 1 2 1 1 2 1 2 1 1 2 1 2 1 1 3 1 2 1 1 2 2
##  [38] 2 1 1 3 3 1 1 1 1 1 1 3 3 1 2 2 1 1 2 1 1 3 1 2 1 2 1 2 1 1 1 1 1 1 1 1 3
##  [75] 1 2 1 2 2 2 1 1 1 3 1 1 2 3 2 3 2 2 2 2 1 1 1 2 1 1 1 2 1 1 1 1 1 2 2 2 1
## [112] 1 2 2 1 1 3 3 2 1 2 1 1 2 1 1 1 1 1 1 1 2 1 1 1 2 1 1 2 1 1 2 1 1 2 1 2 1
## [149] 3 1 1 1 2 1 3 3 2 1 1 1 1 1 3 1 2 2 1 1 1 2 3 1 1 1 1 2 3 1 1 2 3 1 2 3 2
## [186] 2 2 2 1 3 1 2 1 1 3 2 1 1 1 1 2 1 2 1 2 2 1 2 2 1 1 2 2 1 2 1 2 1 1 1 1 2
## [223] 1 2 1 1 3 1 2 2 2 3 3 1 2 1 1 2 2 2 2 1 2 1 2 1 1 2 2 3 1 2 1 2 1 3 2 2 1
## [260] 2 2 2 1 2 1 1 2 1 1 2 1 1 1 2 1 1 2 2 1 2 1 1 2 2 1 1 1 2 1 1 2 1 2 1 1 2
## [297] 1 2 3 1 1 2 2 2 2 1 2 2 1 2 2 1 1 1 1 2 1 2 1 2 3 1 2 1 2 1 1 1 2 3 2 3 2
## [334] 1 1 1 2 1 1 1 2 2 1 1 2 2 2 3 1 1 1 2 2 2 2 1 2 1 1 2 1 1 1 1 1 2 2 2 2 2
## [371] 1 1 1 2 1 2 2 1 1 1 1 1 3 1 3 1 2 2 2 1 1 2 1 1 3 1 2 1 2 2 1 2 2 1 1 1 1
## [408] 2 2 3 1 1 1 1
## 
## Within cluster sum of squares by cluster:
## [1] 610.91693 537.79904  57.54701
##  (between_SS / total_SS =  51.3 %)
## 
## Available components:
## 
## [1] "cluster"      "centers"      "totss"        "withinss"     "tot.withinss"
## [6] "betweenss"    "size"         "iter"         "ifault"

Visualisasi hasil cluster

Visualisasi cluster dilakukan untuk melihat pemisahan data pada ruang dua dimensi hasil reduksi PCA.

fviz_cluster(kmeans_result, data = data_scaled)

Terlihat bahwa data terbagi menjadi tiga kelompok utama yang cukup terpisah.

Menambahkan label cluster ke data

Label cluster ditambahkan ke dataset agar karakteristik tiap cluster dapat dianalisis lebih lanjut.

data_kmeans <- data_clust
data_kmeans$cluster <- kmeans_result$cluster

head(data_kmeans)
## # A tibble: 6 × 7
##     age distance stores   lat  long price cluster
##   <dbl>    <dbl>  <dbl> <dbl> <dbl> <dbl>   <int>
## 1  32       84.9     10  25.0  122.  37.9       1
## 2  19.5    307.       9  25.0  122.  42.2       1
## 3  13.3    562.       5  25.0  122.  47.3       1
## 4  13.3    562.       5  25.0  122.  54.8       1
## 5   5      391.       5  25.0  122.  43.1       1
## 6   7.1   2175.       3  25.0  122.  32.1       2

Karakteristik tiap cluster

Perhitungan rata-rata setiap variabel pada tiap cluster dilakukan untuk mengetahui karakteristik masing-masing kelompok properti.

aggregate(data_kmeans[,1:6], 
          by = list(Cluster = data_kmeans$cluster), 
          mean)
##   Cluster      age  distance    stores      lat     long    price
## 1       1 17.93142  369.8999 6.2787611 24.97478 121.5412 46.39115
## 2       2 16.78079 1342.8699 1.7483444 24.96629 121.5301 30.17947
## 3       3 20.17838 4388.0526 0.3243243 24.94507 121.4991 18.44054

Cluster dapat diinterpretasikan sebagai area premium, menengah, dan pinggiran berdasarkan harga, fasilitas, dan jarak ke MRT.

Hierarchical Clustering

Metode kedua yang digunakan adalah Hierarchical Clustering. Metode ini membentuk cluster secara bertahap berdasarkan jarak antar data dan divisualisasikan menggunakan dendrogram. Metode ini memberikan gambaran struktur hubungan antar data melalui dendrogram.

## Matriks Jarak
dist_matrix <- dist(data_scaled)

## Proses Hierarchical Clustering (Ward)
hc <- hclust(dist_matrix, method = "ward.D2")

## Dendrogram
plot(hc, labels = FALSE, main = "Dendrogram Hierarchical Clustering")
rect.hclust(hc, k = 3, border = "red")

## Ambil Cluster
hc_cluster <- cutree(hc, k = 3)
table(hc_cluster)
## hc_cluster
##   1   2   3 
## 231 147  36
## Visualisasi Cluster
fviz_cluster(list(data = data_scaled, cluster = hc_cluster))

Matriks jarak digunakan untuk menghitung sebagai dasar pembentukan hierarchical clustering menggunakan metode Ward. Sedangkan Dendrogram bertujuan menunjukkan pembentukan tiga kelompok utama yang konsisten dengan K-Means.

DBScan Clustering

Metode ketiga yang digunakan adalah DBSCAN (Density-Based Spatial Clustering). Metode ini mengelompokkan data berdasarkan kepadatan dan mampu mendeteksi outlier. Metode ini mampu menemukan outlier yang tidak terdeteksi metode lain.

Menentukan Nilai eps

kNNdistplot(data_scaled, k = 5)
abline(h = 1.5, col = "red")

db <- dbscan(data_scaled, eps = 1.5, minPts = 5)
db
## DBSCAN clustering for 414 objects.
## Parameters: eps = 1.5, minPts = 5
## Using euclidean distances and borderpoints = TRUE
## The clustering contains 3 cluster(s) and 6 noise points.
## 
##   0   1   2   3 
##   6 367  34   7 
## 
## Available fields: cluster, eps, minPts, metric, borderPoints
# Visualisasi DBScan
fviz_cluster(db, data = data_scaled)

Grafik kNN distance digunakan untuk menentukan parameter eps. Beberapa data teridentifikasi sebagai noise/outlier.

Perbandingan Metode

Berdasarkan hasil eksperimen, ketiga metode clustering menghasilkan tersebut mempunyai karakteristik yang berbeda. K-Means menghasilkan pembagian cluster yang paling seimbang. Hierarchical Clustering menghasilkan struktur hubungan antar cluster yang dapat dilihat melalui dendrogram. DBSCAN mampu mendeteksi outlier yang tidak dapat dilakukan oleh K-Means. Secara keseluruhan, metode K-Means memberikan hasil clustering paling stabil untuk dataset ini.

Kesimpulan

Penelitian ini berhasil melakukan segmentasi wilayah properti menggunakan tiga metode clustering, yaitu K-Means, Hierarchical, dan DBSCAN. Berdasarkan evaluasi, jumlah cluster optimal adalah 3 cluster. Hasil clustering menunjukkan adanya perbedaan karakteristik wilayah berdasarkan jarak ke transportasi, fasilitas sekitar, dan harga properti. Metode K-Means memberikan performa terbaik dalam mengelompokkan data.