DEAP1.2.2(六) 一个GP实例——用于函数发现

(六) GP实例——函数发现
话不多说直接上代码

import operator, math, random, numpy
from deap import gp, tools, base, creator, algorithms

toolbox = base.Toolbox()
pset = gp.PrimitiveSet("MAIN", 1)
#define protectedDive function which return their division
def protectedDiv(left, right):
    try:
        return left / right
    except ZeroDivisionError:
        return 1
#adding other functions
pset.addPrimitive(operator.add, 2)
pset.addPrimitive(operator.sub, 2)
pset.addPrimitive(operator.mul, 2)
pset.addPrimitive(protectedDiv, 2)
pset.addPrimitive(operator.neg, 1)
pset.addPrimitive(math.cos, 1)
pset.addPrimitive(math.sin, 1)
#add random constants which is an int type
pset.addEphemeralConstant("rand1", lambda: random.randint(-1,1))
#rename augument x
pset.renameArguments(ARG0='x')

#creating MinFit 
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
#creating individual
creator.create("Individual", gp.PrimitiveTree, fitness=creator.FitnessMin)

#import toolbox
toolbox = base.Toolbox()
#resigter expr individual population and compile
toolbox.register("expr", gp.genHalfAndHalf, pset=pset, min_=1, max_=2)     #0~3
toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.expr)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
toolbox.register("compile", gp.compile, pset=pset)
#define evaluating function
def evalSymbReg(individual, points):
    # Transform the tree expression in a callable function
    func = toolbox.compile(expr=individual)
    # Evaluate the mean squared error between the expression
    # and the real function : x**4 + x**3 + x**2 + x
    sqerrors = ((func(x) - x**4 - x**3 - x**2 - x)**2 for x in points) #define their differential
    #return the average fitness
    return math.fsum(sqerrors) / len(points),

#register genetic operations(evaluate/selection/mutate/crossover/)
toolbox.register("evaluate", evalSymbReg, points=[x/10. for x in range(-10,10)]) #the range of points in evaluate function
toolbox.register("select", tools.selTournament, tournsize=3) 
toolbox.register("mate", gp.cxOnePoint)\
#this is expr_mut, if we want to use a GEP, we can mutute the expr at first, then do the expression
toolbox.register("expr_mut", gp.genFull, min_=0, max_=2)
toolbox.register("mutate", gp.mutUniform, expr=toolbox.expr_mut, pset=pset)
#decorating the operator including crossover and mutate, restricting the tree's height and length
toolbox.decorate("mate", gp.staticLimit(key=operator.attrgetter("height"), max_value=17))
toolbox.decorate("mutate", gp.staticLimit(key=operator.attrgetter("height"), max_value=17))

def main():
    #Parameter setting
    CXPB = 0.1
    MUPB = 0.1
    GEN = 400
    POP_SIZE = 300 
    #initializing population
    pop = toolbox.population(n = POP_SIZE)
    
    '''start evolution'''
    print('Start evolution')
    #evaluating the fitness
    fitnesses = list(map(toolbox.evaluate, pop))
    #assign fitness values
    for ind, fit in zip(pop, fitnesses):
        ind.fitness.values = fit
    print('Evaluated %i individuals' %len(pop))
    '''The genetic operations'''
    for g in range(GEN):
        #select
        offspring = toolbox.select(pop, len(pop))
        offspring = list(map(toolbox.clone, offspring))
        #crossover
        for child1, child2 in zip(offspring[::2], offspring[1::2]):
            if random.random() < CXPB:
                toolbox.mate(child1, child2)
                
                del child1.fitness.values
                del child2.fitness.values
        
        #mutation
        for mutant in offspring:
            if random.random() < MUPB:
                toolbox.mutate(mutant)
                del mutant.fitness.values
        
        #evaluate the invalid individuals
        invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
        fitnesses = list(map(toolbox.evaluate, invalid_ind))
        for ind, fit in zip(invalid_ind, fitnesses):
            ind.fitness.values = fit
        print('Evaluated %i individuals' %len(invalid_ind))
        
        #update the pop
        pop[:] = offspring
        
        #statistics
        stats = tools.Statistics(key=lambda ind: ind.fitness.values)
        record = stats.compile(pop)
        stats.register("avg", numpy.mean, axis=0)
        stats.register("min", numpy.min, axis=0)
        stats.register("max", numpy.max, axis=0)
        record = stats.compile(pop)
        logbook = tools.Logbook()
        logbook.record(gen=g, evals=30, **record)
        logbook.header = "gen", "avg", "min", "max"
        print(logbook)
        


    print("-- End of (successful) evolution --")
    
    best_ind = tools.selBest(pop, 1)[0]
    print("Best individual is %s, Best results are %s" % (best_ind, best_ind.fitness.values))
    
        
    

if __name__ == "__main__":
    main()

大部分注释都有写,总结一下这个例子:
首先,要发现的函数是: f(x) = x^4 - x^3 - x^2 - x, fitness func为 min{sum(func(x) - f(x))^2}/xnum,x in (-1, 1] 间隔0.1。
接下来首先搭建GP框架
STEP1. 适应度函数的构建,个体及种群初始化,所用工具包:creator/toolbox
STEP2. 演化操作定义以及树的size限制
STEP3. 设定参数(交叉率、变异率、迭代次数以及种群大小),初始化种群并计算适应度
STEP4. 按照选择、交叉、变异的顺序进行演化操作,在一次演化操作完成后选出无效个体(即适应性不如先前个体的个体,对这些个体的适应度不予修改)
STEP5. 更新种群,统计当前种群的适应度信息并输出
STEP6. 当循环结束,输出全局最优解

注意:在GP这种树结构的算法中,在适应度计算当中,生成的树结构首先要通过toolbox.compile转化为函数,再通过函数进行计算,同时所有的遗传操作均是基于树结构进行的,因此在register这些步骤时候需要使用特定的方法,如gp.cxOnePoint等。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容