遗传算法(Genetic Algorithm)及python实现
遗传算法
- 遗传算法
- 遗传算法的定义
- 遗传算法的流程
- 具体实现过程
- 适应度评估
- 选择
- 交叉
- 变异
- 代码实现
- 引用
遗传算法
遗传算法的定义
遗传算法(Genetic Algorithm, GA)是一种以达尔文物种进化理论的自然选择理论和遗传学机理为基础,这是一种随机换算法,它的结果是不确定的。它 模拟了种群一代一代进化的过程,它可以通过评估函数对个体进行选择和淘汰,再依据交叉与变异来模拟生物进化,从而经过一代代的进化搜索出最优解。
遗传算法将每一个个体作为对象,最终结果也是选择出最为优良的个体。遗传算法所涉及的操作有选择、交叉、变异,核心在于如何完成初始化群体的设定,如何设置遗传算法操作。
遗传算法需要解决的问题是如何筛选出最适于在当前环境生存的种群(population)。而一个种群则是由个体(individual)组成的,每个个体都是带有不同特征表现的实体,都由基因(gene)编撰而成的染色体(chromosome)组成且代表了个体的性状。基因、染色体、种群的关系从下图中可以比较明显的看出来。
遗传算法的流程
遗传算法的起点在于根据所要解决的问题进行"数字化"编码,例如在使用logistics算法过程中,不同feature的权值即为该问题的编码。其次,要随机初始化种群,种群里面的每个个体就是这些数字化的编码,就想之前图样中 A i A_i Ai表现得那样。
初代种群产生之后,按照"适者生存,优胜劣汰"的原理,逐代(generation)演化产生出越来越好的近似解,在每一代,根据问题域中个体的适应度(fitness)大小选择(selection)个体,并借助于自然遗传学的遗传算子(genetic operators)进行组合交叉(crossover)和变异(mutation),产生出代表新的解集的种群。
进行判断的方法一般有三种:
1-多次迭代后适应性没有明显增长
2-已经达到对适应性的需求
3-超过了需求时间
这个过程将导致种群像自然进化一样的后生代种群比前代更加适应于环境,末代种群中的最优个体经过解码(decoding),可以作为问题近似最优解。
值得注意的是,遗传算法作为一种启发式算法,无法判断出与真实最优解的偏离程度。
具体实现过程
适应度评估
在遗传算法中所有生物学定义都有着自己在数学意义上的对象,例如个体就相当于相同参数不同weight的模型。一般情况下针对不同的目标和项目,使用不同的适应性函数(fitness function)来判断该方案的优劣,常用的适应性评估方案有以下几个:
基于损失函数最小:MSE, cross entropy
基于模型结果最优:AUC(先使用TPR、FPR画出ROC曲线,再求AUC)
这一过程类似于自然界中运行的自然选择,适应性好的模型将被保留,差的将被’kill’。
选择
这一过程类似于父类中的哪些个体可以繁殖并将基因传给子代。选择操作的目的就是选取一定个体来完成后续交叉、变异等过程。
选择的方法更为多样,使用较多的有以下几个方法:
1-轮判断选择(Roulette Wheel Selection):这是一种有放回的随机抽样方法,每个个体被选中的概率 = 个体的适应度占全体个体适应度和的比例
2-随机竞争选择(Stochastic Tournament):首先,按照轮盘赌的方法随机选择出一对个体;其次,适应度高的个体被允许传入下一代,直到达到所需个体数量。
3-最优保留选择:首先,依据轮盘赌方法筛选出一批个体,再将其中适应度高的完整复制进入下一代
4-均匀排序:按照适应度大小排序,并随机给出0-1的数值,数字在哪个区间就选择哪个个体
5-最优保存选择②:用当前群体中适应度最高的个体替换完成交叉、变异等操作后所产生的适应度最低的个体。
等等
交叉
这一过程类似于生物进化当中的染色体基因呼互换,具体指两个相互配对的染色体交换各自个体的某些基因段,从而产生新的个体,交叉方法如下:
1-单点交叉:在个体中随机选择一个点,在这个点完成部分基因的交换
2-两点交叉:随机产生出一个位置段,在这个段落中的基因被交换
3-均匀交换:每个对应位置的基因都要以某个特定概率随机完成交换。
变异
基本位变异(Simple Mutation):以某一特定概率,一个或几个基因变异
均匀变异(Uniform Mutation):用一组服从均匀分布的随机数,以某较小概率替换每个染色体上的基因
代码实现
代码的来源是我当时的leader直接发给我的,具体来源也不清楚,如果有读者知道这套代码的来源是什么的话,请评论告诉我,我会加入引用的。
import random
import numpy as np
from deap import base, creator, tools
from sklearn.metrics import auc
from sklearn.metrics import roc_curvedef generate_weight(num):# 随机生成初始值value = np.random.random(num)total_sum = np.sum(value)# 以随机数占总和的比值为标准,生成第一代权重值,实现权重加和为1for v in value:yield v / total_sumdef cxTwoPoint(ind1, ind2):# 该函数作用是individual随机gene交换# 最长可交换基因数 = 交换的两个individual中较短的那个size = min(len(ind1), len(ind2))# 随机生成交换gene位置cxpoint1 = random.randint(1, size)cxpoint2 = random.randint(1, size - 1)if cxpoint2 >= cxpoint1:cxpoint2 += 1else: # Swap the two cx pointscxpoint1, cxpoint2 = cxpoint2, cxpoint1# 交换geneind1[cxpoint1:cxpoint2], ind2[cxpoint1:cxpoint2] \= ind2[cxpoint1:cxpoint2], ind1[cxpoint1:cxpoint2]# 重新计算权重值total_ind1 = sum(ind1)total_ind2 = sum(ind2)for i, v in enumerate(ind1):ind1[i] = v / total_ind1for i, v in enumerate(ind2):ind2[i] = v / total_ind2return ind1, ind2class SimpleGeneticAlgorithm(object):"""Modified genetic algorithm, used to solve following constraint optimization problemsmin f(w1, w2, w3, w4, w5, ... )s.t. 0<= w_i <=1, i=1, 2, 3, ...w_1 + w_2 + ... w_n = 1# lower bound and upper bound can be defined by userlower_bound <= w_i <= upper_bound, i=1, 2, 3, ...where f can be any objective functions, such as cross entropy, mse, etc."""# 设置初始化参数def __init__(self,x,y,population_size=1000, #size pof populationgeneration=500, #the times of iterationcross_prob=0.3, #probability of crossmutation_prob=0.4, #probability of mutationobj_fn='cross_entropy', #objective function:cross_entropy, MSE, AUCthreshold=None, #include [lower_bound, upper_bound]early_stop=True, #stop if no improvement during 100 stepsverbose=False): #whether print information""":param x: numpy array is required :param y: numpy array is required:param population_size: population size for GA algorithm, default 1000:param generation: number of generations, default 500:param cross_prob: the probability for cross event between two individuals:param mutation_prob: the probability for mutation:param obj_fn: objective functions used in the algorithm, currently support, default cross_entropy- mse: mean square error- cross_entropy: cross entropy function, same as objective function for logistic regression:param threshold: list type object, [lower_bound, upper_bound], contains lower bound and upper bound for the weight:param early_stop: default True, whether the algorithm stops early, if no improvement for 100 steps:param verbose: default False, whether to print the log information each step"""self.x = xself.y = yself.population = population_sizeself.generation = generationself.cross_prob = cross_probself.mutation_prob = mutation_probself.threshold = thresholdself.early_stop = early_stopself.verbose = verboseself.best_ind = None# Creat 'GA' class by using creator function from deap package,# during this funcation:bas.Fitness is base class,# weights=(-1,) shows this is a minimization problem with just 1 objective functioncreator.create('GA', base.Fitness, weights=(-1, ))# Creat the data structure about individual and hold data in listcreator.create('Individual', list, fitness=creator.GA)self.toolbox = base.Toolbox()#定义individual的初始化函数self.toolbox.register('generate_weight', generate_weight, self.x.shape[1])self.toolbox.register('individual',tools.initIterate,creator.Individual,self.toolbox.generate_weight)#create populationself.toolbox.register('population', tools.initRepeat, list, self.toolbox.individual)self.obj_fn = obj_fnif obj_fn == 'cross_entropy':self.toolbox.register('evaluate', self.logistic_objective)elif obj_fn == 'mse':self.toolbox.register('evaluate', self.mse_objective)elif obj_fn == 'AUC':self.toolbox.register('evaluate', self.AUC_objective)else:raise NotImplementedError('More Objective Function in future')#define gene mate funcation, mutate funcation、individual select funcationself.toolbox.register('mate', cxTwoPoint)self.toolbox.register('mutate', tools.mutShuffleIndexes, indpb=0.1)self.toolbox.register('select', tools.selTournament, tournsize=3)def meet_other_constraints(self, individual):"""use to check whether each individual is between the user defined lower and upper bound if provided"""if self.threshold is not None:if np.any(np.array(individual) > self.threshold[1]) | \np.any(np.array(individual) < self.threshold[0]):return Falseelse:return Trueelse:return Truedef logistic_objective(self, individual):"""cross entropy function, same as objective function in logistic regression"""if not self.meet_other_constraints(individual):return np.iinfo(np.uint64).max,y_hat = np.matmul(self.x, individual)return -np.mean(self.y * np.log(y_hat) + (1-self.y) * np.log(1-y_hat)),def mse_objective(self, individual):"""mean square error"""if not self.meet_other_constraints(individual):return np.iinfo(np.uint64).max,y_hat = np.matmul(self.x, individual)return np.mean( (self.y - y_hat)**2),def AUC_objective(self, individual):"""area under curve:param individual::return:"""if not self.meet_other_constraints(individual):return np.iinfo(np.uint64).max,y_hat = np.matmul(self.x, individual)fpr, tpr, thresholds = roc_curve(self.y, y_hat, pos_label=1)return np.mean(auc(fpr, tpr)),def run(self):"""run the simplified GA algorithm"""# initialize the populationpop = self.toolbox.population(self.population)# evalute each individual in the populationfitnesses = list(map(self.toolbox.evaluate, pop))# 目标函数值与每个个体关联起来for ind, fit in zip(pop, fitnesses):ind.fitness.values = fit# 记录现在最小的目标函数的值(因为我们是最小化问题)previous_obj = None# used for early stopcount = 0# loop for each generationfor g in range(self.generation):if self.verbose:print("-- Generation %i --" % g)# select offspringsoffspring = self.toolbox.select(pop, len(pop))# clone the offspringsoffspring = list(map(self.toolbox.clone, offspring))# between two individuals, check whether gene exchange will happenfor child1, child2 in zip(offspring[::2], offspring[1::2]):# if a random number is smaller than the cross_probif random.random() < self.cross_prob:self.toolbox.mate(child1, child2)# delete the objective values for the children, since they are going to be reevaluateddel child1.fitness.valuesdel child2.fitness.values# for each individualfor mutant in offspring:# if a random number is smaller than the mutation_probif random.random() < self.mutation_prob:self.toolbox.mutate(mutant)# delete the objective values for the child, since it's going to be reevaluateddel mutant.fitness.values# select all the newly generated individualsinvalid_ind = [ind for ind in offspring if not ind.fitness.valid]# reevaluate the objective for newly generated individualsfitnesses = map(self.toolbox.evaluate, invalid_ind)# assign the valuefor ind, fit in zip(invalid_ind, fitnesses):ind.fitness.values = fit# update all the pupulationspop[:] = offspring# get all the objective functionsfits = [ind.fitness.values[0] for ind in pop]# AUC record the maxmum, others record the minumumif self.obj_fn == 'AUC':current_obj = max(fits)else:current_obj = min(fits)if self.verbose:length = len(pop)mean = sum(fits) / lengthsum2 = sum(x * x for x in fits)std = abs(sum2 / length - mean ** 2) ** 0.5print(" Min %s" % min(fits))print(" Max %s" % max(fits))print(" Avg %s" % mean)print(" Std %s" % std)if self.obj_fn == 'AUC':if previous_obj is None:previous_obj = current_objelif previous_obj >= current_obj:# count none decreasing timescount += 1else:# update the best objective valuesprevious_obj = current_obj# previous_obj > current_obj:# reset decreasing times to 0count = 0else:if previous_obj is None:previous_obj = current_objelif previous_obj <= current_obj:# count none decreasing timescount += 1else:# update the best objective valuesprevious_obj = current_obj# previous_obj > current_obj:# reset decreasing times to 0count = 0if self.early_stop and count > 100:if self.verbose:print('Early stop condition encountered!')breakself.best_ind = tools.selBest(pop, 1)[0]if self.verbose:print("-- End of (successful) evolution --")best_ind = tools.selBest(pop, 1)[0]print("Best individual is %s" % best_ind)print("Best objective function is %s" % best_ind.fitness.values)if __name__ == '__main__':# X = np.array([# [0.5, 0.2, 0.4, 0.8],# [0.3, 0.5, 0.1, 0.2],# [0.4, 0.5, 0.2, 0.1],# [0.9, 0.2, 0.8, 0.8]# ])# X1 = np.array([# [0.3, 0.2, 0.4, 0.8],# [0.6, 0.5, 0.1, 0.2],# [0.7, 0.5, 0.2, 0.1],# [0.2, 0.2, 0.8, 0.8]# ])# X2 = np.array([# [0.5, 0.2, 0.4, 0.8],# [0.3, 0.5, 0.1, 0.3],# [0.4, 0.5, 0.2, 0.1],# [0.9, 0.2, 0.8, 0.8]# ])# X3 = np.array([# [0.5, 0.2, 0.4, 0.8],# [0.3, 0.5, 0.1, 0.2],# [0.4, 0.5, 0.2, 0.1],# [0.9, 0.2, 0.8, 0.8]# ])# X4 = np.array([# [1.0, 0.2, 0.4, 0.8],# [0.3, 0.5, 0.1, 0.2],# [0.4, 0.5, 0.2, 0.1],# [0.9, 0.2, 0.8, 0.8]# ])## y = np.array([1, 0, 0, 1])X = np.random.random(400).reshape((100, 4))X1 = np.random.random(400).reshape((100,4))X2 = np.random.random(400).reshape((100, 4))X3 = np.random.random(400).reshape((100, 4))X4 = np.random.random(400).reshape((100, 4))# X[:, 3] = [x - int(x) for x in abs(np.random.randn(10))]y = random.ranint(0,2,(100,))print(X)print(y)print(X1)print(y)population = 100cross_prob = 0.5mutation_prob = 0.2generation = 100# threshold_max 用于限制权重最大值# threshold_min 用于限制权重最小值threshold_max = 0.33threshold_min = 0.05ga = SimpleGeneticAlgorithm(x=X4,y=y,population_size=population,generation=500,cross_prob=cross_prob,mutation_prob=mutation_prob,obj_fn='AUC',threshold=[threshold_min, threshold_max],early_stop=True,verbose=True)ga.run()# best weightsga.best_ind# objective valuega.best_ind.fitness.values
引用
1-超详细的遗传算法(Genetic Algorithm)解析:https://www.jianshu.com/p/ae5157c26af9
2- wiki相关搜索
3-ROC:https://www.jianshu.com/p/135e412d43fa
遗传算法(Genetic Algorithm)及python实现相关推荐
- python遗传算法_【机器学习】遗传算法(Genetic Algorithm)的Python实现
本文章用Python实现了基本的优化遗传算法并用类进行了封装 一.遗传算法概述 遗传算法(Genetic Algorithm)是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一 ...
- 遗传算法(Genetic Algorithm)从了解到实例运用(上)(python)
前言 本文主要介绍了数学建模常用模型遗传算法,从原理出发到编程实现再到实例运用.笔者参与过大大小小五次数学建模,个人觉得该优化算法值得一学. 提示:以下是本篇文章正文内容 一.遗传算法由来 遗传算法的 ...
- 遗传算法(Genetic Algorithm,GA)实现数据排序,python
遗传算法(Genetic Algorithm,GA)实现数据排序,python 遗传算法是一种比较广泛.通用的算法体系,为了说明遗传算法的原理和实现,现在用GA解决一个计算机科学最基本.最古老的问题: ...
- uniform crossover(均匀交叉),遗传算法(Genetic Algorithm,GA),python
uniform crossover(均匀交叉),遗传算法(Genetic Algorithm,GA),python 假设有双亲p1和p2的二进制基因染色体表达,子代的基因以等概率(50%)来自双亲中之 ...
- 遗传算法 python包_遗传算法 (Genetic Algorithm)
遗传算法( Genetic Algorithm )又叫基因进化算法,或进化算法.属于启发式搜索算法一种,这个算法比较有趣,并且弄明白后很简单,写个 100-200 行代码就可以实现.在某些场合下简单有 ...
- 遗传算法 python 简书_遗传算法(Genetic Algorithm ,GA)学习笔记
1 遗传算法的概念 1.1 遗传算法的科学定义 遗传算法(Genetic Algorithm, GA) 是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程 ...
- 遗传算法 python 简书_【算法】超详细的遗传算法(Genetic Algorithm)解析
00 目录 遗传算法定义 生物学术语 问题导入 大体实现 具体细节 代码实现 01 什么是遗传算法? 1.1 遗传算法的科学定义 遗传算法(Genetic Algorithm, GA)是模拟达尔文生物 ...
- 遗传算法Genetic Algorithm
文章目录 遗传算法Genetic Algorithm 1. 简介 1.1 简介 1.2 相关概念介绍 1.2.1 选择(复制) 1) 轮盘赌选择法 2) 随机遍历抽样法 3) 锦标赛选择法 4) 比例 ...
- 【深度学习入门到精通系列】遗传算法 (Genetic Algorithm)
文章目录 1 遗传算法概述 2 遗传算法 2.1 找一个好的fitness方程 2.2 DNA 编码 2.3 代码实现 3 配对句子 4 旅行商问题 5 Microbial Genetic Algor ...
- 路径算法:遗传算法 (Genetic Algorithm, GA)
遗传算法简介 遗传算法是受自然进化理论启发的一系列搜索算法.通过模仿自然选择和繁殖的过程,遗传算法可以为涉及搜索,优化和学习的各种问题提供高质量的解决方案.同时,它们类似于自然进化,因此可以克服传统搜 ...
最新文章
- 线性回归之模型的保存和加载
- android小程序案例_这几个小程序案例告诉你,小程序该怎么做!
- SpringCloud(第 054 篇)简单 Quartz-Cluster 微服务,采用注解配置 Quartz 分布式集群... 1
- 如何在关闭窗口的时候,不让浏览器自动弹出确认关闭对话框
- CSS挂马及相应防范方法
- js 对一个字段去重_js正则去重及(?=)的匹配规则
- 关于[知识竞赛现场管理系统-双屏PPT版]内置的第三方答题平台以及[评委计分系统-双屏专业版]的特殊疑难问题 汇编
- linux停止license服务器,LICENSE · 机器不学习/linux-command - Gitee.com
- 图解FPGrowth 算法
- 李开复写给中国大学生的信
- iBeacon距离测量误差有多大
- Android应用向su申请root权限,以及Superuser进行授权管理的原理浅析
- mysql 自增 空洞_MySQL auto_increment空洞问题
- rsa私钥 txt转化为pem格式
- 计算新闻传播学临摹作业_数据抓取与数据清洗(西安交大国家艺术基金数据可视化培训第34天)
- VS Code + Latex + SumatraPDF 环境(实用)
- 美国依靠美元霸权, 是如何收割世界财富的?
- 期望、方差、标准差、协方差、正太分布、分布
- 【C语言】指针基础知识点汇总
- aspx repeater 用法_Repeater控件的详细用法
热门文章
- 如何解决Mac盖上屏幕后外接屏幕持续黑屏的问题
- 零基础3D游戏建模入门详解
- 已解决Encountered error while trying to install package.wxPython
- ## 解决ubuntu没有网络
- 还不知道音频格式转换mp3软件哪个好?进来看看就知道了
- gprMax3.0安装教程
- 解决GitHub打不开(FastGithub,支持MAC)
- 一场由飞艇连接的云栖大会背后阿里云物联网战略提速
- MySQL 的覆盖索引的实现
- Siamese Network (应用篇3) :孪生网络用于图像块匹配 ACCV2016