Clustering Binary Dataset dengan Menggunakan Pendekatan Meta Heuristic
Travelling Salesperson Problem dan Spiral Optimization Algorithm
Pendahuluan
Pada tulisan kali ini saya akan menggunakan dua algoritma meta heuristic, yakni TSP dan SDOA untuk clustering suatu data tertentu.
Biasanya untuk melakukan clustering, saya mengandalkan unsupervised learning seperti k-means clustering. Namun untuk suatu data yang semuanya berisi binary, saya rasa kurang tepat jika menggunakan k-means clustering.
Saya akan mencoba cara baru dalam melakukan clustering dengan memanfaatkan perhitungan jarak, prinsip TSP, dan optimisasi dengan SDOA.
Data yang Digunakan
Saya memiliki data berisi profil 50 orang sebagai berikut:
Ada 12
atribut yang masing-masing merupakan data bertipe binary.
Tujuan
Melakukan clustering dari data binary yang diberikan menggunakan prinsip TSP dan SDOA.
Metode dan Tahapan Pengerjaan
Saya akan coba jelaskan metode pengerjaan clustering dengan TSP dan SDOA.
Flowchart
Berikut adalah flowchart yang akan dikerjakan:
Perhitungan Jarak
Jarak didefinisikan sebagai ukuran yang mengindikasikan persamaan atau pertaksamaan dari dua id
data. Sepasang data dikatakan sama jika jarak antar keduanya adalah nol. Sedangkan sepasang data dikatakan tidak sama jika ada jarak antara keduanya.
Perhitungan jarak untuk data bertipe binary saya akan definisikan sebagai:
d(i,j)={0,xif=xjf1,lainnya
Dalam R berikut function-nya:
= function(a,b){
jarak_biner = sum(a != b) # beri nilai 1 jika berbeda lalu dijumlahkan
jarak return(jarak) # output function
}
Output dari tahapan ini adalah matriks jarak antar id
.
Berikut adalah proses perhitungannya:
# bikin matriks dulu
= nrow(df)
N = matrix(0,ncol = N,nrow = N)
mat_final
# proses menghitung matriks
= df %>% as.matrix() %>% t()
df_t
# proses perhitungan matriks jarak
for(i in 1:N){
for(j in 1:N){
= jarak_biner(df_t[,i],df_t[,j])
mat_final[i,j]
} }
TSP
Algoritma TSP memiliki input berupa matriks jarak kemudian menghitung dan menentukan rute terpendek dari matriks tersebut sehingga semua titik terlewati. Atas prinsip tersebut, kita akan melakukan clustering dengan cara mengelompokkan id
mana saja yang menghasilkan rute-rute terpendek.
Misalkan saya hendak membuat 4
clusters, artinya saya akan mencari 4
kelompok id
yang menghasilkan total rute terpendek dari matriks jarak masing-masing.
Saya definisikan objective function sebagai berikut:
= 1:nrow(df)
id
# bikin objective function untuk 4 clusters
= function(tes){
obj_func = round(tes)
tes if(min(tes) < 1 | max(tes) > 4){
= 999999
ztot
}else{
= id[which(tes == 1)]
id_1 = id[which(tes == 2)]
id_2 = id[which(tes == 3)]
id_3 = id[which(tes == 4)]
id_4
= mat_final[id_1,id_1]
temp_1 = mat_final[id_2,id_2]
temp_2 = mat_final[id_3,id_3]
temp_3 = mat_final[id_4,id_4]
temp_4
= as.TSP(temp_1)
problem_1 = solve_TSP(problem_1)
hasil_1 = tour_length(hasil_1)
z1
= as.TSP(temp_2)
problem_2 = solve_TSP(problem_2)
hasil_2 = tour_length(hasil_2)
z2
= as.TSP(temp_3)
problem_3 = solve_TSP(problem_3)
hasil_3 = tour_length(hasil_3)
z3
= as.TSP(temp_4)
problem_4 = solve_TSP(problem_4)
hasil_4 = tour_length(hasil_4)
z4
= (z1 + z2 + z3 + z4)
ztot
}return(ztot)
}
SDOA
Salah satu function yang penting pada SDOA adalah pendefinisian matriks rotasi. Berikut adalah script dan pendefinisiannya:
# function matriks rotasi
= function(theta,n){
buat_rot_mat # buat template sebuah matriks identitas
= matrix(0,ncol = n,nrow = n)
temp_mat diag(temp_mat) = 1
# buat matriks identitas terlebih dahulu
= temp_mat
mat_rot
for(i in 1:(n-1)){
for(j in 1:i){
= temp_mat
temp = n-i
idx = n+1-j
idy # print(paste0("Matriks rotasi untuk ",idx," - ",idy,": DONE"))
= cos(theta)
temp[idx,idx] = -sin(theta)
temp[idx,idy] = sin(theta)
temp[idy,idx] = cos(theta)
temp[idy,idy] # assign(paste0("M",idx,idy),temp)
= mat_rot %*% temp
mat_rot = mat_rot
mat_rot
}
}return(mat_rot)
}
# bikin matriks rotasinya
= buat_rot_mat(2*pi/30,50) A_rot
Sekarang saya akan mulai proses SDOA untuk menemukan cluster yang terbaik:
# kita mulai spiralnya
= 900
N_spiral = 1:N_spiral
id_calon = vector("list",N_spiral)
calon = c()
f_hit for(i in 1:N_spiral){
= runif(50,.55,4.45)
calon[[i]] = obj_func(calon[[i]])
f_hit[i]
}
for(ikanx in 1:30){
# penentuan calon paling minimum
= id_calon[which(f_hit == min(f_hit))] %>% min()
id_min = calon[[id_min]]
pusat
# proses rotasi semua calon
for(i in 1:N_spiral){
= calon[[i]]
Xt = A_rot %*% (Xt - pusat)
X = pusat + (.5 * X)
X = X
calon[[i]] = obj_func(calon[[i]])
f_hit[i]
} }
Hasil Perhitungan
Berikut adalah hasil teroptimal yang didapatkan:
= id_calon[which(f_hit == min(f_hit))] %>% min()
id_min = calon[[id_min]] %>% round()
cluster # tabulasi berapa banyak id per cluster
table(cluster)
## cluster
## 1 2 3 4
## 9 18 12 11
# totak jarak yang dihasilkan
min(f_hit)
## [1] 60