Processing math: 100%

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:

jarak_biner = function(a,b){
  jarak = sum(a != b)     # beri nilai 1 jika berbeda lalu dijumlahkan
  return(jarak)           # output function
}

Output dari tahapan ini adalah matriks jarak antar id.

Berikut adalah proses perhitungannya:

# bikin matriks dulu
N = nrow(df)
mat_final = matrix(0,ncol = N,nrow = N)

# proses menghitung matriks
df_t = df %>% as.matrix() %>% t()

# proses perhitungan matriks jarak
for(i in 1:N){
  for(j in 1:N){
    mat_final[i,j] = jarak_biner(df_t[,i],df_t[,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:

id = 1:nrow(df)

# bikin objective function untuk 4 clusters
obj_func = function(tes){
  tes = round(tes)
  if(min(tes) < 1 | max(tes) > 4){
    ztot = 999999
  }
  else{
    id_1 = id[which(tes == 1)]
    id_2 = id[which(tes == 2)]
    id_3 = id[which(tes == 3)]
    id_4 = id[which(tes == 4)]
    
    temp_1 = mat_final[id_1,id_1]
    temp_2 = mat_final[id_2,id_2]
    temp_3 = mat_final[id_3,id_3]
    temp_4 = mat_final[id_4,id_4]
    
    problem_1 = as.TSP(temp_1)
    hasil_1 = solve_TSP(problem_1)
    z1 = tour_length(hasil_1)
    
    problem_2 = as.TSP(temp_2)
    hasil_2 = solve_TSP(problem_2)
    z2 = tour_length(hasil_2)
    
    problem_3 = as.TSP(temp_3)
    hasil_3 = solve_TSP(problem_3)
    z3 = tour_length(hasil_3)
    
    problem_4 = as.TSP(temp_4)
    hasil_4 = solve_TSP(problem_4)
    z4 = tour_length(hasil_4)
    
    ztot = (z1 + z2 + z3 + z4)
  }
  return(ztot)
}

SDOA

Salah satu function yang penting pada SDOA adalah pendefinisian matriks rotasi. Berikut adalah script dan pendefinisiannya:

# function matriks rotasi
buat_rot_mat = function(theta,n){
  # buat template sebuah matriks identitas
  temp_mat = matrix(0,ncol = n,nrow = n)
  diag(temp_mat) = 1
  
  # buat matriks identitas terlebih dahulu
  mat_rot = temp_mat
  
  for(i in 1:(n-1)){
    for(j in 1:i){
      temp = temp_mat
      idx = n-i
      idy = n+1-j
      # print(paste0("Matriks rotasi untuk ",idx," - ",idy,": DONE"))
      temp[idx,idx] = cos(theta)
      temp[idx,idy] = -sin(theta)
      temp[idy,idx] = sin(theta)
      temp[idy,idy] = cos(theta)
      # assign(paste0("M",idx,idy),temp)
      mat_rot = mat_rot %*% temp
      mat_rot = mat_rot 
    }
  }
  return(mat_rot)
}

# bikin matriks rotasinya
A_rot = buat_rot_mat(2*pi/30,50)

Sekarang saya akan mulai proses SDOA untuk menemukan cluster yang terbaik:

# kita mulai spiralnya
N_spiral = 900
id_calon = 1:N_spiral
calon = vector("list",N_spiral)
f_hit = c()
for(i in 1:N_spiral){
  calon[[i]] = runif(50,.55,4.45)
  f_hit[i] = obj_func(calon[[i]])
}

for(ikanx in 1:30){
  # penentuan calon paling minimum
  id_min = id_calon[which(f_hit == min(f_hit))] %>% min()
  pusat = calon[[id_min]]

  # proses rotasi semua calon
  for(i in 1:N_spiral){
    Xt = calon[[i]]
    X = A_rot %*% (Xt - pusat)
    X = pusat + (.5 * X)
    calon[[i]] = X
    f_hit[i] = obj_func(calon[[i]])
  }
}

Hasil Perhitungan

Berikut adalah hasil teroptimal yang didapatkan:

id_min = id_calon[which(f_hit == min(f_hit))] %>% min()
cluster = calon[[id_min]] %>% round()
# 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