---
title: 'R 語言學習心得 Genetic Algorithm'
disqus: hackmd
---
R Genetic Algorithm
Machine Learning
===
![downloads](https://img.shields.io/badge/download-R-brightgreen)
![grade](https://img.shields.io/badge/Grade-新手-brightgreen)
![chat](https://img.shields.io/discord/:serverId.svg)
----
基因演算法原理
===
透過模仿自然法則來設計演算法: 主要有**篩選&交配&突變**3個主要機制
==篩選==
從所有的染色體中選取最適配(根據目標函數)的一對(或多對)作為父母染色體 ---> 競爭篩選法
計算每個染色體的適配值---> 越適合,被選中的機率越高,但人人有機會 ---> 輪盤篩選法
**被篩選出來的染色體就進入交配池**
==交配==
交配的目的是交換基因,交換基因也有很多種方式,介紹最簡單的單點交配
從交配池抓出兩個染色體 A&B
A = 111000
B = 101011
若演算法決定在第N個基因為交配點,則兩個染色體的基因在第N個基因後進行互換
---> 設N=3(從左邊數過來)
:::success
A = 111|000
B = 101|011
---開始交換---
A = 111|011
B = 101|000
---交換完成---
:::
==突變==
但是如果只是交配還是有問題 ---> 無法產生新的基因
因此演算法要設定一個突變機率
突變也是有許多方法,最簡單就是在要突變的染色體上找一個基因--->將其值反轉
:::info
A = 11100**0**
A' = 11100**1**
:::
==菁英基因==
保留前一代一定數量的基因,來讓優秀基因留下來
剩下的染色體則由交配後的子代取代
==流程==
```
start()
Generate_initial_group()
while(terminate = False){
Calculate_Fitting_values()
Select_mating_gene()
Mating()
Mutation()
Replace(Elite_Rate)
Check_terminate()
}
end()
```
----
實作目標
===
==以遺傳演算法去逼近以下方程式==
:::info
f(x)=abs(x1-sqrt(exp(1)))+abs(x2-log(pi))
:::
找出在指定範圍的x1&x2 ---> 使f(x)之最小值
![](https://i.imgur.com/1HDhrjN.png)
----
rbga in R (2 variables)
===
```r=
library(genalg)
evaluate <- function(string=c()) {
returnVal = NA;
if (length(string) == 2) {
returnVal = abs(string[1]-sqrt(exp(1))) + abs(string[2]-log(pi));
} else {
stop("Expecting a chromosome of length 2!");
}
returnVal
}
monitor <- function(obj) {
# plot the population
xlim = c(obj$stringMin[1], obj$stringMax[1]);
ylim = c(obj$stringMin[2], obj$stringMax[2]);
plot(obj$population, xlim=xlim, ylim=ylim,
xlab="sqrt(exp(1))", ylab="log(pi)");
}
rbga.results <- rbga(c(0, 0), c(5,5),
monitorFunc=monitor,
evalFunc=evaluate,
verbose=TRUE,
iters = 1000,
popSize = 100,
mutationChance=0.01)
s <- summary(rbga.results,ehco = TRUE)
# 對答案(如果沒有叫出summary的話)
rbga.results$population[1,]
# check loss
real <- c(1.648721,1.14473)
diff <- real - rbga.results$population[1,]
diff
```
![](https://i.imgur.com/M79vfgP.png)
![](https://i.imgur.com/vkKvpHM.png)
----
rbga in R (3 variables)
===
3個變數,範圍上下限一樣為0~5
```r=
library(genalg)
library(plot3D)
evaluate <- function(string=c()) {
returnVal = NA;
if (length(string) == 3) {
returnVal = abs(string[1]-sqrt(exp(1))) + abs(string[2]-log(pi)) + abs(string[3]-2*pi);
} else {
stop("Expecting a chromosome of length 3!");
}
returnVal
}
monitor <- function(obj) {
# plot the population
xlim = c(obj$stringMin[1], obj$stringMax[1]);
ylim = c(obj$stringMin[2], obj$stringMax[2]);
zlim = c(obj$stringMin[3], obj$stringMax[3]);
x = obj$population[,1];
y = obj$population[,2];
z = obj$population[,3];
scatter3D(x,y,z, xlim = xlim,ylim = ylim,zlim = zlim,main="3 variables GA",
xlab="sqrt(exp(1))", ylab="log(pi)",zlab="2*pi",colkey=TRUE,col = rainbow(12),
ticktype="detailed", bty="g",phi=0,speed = 0.2, clab="Rainbow",pch=20,cex=2);
}
rbga.results <- rbga(c(0,0,0), c(5,5,5),
monitorFunc=monitor,
evalFunc=evaluate,
verbose=TRUE,
iters = 500,
popSize = 100,
mutationChance=0.01)
#rbga.results$population[1,]
s <- summary(rbga.results,ehco = TRUE)
# 對答案(如果沒有叫出summary的話)
rbga.results$population[1,]
```
:::info
基因演算法絕對不是只可以算兩個變數(大部分教學都只展示兩個),其實幾個都行
1. 設計function時把變數加上去
2. 以3個變數來說,畫圖應該要用3D,更多維就不用畫圖了
3. 用plot3D的scatter3D()來畫圖,注意這邊x,y,z要用
"obj之population"的$column$(不信可以把"obj$population" print出來)
4. 畫3D圖的其他設定可以參考----->[這裡](https://www.rdocumentation.org/packages/QCAGUI/versions/1.2-7/topics/scatter3d)或[這裡](http://badala2164.blogspot.com/2018/05/r-3d.html)
:::
![](https://i.imgur.com/R142a5C.png)
----
==reference==
[第一篇](https://www.itread01.com/content/1542380602.html)
[第二篇](https://rdrr.io/cran/genalg/man/rbga.html)
[第三篇](http://iccm.cc/colors-and-palettes-in-r-language/)
4. 應用R語言於資料分析-從機器學習/資料探勘到巨量資料 - 李仁鐘
----
## More tutorial / note
1. [my coding-blog](fatcatcat-lab.blogspot.com)
2. [my movie-blog](fatcatcat-movie.blogspot.com)
###### tags: `R` `beginner` `cat` `tutorial`