Strongly typed, type mismatch

231 views
Skip to first unread message

Pierre-Yves Mathieu

unread,
Apr 22, 2014, 3:13:04 PM4/22/14
to deap-...@googlegroups.com
Hi, long time no see,

I am still working on a strongly type genetic programming, I have been having lots of error where the system send numpy.ndarray as argument of a function which is strictly for Boolean value. this raise errors and problems to my search for solution. Right now I give a very bad fitness score to individual with error on them but I would like to avoid them completely as they occupy a large part of the initial individual seed, rendering my GP analysis very unstable.
It is unstable because sometime I begin with 300 good solution and other 200 of them are bad which mean I don't cover the same solution space each run.


pset.addPrimitive(identityo, [object], object)
pset.addPrimitive(identityb, [bool], bool)
pset.addPrimitive(identitya, [numpy.ndarray], numpy.ndarray)

pset.addPrimitive(OR, [bool, bool], bool)
pset.addPrimitive(IF1T, [bool, bool, bool], bool)
pset.addPrimitive(IF1T, [bool, numpy.ndarray, numpy.ndarray], numpy.ndarray)

pset.addPrimitive(add, [numpy.ndarray, numpy.ndarray], numpy.ndarray)
pset.addPrimitive(sub, [numpy.ndarray, numpy.ndarray], numpy.ndarray)
pset.addTerminal(True, bool, "TRUE")
pset.addTerminal(False, bool, "FALSE") 

pset.renameArguments(ARG1="day_sunday") #boolean
pset.renameArguments(ARG2="day_monday") #boolean

pset.addPrimitive(sub, [numpy.ndarray, numpy.ndarray], numpy.ndarray)

pset.addTerminal(numpy.array([0,0,0]), numpy.ndarray, "Null")
pset.addTerminal(numpy.array([1,0,0]), numpy.ndarray, "VAL1")
pset.addTerminal(numpy.array([0,1,0]), numpy.ndarray, "VAL2")
pset.addTerminal(numpy.array([0,0,1]), numpy.ndarray, "VAL3")

identityo(OR(sub(Null, Null), day_monday))
The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

the problem is Deap sending sub which return numpy.ndarray to OR which takes boolean value only

Félix-Antoine Fortin

unread,
Apr 22, 2014, 5:49:16 PM4/22/14
to deap-...@googlegroups.com
Why do you add the following function to your pset ?
pset.addPrimitive(identityo, [object], object) 

Regards,
Félix-Antoine

--
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.

Pierre-Yves Mathieu

unread,
Apr 23, 2014, 10:19:13 AM4/23/14
to deap-...@googlegroups.com
well otherwise I sometimes get an error telling me that the GP can't find a primitive of type object. This is weird  but easy to fix by providing an identity object.

Félix-Antoine Fortin

unread,
Apr 23, 2014, 10:20:27 AM4/23/14
to deap-...@googlegroups.com
How do you initialize your primitive set?

Félix-Antoine

Pierre-Yves Mathieu

unread,
Apr 23, 2014, 11:55:52 AM4/23/14
to deap-...@googlegroups.com
Here is a pastebin of my script:
 

thank you very much for your help!

Félix-Antoine Fortin

unread,
Apr 24, 2014, 9:23:44 AM4/24/14
to deap-...@googlegroups.com
Could you show how you generate your individual?

I am guessing you forgot to specify the return type argument, which by default is equal to the class object and this is why you had to add 
pset.addPrimitive(identityo, [object], object)

Félix-Antoine

Pierre-Yves Mathieu

unread,
Apr 30, 2014, 3:27:24 PM4/30/14
to deap-...@googlegroups.com
that probably it, I don't really know  as I use the example, here is some more code:
 


BTW: is it possible to inject a single individual in the beginning population, effectively "continuing" computation with some of the last computation results?

Pierre-Yves Mathieu

unread,
Apr 30, 2014, 3:28:32 PM4/30/14
to deap-...@googlegroups.com
there is :
pset = gp.PrimitiveSetTyped("MAIN", [bool]*n, numpy.ndarray)
 inside the initNode function, I tough the last argument is the output type!

Félix-Antoine Fortin

unread,
Apr 30, 2014, 3:34:38 PM4/30/14
to deap-...@googlegroups.com
Yes, and no…

Since, the generate functions are also used with mutation, the default type is not set to the primitive set return type.
The default type is 'object' because generate functions are the same for standard GP and STGP.

