python的deap库使用记录

  • 主要是在遗传符号回归的代码中添加了注释和根据一部分源码做了一点改动
import operator
import random
import numpy as np
import matplotlib.pyplot as plt
from deap import algorithms, base, creator, tools, gp
from operator import attrgetter

##生成数据
def generate_data():
    X = np.random.uniform(-10, 10, 100).reshape(-1, 1)
    y = X**3 - 2*X**2 + 3*X - 5 + np.random.normal(0, 5, 100).reshape(-1, 1)
    
    return X, y

##population:群体
##toolbox:工具箱
##cxpb:交配概率
##mutpb:变异概率
def varAnd(population, toolbox, cxpb, mutpb):
    offspring = [toolbox.clone(ind) for ind in population]

    # Apply crossover and mutation on the offspring
    for i in range(1, len(offspring), 2):
        if random.random() < cxpb:
            offspring[i - 1], offspring[i] = toolbox.mate(offspring[i - 1],
                                                          offspring[i])
            del offspring[i - 1].fitness.values, offspring[i].fitness.values

    for i in range(len(offspring)):
        if random.random() < mutpb:
            offspring[i], = toolbox.mutate(offspring[i])
            del offspring[i].fitness.values
    return offspring

def if_then_else(input, output1, output2):
    return np.where(input, output1, output2)

# 定义评价函数
def evalSymbReg(individual, points):
    func = toolbox.compile(expr=individual)           #编译表达式
    sqerrors = ((func(points) - y)**2).flatten()      #误差计算
    return np.sqrt(np.sum(sqerrors)),

# 挑选好的若干个体
def selTournament(individuals, k, tournsize, fit_attr="fitness"):
    chosen = []
    for i in range(k):
        aspirants = [random.choice(individuals) for i in range(tournsize)]
        chosen.append(max(aspirants, key=attrgetter(fit_attr)))
    return chosen


def eaSimple2(population, toolbox, cxpb, mutpb, ngen, stats=None,halloffame=None, verbose=__debug__):

    #用适应度评价群体,对还没有进行过评价的个体进行评价(主要是存在很多评价过的个体)
    invalid_ind = []   
    for ind in population:
        if not ind.fitness.valid:
            invalid_ind.append(ind)
    fitnesses = toolbox.map(toolbox.evaluate, invalid_ind)
    for ind, fit in zip(invalid_ind, fitnesses):
        ind.fitness.values = fit

    if halloffame is not None:    #名人堂
        halloffame.update(population)


    #开始迭代过程
    for gen in range(1, ngen + 1):
        #1、选择下一代繁殖个体
        offspring = toolbox.select(population, len(population))
        #2、交叉变异
        offspring = toolbox.varAnd(offspring, toolbox, cxpb, mutpb)
        #3、对适应度无效的个体进行评价
        invalid_ind = []
        for ind in offspring:
            if not ind.fitness.valid:
                invalid_ind.append(ind)
        fitnesses = toolbox.map(toolbox.evaluate, invalid_ind)
        for ind, fit in zip(invalid_ind, fitnesses):
            ind.fitness.values = fit
        #4、更新名人堂
        if halloffame is not None:
            halloffame.update(offspring)
        #5、用后代代替当前的群体
        population = offspring   #用这种方法可以使用原来的地址
    return population


#################################################################################################
# 1、创建遗传符号回归语义集合
pset = gp.PrimitiveSet("MAIN", 1)
pset.addPrimitive(operator.add, 2)
pset.addPrimitive(operator.sub, 2)
pset.addPrimitive(operator.mul, 2)
pset.addPrimitive(operator.neg, 1)
pset.addPrimitive(np.square, 1)
pset.addPrimitive(np.sqrt, 1)
pset.addPrimitive(if_then_else, 3)
pset.addEphemeralConstant("rand101", lambda: random.uniform(-10, 10))

# 2、顶级适应度和个体类
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
creator.create("Individual", gp.PrimitiveTree, fitness=creator.FitnessMin)
# 4、定义工具函数,这里可以引入自定义函数
toolbox = base.Toolbox()
## 4.1 定义个体和种群
toolbox.register("expr", gp.genFull, pset=pset, min_=1, max_=2)                      #在两个子叶之间生成1-2深度表达式
toolbox.register("individual", tools.initIterate, creator.Individual, toolbox.expr)  #定义个体
toolbox.register("population", tools.initRepeat, list, toolbox.individual)            #生成群体
## 4.2 公式编码
toolbox.register("compile", gp.compile, pset=pset)                                    #表达式编译
## 4.3 评价和挑选
X, y = generate_data()
toolbox.register("evaluate", evalSymbReg, points=X)                                #用生成的这些数据进行评价 
toolbox.register("select", selTournament, tournsize=3)                           #个体筛选
## 4.4 交叉变异和下一代繁殖
toolbox.register("mate", gp.cxOnePoint)                                                   #交叉

toolbox.register("expr_mut", gp.genFull, min_=0, max_=2)
toolbox.register("mutate", gp.mutUniform, expr=toolbox.expr_mut, pset=pset)               #变异
toolbox.register("select", selTournament, tournsize=3)   

toolbox.register("varAnd", varAnd)   #繁殖


########################################################################
# 1、定义种群和名人堂
pop = toolbox.population(n=300)        #种群
hof = tools.HallOfFame(10)              #名人堂
# 2、拟合公式
pop = eaSimple2(pop, toolbox, 0.5, 0.1, 40,halloffame=hof, verbose=True)
best_ind = hof[0]
print("拟合公式:",best_ind)
# 3、画出图像
func = toolbox.compile(expr=best_ind)
y_pred = func(X)
plt.figure()
plt.scatter(X, y, color='blue', label='Actual data')
plt.scatter(X, y_pred, color='red', label='Predicted data')
plt.legend()
plt.show()





相关推荐

  1. pythondeap使用记录

    2024-05-12 03:00:07       32 阅读
  2. 使用 PythonDEAP多目标优化示例

    2024-05-12 03:00:07       33 阅读
  3. 【C++】学习记录--Thread线程使用

    2024-05-12 03:00:07       46 阅读
  4. Python图像处理:PIL使用

    2024-05-12 03:00:07       54 阅读
  5. python视频处理FFmpeg使用

    2024-05-12 03:00:07       31 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-05-12 03:00:07       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-05-12 03:00:07       106 阅读
  3. 在Django里面运行非项目文件

    2024-05-12 03:00:07       87 阅读
  4. Python语言-面向对象

    2024-05-12 03:00:07       96 阅读

热门阅读

  1. AI绘画已如此厉害,为何我们仍需学习绘画?

    2024-05-12 03:00:07       37 阅读
  2. 相机标定详解

    2024-05-12 03:00:07       31 阅读
  3. C++面向对象

    2024-05-12 03:00:07       35 阅读
  4. spring-boot-starter-validation校验框架

    2024-05-12 03:00:07       34 阅读
  5. 流畅的python-学习笔记_协议+继承优缺点

    2024-05-12 03:00:07       31 阅读
  6. Spring中用到的设计模式有哪些

    2024-05-12 03:00:07       32 阅读