--- 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`