how to minimize a function using Deap?

1,479 views
Skip to first unread message

Luca Puggini

unread,
Mar 14, 2014, 8:37:07 AM3/14/14
to deap-...@googlegroups.com

I need to minimize a function using genetic algorithm and PSO.

Different posts suggest to use DEAP I do not even understand how to start.

We can consider for example f on the interval i

i=arange(-10,10,0.1)
def f(x):
    return x*sin(x)

How can I minimize this function using DEAP?

François-Michel De Rainville

unread,
Mar 14, 2014, 6:29:06 PM3/14/14
to deap-...@googlegroups.com

Dear Luca,

The first thing to do would be to study the theory behind evolutionary computation. There exist an excellent introductory book by Melanie Mitchell, An introduction to genetic algorithm. Then, you can browse the  tutorials of DEAP that will help you understand the concepts behind the library. Finally you can have a look at the examples that will show you his to use DEAP in multiple optimisation scenarios.

Have fun with DEAP,
François-Michel

--
You received this message because you are subscribed to the Google Groups "deap-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to deap-users+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Luca Puggini

unread,
Mar 17, 2014, 6:02:18 AM3/17/14
to deap-...@googlegroups.com
Dear Francois,
my knowledge of GA is very limited and your book would be very useful.  The problem is that I did not find any example of how to use the library to minimize function.
I would probably be able to solve this problem using matlab but I would like to use python as much as possible. 

Can you send me the link to some good examples of how to minimize a function with DEAP? 

Thanks
Luca 

Félix-Antoine Fortin

unread,
Mar 17, 2014, 8:30:14 AM3/17/14
to deap-...@googlegroups.com
Have you look at DEAP's documentation online?

Félix-Antoine

Marc-André Gardner

unread,
Mar 17, 2014, 9:52:20 PM3/17/14
to deap-...@googlegroups.com
There's a GA example (I know it's not PSO, but it is still useful to learn about the individual representation and evaluation procedure), in "examples/ga/kursawefct.py", which show the optimisation of this function. You can also have a look at the basic PSO examples (in examples/pso/basic.py) which should tell you more about the PSO representation in DEAP.

However, as suggested by Félix and François-Michel, you ought to begin by learning a bit more about GA/PSO and the DEAP philosophy. It may seem like a waste of time, but you will end up saving a lot of unsuccessful experiments if you have a good understanding of what's going on behind the screen...

Have fun with DEAP,

Marc-André

Luca Puggini

unread,
Mar 18, 2014, 4:11:29 AM3/18/14
to deap-...@googlegroups.com
Thanks for all the answers. 
The problem with the documentation is that almost every link to the examples is broken. 
I will check the examples inside the repository. 

I need time to think about that. I will let you know how does it go.

Thanks!

Félix-Antoine Fortin

unread,
Mar 18, 2014, 5:08:01 AM3/18/14
to deap-...@googlegroups.com
What links are broken?
Félix-Antoine Fortin

François-Michel De Rainville

unread,
Mar 18, 2014, 7:38:39 AM3/18/14
to deap-...@googlegroups.com

Luca Puggini

unread,
Mar 18, 2014, 8:01:28 AM3/18/14
to deap-...@googlegroups.com
you are right now they are working. 
Maybe it was a my problem. 
To unsubscribe from this group and stop receiving emails from it, send an email to deap-users+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Luca Puggini

unread,
Mar 18, 2014, 11:47:31 AM3/18/14
to deap-...@googlegroups.com


Thanks to your help I am getting closer to the solution but I have still a problem.
Can you please help me with this? 

This is my code (you can reproduce it) It should be easy to understand.
Let me know!


#import some libraries not all are needed

from mpl_toolkits.mplot3d import Axes3D

import numpy as np

from numpy import *

from numpy.linalg import *

import sklearn as sk

import scipy as sp

import scipy.io

from matplotlib.pyplot import *

from scipy.interpolate import *

from scipy.optimize import minimize

from scipy.misc import derivative

from sklearn.preprocessing import *

from scipy.optimize import *


#define the t variable

t1=linspace(-50,50,100)

#define two set of points sig1 and sig2

sig1=sin(t1/2)+np.random.normal(scale=0.1,size=len(t1))

sig2=sin(t1/2)+np.random.normal(scale=0.1,size=len(t1))


# built 2 function f0 and g

f0=interp1d(t1,sig1,kind="cubic",bounds_error=False,fill_value=-10000)

g=interp1d(t1,sig2,kind="cubic",bounds_error=False,fill_value=10000)


#Define some value

A=2

B=0.8

#this is the function that I would like to estimate

def s(t):

return A+B*t+

 


def inv_s(t):

return (t-B)/A


# this is a reparametrization of f0 so my signals now not are aligned

def f(t):

return f0(s(t))

#define a new interval where I will study my problem

Ig=arange(t1.min(),t1.max(),1)

If=(Ig-A)/B

I_min=max(If.min(),Ig.min())

I_max=min(If.max(),Ig.max())


J=linspace(min(If.min(),Ig.min()),max(If.max(),Ig.max()))

I=linspace(I_min,I_max,1000)


# here you can visualize the signal

#plot(J,f(J),J,g(J))

#ylim(-1.2,1.2)


#This is the cost function that I would like to minimize the solution is x=[A,B]

def cost(x,T=I):

a=x[0]

b=x[1]

return norm(g(b*T+a)-f(T))/len(T)


#this is the code from deap pso example

# only one line is changed


import operator

import random


import numpy


from deap import base

from deap import benchmarks

from deap import creator

from deap import tools


creator.create("FitnessMax", base.Fitness, weights=(-1.0,))<-----------------------weights are negative because I want to minize

creator.create("Particle", list, fitness=creator.FitnessMax, speed=list,

smin=None, smax=None, best=None)


