Optimisasi Statistika - Genetic Algorithm
Video Pembelajaran - P10
Video Pembelajaran dapat diakses melalui link berikut : https://ipb.link/materiopstat
Algoritma Genetik
Pengantar
Algoritma Genetik (AG) adalah teknik pemrograman yang mengikuti prinsip evolusi biologis dan seleksi alam. Teknik ini sering digunakan dalam pencarian solusi optimal untuk masalah yang kompleks di mana metode tradisional tidak efisien. Dalam konteks statistika dan pemrograman linear, Algoritma Genetik dapat digunakan untuk optimasi model prediktif berdasarkan set data yang diberikan. AG beroperasi dengan menggunakan populasi dari solusi potensial yang disebut individu atau kromosom. Proses evolusi ini meliputi seleksi, rekombinasi (crossover), dan mutasi.
Langkah-langkah dasar dalam Algoritma Genetik adalah:
- Inisialisasi Populasi: Membuat populasi awal yang terdiri dari
individu-individu secara acak.
- Evaluasi: Menghitung kecocokan setiap individu dalam populasi.
- Seleksi: Memilih individu-individu terbaik sebagai orang tua yang
akan menghasilkan keturunan.
- Crossover (Rekombinasi): Menggabungkan informasi genetik dari orang
tua untuk menghasilkan keturunan baru.
- Mutasi: Memodifikasi keturunan secara acak untuk menjaga keragaman
genetik.
- Penggantian: Mengganti individu lama dengan yang baru untuk generasi
berikutnya.
- Iterasi: Mengulangi proses dari evaluasi hingga penggantian sampai kriteria berhenti terpenuhi.
Modul R Kuliah
Berikut adalah contoh implementasi Algoritma Genetik menggunakan bahasa pemrograman R:
# Create a vector for each column
x1 <- c(15, 11, 18, 10, 18, 13, 18, 12, 19, 10, 18, 17, 15, 15, 13, 19, 11)
x2 <- c(13, 15, 15, 16, 16, 16, 10, 16, 11, 16, 20, 13, 12, 11, 17, 12, 12)
x3 <- c(20, 19, 17, 13, 20, 18, 17, 12, 10, 19, 17, 19, 14, 11, 18, 13, 20)
x4 <- c(16, 20, 10, 20, 20, 10, 19, 17, 19, 17, 11, 15, 10, 12, 11, 11, 10)
x5 <- c(13, 14, 18, 11, 11, 10, 10, 10, 11, 19, 17, 20, 20, 19, 20, 16, 17)
x6 <- c(11, 19, 15, 12, 10, 17, 15, 17, 12, 16, 20, 20, 19, 16, 17, 16, 15)
x7 <- c(16, 10, 13, 20, 20, 20, 13, 19, 20, 15, 14, 18, 14, 14, 14, 18, 20)
x8 <- c(19, 14, 17, 20, 18, 11, 14, 11, 19, 10, 19, 17, 17, 17, 10, 17, 15)
x9 <- c(16, 15, 19, 12, 10, 16, 10, 19, 13, 10, 20, 16, 13, 14, 11, 20, 10)
x10 <- c(12, 17, 20, 10, 10, 17, 15, 12, 12, 20, 10, 17, 18, 12, 18, 19, 19)
x11 <- c(10, 14, 13, 20, 15, 12, 12, 18, 10, 12, 20, 17, 20, 12, 20, 17, 14)
y <- c(96, 88, 118, 91, 122, 102, 102, 101, 114, 89, 127, 111, 93, 90, 108, 117, 81)
# Combine the vectors into a dataframe
x <- data.frame(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)
dd <- x
dd$y <- yData dd akan digunakan pada analisis selanjutnya.
Contoh dasar genetic algorithm
a <- c(1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0)
xterpilih <- x[, which(a == 1)]
ddterpilih <- cbind(xterpilih, y)
regresi <- lm(y~., data=ddterpilih)
summary(regresi)$adj.r.squared## [1] 0.5193257
a <- c(1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1)
xterpilih <- x[, which(a == 1)]
ddterpilih <- cbind(xterpilih, y)
regresi <- lm(y~., ddterpilih)
summary(regresi)$adj.r.squared## [1] 0.645484
Tahapan genetic algorithm
Inisialisasi populasi
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
## [1,] 0 0 1 1 0 0 0 0 0 0 0
## [2,] 1 0 0 0 0 0 0 1 0 0 0
## [3,] 0 0 0 0 0 0 0 0 0 0 0
## [4,] 0 1 1 1 0 0 0 0 0 0 0
## [5,] 0 0 0 0 0 0 0 1 0 0 1
Bagian ini menginisialisasi populasi awal. Populasi terdiri dari 5
individu (baris), dan setiap individu memiliki 11 gen (kolom). Fungsi
rbinom digunakan untuk menghasilkan nilai biner acak (0
atau 1) untuk setiap gen.
Evaluasi fitness (R2-adj)
fitness = rep(0, npop)
for (i in 1:npop){
a <- populasi[i,]
xterpilih <- x[, which(a == 1)]
ddterpilih <- data.frame(cbind(xterpilih, y))
regresi <- lm(y~., data=ddterpilih)
fitness[i] = summary(regresi)$adj.r.squared
}Bagian ini mengevaluasi fitness setiap individu dalam populasi. Fitness dihitung sebagai nilai R-squared dari model regresi linier yang dibangun menggunakan subset fitur yang dipilih oleh gen dalam individu.
Seleksi
nseleksi <- 2
terbaik <- order(fitness, decreasing=TRUE)[1:nseleksi]
ambilterbaik = populasi[terbaik, ]Bagian ini melakukan seleksi individu terbaik dari populasi berdasarkan nilai fitness mereka. Dua individu dengan fitness tertinggi dipilih.
Crossover
anak1 <- c(ambilterbaik[1, 1:5], ambilterbaik[2, 6:11])
anak2 <- c(ambilterbaik[2, 1:5], ambilterbaik[1, 6:11])
populasi <- rbind(ambilterbaik, anak1, anak2)Bagian ini melakukan operasi crossover untuk menghasilkan individu baru. Dua individu terbaik dipilih sebagai orang tua, dan gen mereka dikombinasikan untuk menghasilkan dua individu baru (anak).
Mutasi
mutasi = matrix(rbinom(nrow(populasi)*ncol(populasi), 1, 1/10),
nrow=nrow(populasi), ncol=ncol(populasi))
populasi = abs(populasi - mutasi)Bagian ini melakukan operasi mutasi pada populasi. Setiap gen dalam setiap individu memiliki peluang tertentu untuk berubah (dari 0 menjadi 1, atau sebaliknya).
Tahapan Ver 2
Fungsi-fungsi
# Fungsi untuk evaluasi fitness
eval_fitness <- function(populasi, x, y) {
fitness = rep(0, nrow(populasi))
for (i in 1:nrow(populasi)){
a <- populasi[i,]
xterpilih <- x[, which(a == 1)]
ddterpilih <- data.frame(cbind(xterpilih, y))
regresi <- lm(y~., data=ddterpilih)
fitness[i] = summary(regresi)$adj.r.squared
}
return(fitness)
}
# Fungsi untuk seleksi
seleksi <- function(populasi, fitness, nseleksi) {
terbaik <- order(fitness, decreasing=TRUE)[1:nseleksi]
return(populasi[terbaik, ])
}
# Fungsi untuk crossover
crossover <- function(ambilterbaik) {
n_genes <- ncol(ambilterbaik)
half_point <- floor(n_genes / 2) # Adjust to always be an integer
populasi <- ambilterbaik
for (t1 in 1:(nrow(ambilterbaik)-1)){
for (t2 in (t1+1):nrow(ambilterbaik)){
anak1 <- c(ambilterbaik[t1, 1:half_point], ambilterbaik[t2, (half_point+1):n_genes])
anak2 <- c(ambilterbaik[t2, 1:half_point], ambilterbaik[t1, (half_point+1):n_genes])
populasi <- rbind(populasi, anak1, anak2)
}
}
return(populasi)
}
# Fungsi untuk mutasi
mutasi <- function(populasi, j) {
mutasi = matrix(rbinom(nrow(populasi)*ncol(populasi), 1, 1/(j*10)),
nrow=nrow(populasi), ncol=ncol(populasi))
return(abs(populasi - mutasi))
}Iterasi Genetic Algorithm
# Inisialisasi populasi
npop = 5
populasi <- matrix(rbinom(55, 1, 0.2), nrow=npop, ncol=11)
# Algoritma Genetik
simpanfitness = NULL
for (j in 1:50){
fitness = eval_fitness(populasi, x, y)
simpanfitness <- c(simpanfitness, mean(fitness))
ambilterbaik = seleksi(populasi, fitness, 4)
populasi = crossover(ambilterbaik)
if (j < 50){
populasi = mutasi(populasi, j)
}
}
# Plot fitness
plot(simpanfitness, type="b")Algoritma Genetika dengan Paket
genalg
Algoritma genetika adalah salah satu metode optimasi berbasis heuristic yang terinspirasi oleh proses seleksi alam. Konsep ini mensimulasikan evolusi biologis dengan komponen utama berupa populasi, kromosom, seleksi, crossover (rekombinasi), dan mutasi. Algoritma genetika cocok untuk memecahkan masalah optimasi non-linear dengan ruang solusi yang sangat besar.
Paket genalg di R memfasilitasi implementasi algoritma
genetika, mendukung kromosom berbentuk biner (binary
chromosome) dan titik-mengambang (floating-point
chromosome).
Komponen Utama Algoritma Genetika
Representasi Kromosom
Dalam konteks ini, kromosom direpresentasikan sebagai vektor biner:
\[ \mathbf{C} = \{c_1, c_2, \dots, c_n\}, \quad c_i \in \{0, 1\}, \quad \forall i = 1, 2, \dots, n \] Setiap gen (\(c_i\)) merepresentasikan pemilihan atau pengecualian fitur tertentu.Fungsi Fitness
Fungsi fitness mengevaluasi kualitas setiap kromosom berdasarkan tujuan optimasi. Misalnya, untuk seleksi fitur, fitness dapat berupa \(-R^2_{adj}\) (adjusted R-squared) dari model regresi:
\[ \text{fitness}(\mathbf{C}) = \begin{cases} -R^2_{adj}(\mathbf{C}) & \text{jika } |\mathbf{C}| > 0 \\ 0 & \text{jika } |\mathbf{C}| = 0 \end{cases} \] Di mana \(R^2_{adj}\) adalah koefisien determinasi yang disesuaikan.Seleksi
Seleksi bertujuan memilih kromosom terbaik berdasarkan fitness. Strategi umum adalah roulette wheel selection, di mana peluang seleksi proporsional terhadap fitness.Crossover
Crossover menggabungkan dua kromosom (induk) untuk menghasilkan kromosom baru (keturunan). Misalnya, dengan metode satu titik:
\[ \mathbf{C}_{\text{offspring}} = \mathbf{C}_{\text{parent1}}[1:k] \cup \mathbf{C}_{\text{parent2}}[k+1:n] \]Mutasi
Mutasi memperkenalkan variasi acak ke dalam populasi dengan mengubah nilai gen dengan probabilitas tertentu (\(\text{mutationChance}\)):
\[ c_i' = \begin{cases} 1 - c_i & \text{dengan probabilitas } p_{\text{mutasi}} \\ c_i & \text{dengan probabilitas } 1 - p_{\text{mutasi}} \end{cases} \]
Contoh Implementasi: Seleksi Fitur
Langkah 1: Menyiapkan Dataset Dataset sintetik dengan 10 fitur (\(X_1, X_2, \dots, X_{10}\)) dan satu variabel respons (\(y\)) dapat dibuat sebagai berikut:
set.seed(123)
n <- 100
p <- 10
X <- matrix(rnorm(n * p), ncol = p)
beta <- runif(p, -1, 1)
y <- X %*% beta + rnorm(n)
data <- data.frame(X, y = y)Langkah 2: Mendefinisikan Fungsi Fitness Fungsi fitness menggunakan regresi linier untuk mengevaluasi subset fitur berdasarkan \(-R^2_{adj}\):
fitness <- function(chromosome) {
selected <- which(chromosome == 1)
if (length(selected) == 0) return(0)
fit <- lm(y ~ ., data = data[, c(selected, ncol(data))])
return(-summary(fit)$adj.r.squared)
}Langkah 3: Menjalankan Algoritma Genetika Algoritma dijalankan dengan parameter tertentu, seperti ukuran populasi dan peluang mutasi:
GA_results <- rbga.bin(size = p, popSize = 50, iters = 100, mutationChance = 0.01, evalFunc = fitness)Hasil dan Visualisasi
Output Algoritma Hasil akhir mencakup informasi tentang solusi terbaik (\(\mathbf{C}^*\)) dan nilai fitness-nya:
## $type
## [1] "binary chromosome"
##
## $size
## [1] 10
##
## $popSize
## [1] 50
##
## $iters
## [1] 100
##
## $suggestions
## NULL
##
## $population
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
## [1,] 1 1 1 0 1 1 1 1 1 1
## [2,] 1 1 1 0 1 1 1 1 1 1
## [3,] 1 1 1 0 1 1 1 1 1 1
## [4,] 1 1 1 0 1 1 1 1 1 1
## [5,] 1 1 1 0 1 1 1 1 1 1
## [6,] 1 1 1 0 1 1 1 1 1 1
## [7,] 1 1 1 0 1 1 1 1 1 1
## [8,] 1 1 1 0 1 1 1 1 1 1
## [9,] 1 1 1 0 1 1 1 1 1 1
## [10,] 1 1 1 0 1 1 1 1 1 1
## [11,] 1 1 1 0 1 1 1 1 1 1
## [12,] 1 1 1 0 1 1 1 1 1 1
## [13,] 1 1 1 0 1 1 1 1 1 1
## [14,] 1 1 1 0 1 1 1 1 1 1
## [15,] 1 1 1 0 1 1 1 1 1 1
## [16,] 1 1 1 0 1 1 1 1 1 1
## [17,] 1 1 1 0 1 1 1 1 1 1
## [18,] 1 1 1 0 1 1 1 1 1 1
## [19,] 1 1 1 0 1 1 1 1 1 1
## [20,] 1 1 1 0 1 1 1 1 1 1
## [21,] 1 1 1 0 1 0 1 1 1 1
## [22,] 1 1 1 0 1 1 1 1 1 1
## [23,] 1 1 1 0 1 1 1 1 1 1
## [24,] 1 1 1 0 1 1 1 1 1 1
## [25,] 1 1 1 0 1 1 1 1 1 1
## [26,] 1 1 1 0 1 1 1 1 1 1
## [27,] 1 1 1 0 1 1 1 1 1 1
## [28,] 1 1 1 0 1 1 1 1 1 1
## [29,] 0 1 1 0 1 1 1 1 1 1
## [30,] 1 1 1 0 1 1 0 1 1 1
## [31,] 1 1 1 0 1 1 1 1 1 1
## [32,] 1 1 1 0 1 1 1 1 1 1
## [33,] 1 1 1 0 1 1 1 1 1 1
## [34,] 1 1 1 0 1 1 1 1 0 1
## [35,] 1 1 1 0 1 1 1 1 1 1
## [36,] 1 1 1 0 1 1 1 1 0 1
## [37,] 1 1 1 0 1 1 1 1 1 1
## [38,] 1 1 1 0 1 1 1 1 1 1
## [39,] 1 1 1 0 1 1 1 1 1 1
## [40,] 1 1 1 0 1 1 1 0 1 1
## [41,] 1 1 1 0 1 1 1 1 1 1
## [42,] 1 1 1 0 1 1 1 1 1 1
## [43,] 1 1 1 0 1 1 1 1 1 1
## [44,] 1 1 1 0 1 1 1 1 1 1
## [45,] 1 1 1 0 1 1 1 1 1 1
## [46,] 1 1 1 0 1 1 1 1 1 1
## [47,] 1 1 1 0 1 1 1 1 1 1
## [48,] 1 1 1 0 1 1 1 1 1 1
## [49,] 1 1 1 0 1 1 1 1 1 1
## [50,] 1 1 1 0 1 1 1 1 1 1
##
## $elitism
## [1] 10
##
## $mutationChance
## [1] 0.01
##
## $evaluations
## [1] -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529
## [7] -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529
## [13] -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529
## [19] -0.7715529 -0.7715529 -0.7577728 -0.7715529 -0.7715529 -0.7715529
## [25] -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7203688 -0.7689687
## [31] -0.7715529 -0.7715529 -0.7715529 -0.5028571 -0.7715529 -0.7715529
## [37] -0.7715529 -0.7715529 -0.7715529 -0.5339069 -0.7715529 -0.7715529
## [43] -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529
## [49] -0.7715529 -0.7715529
##
## $best
## [1] -0.3001773 -0.3960330 -0.5113361 -0.5113361 -0.6247445 -0.6351578
## [7] -0.7539872 -0.7646669 -0.7646669 -0.7689687 -0.7689687 -0.7689687
## [13] -0.7689687 -0.7689687 -0.7689687 -0.7689687 -0.7689687 -0.7689687
## [19] -0.7689687 -0.7689687 -0.7689687 -0.7689687 -0.7689687 -0.7689687
## [25] -0.7689687 -0.7689687 -0.7689687 -0.7689687 -0.7689687 -0.7689687
## [31] -0.7689687 -0.7689687 -0.7689687 -0.7689687 -0.7689687 -0.7689687
## [37] -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529
## [43] -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529
## [49] -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529
## [55] -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529
## [61] -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529
## [67] -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529
## [73] -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529
## [79] -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529
## [85] -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529
## [91] -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529 -0.7715529
## [97] -0.7715529 -0.7715529 -0.7715529 -0.7715529
##
## $mean
## [1] -0.08772023 -0.19255148 -0.27473859 -0.35402961 -0.42193414 -0.47579882
## [7] -0.56565508 -0.61060513 -0.64408684 -0.69833158 -0.73887399 -0.76018961
## [13] -0.76832583 -0.76800358 -0.76325351 -0.75257954 -0.75827003 -0.76866997
## [19] -0.75902680 -0.74692904 -0.75790596 -0.76888267 -0.76385763 -0.76067412
## [25] -0.75997213 -0.76896871 -0.76375311 -0.76315564 -0.76018483 -0.75762346
## [31] -0.76237944 -0.76424240 -0.76325351 -0.76540043 -0.76518773 -0.76030805
## [37] -0.76553815 -0.76622600 -0.76688955 -0.76019322 -0.76439720 -0.74849150
## [43] -0.76686632 -0.77152003 -0.76694197 -0.76521641 -0.75200723 -0.76418725
## [49] -0.76854913 -0.76722760 -0.75549226 -0.77155286 -0.77127726 -0.76066205
## [55] -0.76877188 -0.76671425 -0.77143586 -0.77127726 -0.77155286 -0.76679994
## [61] -0.76046109 -0.76587663 -0.76672452 -0.75510383 -0.76278253 -0.74658412
## [67] -0.76602490 -0.76805997 -0.76699525 -0.76534699 -0.77150118 -0.76471395
## [73] -0.76616305 -0.75650407 -0.76612726 -0.76075335 -0.76708914 -0.76703629
## [79] -0.77155286 -0.77127726 -0.76885756 -0.76174806 -0.76945381 -0.77039181
## [85] -0.76545036 -0.75673425 -0.76007644 -0.76830636 -0.77155286 -0.75636556
## [91] -0.76671425 -0.77127726 -0.76606043 -0.76230960 -0.76075335 -0.76652434
## [97] -0.76992290 -0.76671425 -0.75873073 -0.76007506
##
## attr(,"class")
## [1] "rbga"
Visualisasi Proses Optimasi Progres optimasi dapat divisualisasikan dengan:
Grafik ini menunjukkan bagaimana fitness terbaik dan rata-rata dalam
populasi meningkat selama iterasi, mencerminkan konvergensi solusi.
Studi Kasus: Dataset Iris
Dataset Iris digunakan untuk mendemonstrasikan kemampuan algoritma genetika dalam seleksi fitur. Dataset ditambahkan variabel acak (noise) untuk mensimulasikan tantangan.
Langkah 1: Persiapan Data
data(iris)
set.seed(123)
X <- cbind(scale(iris[, 1:4]), matrix(rnorm(36 * 150), 150, 36))
Y <- iris[, 5]Langkah 2: Fitness Function untuk LDA Fungsi fitness menggunakan Linear Discriminant Analysis (LDA) untuk meminimalkan tingkat salah klasifikasi: \[ \text{fitness}(\mathbf{C}) = \begin{cases} 1 - \frac{\text{Jumlah Salah Klasifikasi}}{\text{Total Data}} & \text{jika } |\mathbf{C}| > 2 \\ 1 & \text{lainnya} \end{cases} \] Kode R:
iris.evaluate <- function(indices) {
result = 1
if (sum(indices) > 2) {
huhn <- lda(X[, indices == 1], Y, CV = TRUE)$posterior
result = sum(Y != colnames(huhn)[apply(huhn, 1, which.max)]) / length(Y)
}
result
}Langkah 3: Menjalankan Algoritma
GA_iris <- rbga.bin(size = 40, popSize = 50, iters = 100, mutationChance = 0.05, evalFunc = iris.evaluate)
plot(GA_iris)Kesimpulan
Keunggulan Algoritma Genetika
Algoritma genetika fleksibel dalam menangani masalah optimasi kompleks seperti seleksi fitur dan pengurangan dimensi, terutama dengan data yang memiliki ruang solusi luas.Hasil Visualisasi
Plot menunjukkan bahwa algoritma mampu mengkonvergensi menuju solusi optimal dalam jumlah iterasi tertentu.Aplikasi Lanjut
Metode ini dapat diperluas untuk berbagai model statistik (misalnya regresi, LDA, atau metode non-linear).