I try to make a custom "individual" in DEAP. Reason is that individual is made of several explanatory variables. Each explanatory variable has lower and upper bound. Also, it may have step or precision.
This is the code I am working on:
import random
from deap import base, creator, tools
from typing import Optional, List, Any
creator.create("FitnessMin", base.Fitness, weights=(-1.0,))
creator.create("Individual", list, fitness=creator.FitnessMin) # individual data-type : List
toolbox = base.Toolbox()
'''
Functions
'''
def random_pick(lower: float, upper: float, step: Optional[int] = None) -> float:
# Pick random numbers within specified bounds
if step is None:
return random.uniform(lower, upper)
else:
candidates_num = round((upper - lower) / step)
return lower + random.randint(0, candidates_num) * step
def make_individual(explanatories) -> List[Any]:
individual = []
for explanatory in explanatories:
individual.append(
random_pick(
lower=explanatories[explanatory][0],
upper=explanatories[explanatory][1],
step=explanatories[explanatory][2] if len(explanatories[explanatory]) == 3 else None,
)
)
return creator.Individual(individual)
'''
Main
'''
pop_size = 10
explanatories={
"a": (30, 100, 1), # (low, high, step)
"b": (80, 200, 1),
"c": (15, 80, 1),
"d": (1.5, 5, 0.1),
"e": (15, 200, 1),
"f": (5, 1699, 1),
"g": (0.5, 0.5), # (low, high)
}
toolbox.register("individual", make_individual)
# Check value of individual
ind = toolbox.individual(explanatories) # list
# Population (following is the Bag type of population which is common)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
# Check population
pop = toolbox.population(pop_size) # ERROR
Function random_pick
randomly picks up values for all explanatories within lower & upper bounds by considering step. And function make_individual
is responsible to make individual.
The problem of the above code is where I try to make population. When I run the following line:
pop = toolbox.population(pop_size)
I get the error:
TypeError: make_individual() missing 1 required positional argument: 'explanatories'
My question is that how I can pass explanatories as input argument to "toolbox.population" or "make_individual()" when making a population.
Thank you for your help.
Your problem seems to arise from how tools.initRepeat
takes only three arguments: container
, func
and n
(docs here).
As such, it cannot "pass on" the explanatories
argument to func
(which in this case is toolbox.individual
).
You can get around this by specifying explanatories
as an argument for make_individual
when you register toolbox.individual
.
That is to say, this works:
toolbox.register(
"individual",
make_individual,
explanatories=explanatories # now toolbox.individual uses default explanatories
)
ind = toolbox.individual() # no longer provide explanatories arg
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
pop = toolbox.population(pop_size)
print(int)
print(pop)
and it prints something like
<class 'int'>
[[71, 122, 50, 1.9, 62, 679, 0.5], [88, 192, 24, 3.4000000000000004, 40, 1377, 0.5], [78, 182, 59, 4.1, 65, 1297, 0.5], [39, 174, 49, 3.0, 104, 883, 0.5], [89, 153, 36, 5.0, 102, 718, 0.5], [57, 114, 23, 2.7, 54, 1628, 0.5], [78, 146, 32, 2.1, 145, 961, 0.5], [96, 174, 40, 5.0, 19, 974, 0.5], [39, 150, 80, 4.7, 140, 801, 0.5], [31, 150, 37, 2.8, 109, 1230, 0.5]]