def generate(size, pmin, pmax, smin, smax):

part = creator.Particle(random.uniform(pmin, pmax) for _ in range(size))

part.speed = [random.uniform(smin, smax) for _ in range(size)]

part.smin = smin

part.smax = smax

return part


def updateParticle(part, best, phi1, phi2):

u1 = (random.uniform(0, phi1) for _ in range(len(part)))

u2 = (random.uniform(0, phi2) for _ in range(len(part)))

v_u1 = map(operator.mul, u1, map(operator.sub, part.best, part))

v_u2 = map(operator.mul, u2, map(operator.sub, best, part))

part.speed = list(map(operator.add, part.speed, map(operator.add, v_u1, v_u2)))

for i, speed in enumerate(part.speed):

if speed < part.smin:

part.speed[i] = part.smin

elif speed > part.smax:

part.speed[i] = part.smax

part[:] = list(map(operator.add, part, part.speed))


toolbox = base.Toolbox()

toolbox.register("particle", generate, size=2, pmin=-6, pmax=6, smin=-3, smax=3)

toolbox.register("population", tools.initRepeat, list, toolbox.particle)

toolbox.register("update", updateParticle, phi1=2.0, phi2=2.0)

toolbox.register("evaluate", cost) #<----------------------------------------------I replaced the default function with cost


def main():

pop = toolbox.population(n=5)

stats = tools.Statistics(lambda ind: ind.fitness.values)

stats.register("avg", numpy.mean)

stats.register("std", numpy.std)

stats.register("min", numpy.min)

stats.register("max", numpy.max)


logbook = tools.Logbook()

logbook.header = ["gen", "evals"] + stats.fields


GEN = 1000

best = None


for g in range(GEN):

for part in pop:

part.fitness.values = toolbox.evaluate(part)#<----------- this line return an error I should probably define the cost function in another way. HOW?

if not part.best or part.best.fitness < part.fitness:

part.best = creator.Particle(part)

part.best.fitness.values = part.fitness.values

if not best or best.fitness < part.fitness:

best = creator.Particle(part)

best.fitness.values = part.fitness.values

for part in pop:

toolbox.update(part, best)


# Gather all the fitnesses in one list and print the stats

logbook.record(gen=g, evals=len(pop), **stats.compile(pop))

print(logbook.stream)

return pop, logbook, best


if __name__ == "__main__":

main()



###############################################
This is the error message:

    part.fitness.values = toolbox.evaluate(part)
  File "/usr/local/lib/python2.7/dist-packages/deap-1.0.0-py2.7.egg/deap/base.py", line 184, in setValues
    self.wvalues = tuple(map(mul, values, self.weights))
TypeError: Both weights and assigned values must be a sequence of numbers when assigning to values of <class 'deap.creator.FitnessMax'>. Currently assigning value(s) 279.99751771591866 of <type 'numpy.float64'> to a fitness with weights (-1.0,).

Félix-Antoine Fortin

unread,
Mar 18, 2014, 12:46:51 PM3/18/14
to deap-...@googlegroups.com
As covered in the tutorial and the documentation, your fitness or cost function should always return a tuple even if it is single-objective. Therefore, simply add a comma after len(T) in your cost function. This is also what is explicitly said by the error message you got "Both weights and assigned values must be a sequence of numbers".

In order to help other users scavenge information from the mailing-list, we would appreciate if you could follow the mailing-list guidelines. More precisely, when you want to share code, please use a service like Github gist or pastebin, and we could not insist enough on the importance of reading the documentation...

Félix-Antoine

Luca Puggini

unread,
Mar 20, 2014, 7:24:25 AM3/20/14
to deap-...@googlegroups.com
Thanks for the help.
I have been able to solve.  

Sorry for the code I will try to pay more attention to the rules.

I have a last small question.

How can I set the interval where my population should be? 
I have a minimization problem of 3 variables I would like to seed the population of the first variable in the interval [a1,a2] and the population of  the second one in [b1,b2] and so on.
In the case of the PSO algorithm I also need to define different velocity for each variable

(My understanding is that by default all the variables are initialized between pmin and  pmax). 

To define the population should I use the "A funky one " of the documentation or there is something of easier?


Let me know.
Thanks,
Luca

François-Michel De Rainville

unread,
Mar 20, 2014, 9:18:40 AM3/20/14
to deap-...@googlegroups.com
You are allowed to change the code inside the particle generation function. Just allow it to receive sequences; the lower and upper bounds for the initial position and speed. These arguments should be provided at there registration in the toolbox.

The funky individual is to have an individual with attribute being of different types.

Cheers,
François-Michel

Luca Puggini

unread,
Mar 21, 2014, 6:19:32 AM3/21/14
to deap-...@googlegroups.com
Hi,
thanks for the answer but I am not sure that I understood.
I have changed the line
part = creator.Particle(random.uniform(pmin[i], pmax[i]) for i in range(size)) in the generator function but after the update the particles are again out of their zone.

Can I ask where is the creator.Particle function? It is not in the deap/creator file .

By the way I have found the broken link I was talking about
It is at the end of page http://code.google.com/p/deap/wiki/PSOExample (https://deap.googlecode.com/hg/examples/pso_basic.py)

Let me know.
Best,
Luca

François-Michel De Rainville

unread,
Mar 24, 2014, 12:01:29 PM3/24/14
to deap-...@googlegroups.com
The wiki pages are marked deprecated, however thanks for reporting this, we have changed to a simple link to the official documentation.

The creator.Particle class is created by the creator on the line creator.create("Particle", ...) at runtime, as explained in the documentation.

Furthermore, to keep the particles inside their zone after the update you have to modify the update method to enforce constraints.
Reply all
Reply to author
Forward
0 new messages