However, I have to admit that this is not exactly intuitive. I will look to modify the generate function to use by default the pset return type, and if return type is specified to use this value instead.

Stay tuned.
Félix-Antoine

Félix-Antoine Fortin

unread,
Apr 30, 2014, 4:23:46 PM4/30/14
to deap-...@googlegroups.com
This is now fixed and will be part of release 1.0.2.

Just install the version from the Mercurial repository tip if you are interested in using it before the release.

Following this change, you will no longer need to add the function 'identityo' to your primitive set.

We have also updated the documentation accordingly.

Thanks for the indirect bug report!

Regards,
Félix-Antoine

Pierre-Yves Mathieu

unread,
Apr 30, 2014, 6:11:21 PM4/30/14
to deap-...@googlegroups.com
I am very glad I could help! I love this project! do you know about this:

1-: is it possible to feed some individual in the initial population (can you point me to how)
2-: is it possible to have initial population say 5-6 (n) time bigger easily. this would diminish effect of luck in initial position in the solution space

thank you,

Pierre-Yves Mathieu

unread,
Apr 30, 2014, 6:21:18 PM4/30/14
to deap-...@googlegroups.com
And

I am unfamiliar with mercurial, generally I use git to install through pip

like this: http://stackoverflow.com/a/20101940/1622838

is it possible to do the same and how? I tried:

sudo pip install -e hg+https://code.google.com/p/deap/@1.0.2#egg=Package

getting:

abort: unknown revision '1.0.2'!
  Complete output from command /usr/bin/hg update -q 1.0.2:
 
----------------------------------------
Cleaning up...
Command /usr/bin/hg update -q 1.0.2 failed with error code 255 in /home/dog/src/package
Storing debug log for failure in /home/dog/.pip/pip.log

Félix-Antoine Fortin

unread,
Apr 30, 2014, 6:23:43 PM4/30/14
to deap-...@googlegroups.com
Your pip command is correct, except there is no tag for version 1.0.2 yet. Use the name "default" instead.

Félix-Antoine
--
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.


--
Félix-Antoine Fortin

Pierre-Yves Mathieu

unread,
Apr 30, 2014, 7:27:49 PM4/30/14
to deap-...@googlegroups.com
I posted twice, sorry, I was also asking about this to help me out:

Marc-André Gardner

unread,
Apr 30, 2014, 10:12:12 PM4/30/14
to deap-...@googlegroups.com
Hi Pierre-Yves,

For your first question, yes it is possible, see http://deap.gel.ulaval.ca/doc/default/tutorials/basic/part1.html#seeding-a-population
Apply it to GP suppose to use the from_string classmethod, so it's a bit less straightforward than the example, but you should have no serious trouble (except maybe with ephemerals, if you have some).

As for the second question, what does prevent you from simply use n=5*nIndiv (taken from your code) in the call to toolbox.population? If it's simply computational effort, then you may want to use a parallel map (for instance by using Pool.map from multiprocessing, which does not involve any extra installation). If you just want to have a bigger population in the _initial_ generation, then you can create a bigger population, evaluate its individuals, and then select the 1/x best ones (for instance len(pop)*0.2) by using toolbox.selBest(), or even a tournament if you want to avoid too much elitism. Once it is selected, then you can feed it to the algorithm as the "real" initial population.

Have fun with DEAP,

Marc-André Gardner

Pierre-Yves Mathieu

unread,
May 1, 2014, 10:41:30 AM5/1/14
to deap-...@googlegroups.com
Thank you very much I will try that!

For the initial subject, using version 1.0.2 solve almost everything,

I still find it is necessary to provide at least  on primitive, other than a terminal, of every types to avoid error message.

Say I have vectors terminal [x,y,z] described as unit vector "unrotated" ( [1,0,0][0,1,0][0,0,1] ) and float 0.3, 0.6  to provide some fine scaling possibilitiesé

then the gp is able to find this solutiuon 0.3 * [1,0,0]. which we will consider the "good" one.

with only that we need at least the primitive vectors and floats and a single primitive in our pset:

in random pseudo code:
coef(float f, vector v): # which return a vector  (they really are numpy array tough)

This brings back the initial error, "there is no primitive of type float to choose". This isn't a real error as I don't want to provide one to keep. It should not be I think!

hope this help!

Thank you, I am having quite a lot of fun seriously! have a nice day!
Reply all
Reply to author
Forward
0 new messages