I contain a population of parameter-combination
Construct me with a callable evaluation func, a sequence of parameter names, and a sequence of bounds containing 2-tuples that each define the lower and upper limits of the values:
func: A callable to which an
Individualcan send its parameter values and from which it receives a sum-of-squared error float value as a result.
- names: A sequence of parameter names.
- bounds: A list of 2-tuples, one for each parameter name. The first element of each tuple is the lower bound of a parameter in the second the upper bound.
The callable func must accept a single 1-D Numpy array as its sole argument and return the sum of squared errors (SSE) as a single float value. To shut down ade, it can return a negative SSE value. If ade is shutting down, it will use None as the argument, and the callable should act accordingly.
|kw||constraints||A list of callables that enforce any constraints on your parameter values.
|popsize||The number of individuals per parameter in the population, if not the default.|
|complaintCallback||A callable that my |
|targetFraction||Set this to a (small) float to override my default target for the total score of improvements in each iteration.|
|Instance Variable||popsize||The number of individuals per parameter. The population size will scale with the number of parameters, up until Np_max is reached. Default is 10 individuals per parameter.|
|Instance Variable||Np_min||Minimum population size, i.e., my total number of individuals. Default is 20.|
|Instance Variable||Np_max||Maximum population size. Default is 500, which is really pretty big.|
|Instance Variable||targetFraction||The desired total score of improvements in each iteration in order for
ade's adaptive algorithm to not change the current differential
|Instance Variable||running||Indicates my run status:
|Method||__getitem__||Sequence-like access to my individuals.|
|Method||__setitem__||Use only this method (item setting) and
|Method||__len__||Sequence-like container of individuals: length.|
|Method||__iter__||Sequence-like container of individuals: iteration.|
|Method||__contains__||Sequence-like container of individuals: "in".|
|Method||iSorted 0||Property: A list of my individuals, sorted by increasing (worsening) SSE.|
|Method||iSorted||Property: "Deleting" my sorted list of individuals forces regeneration of the sorted list that will be returned next time the iSorted property is accessed.|
|Method||__repr__||An informative string representation with a text table of my best individuals.|
|Method||limit||Limits the individual's parameter values to the bounds in the way that
|Method||spawn||Spawns a new
|Method||abort||Aborts my operations ASAP. Repeated calls will release any locks that got acquired since the last call.|
|Method||setup||Sets up my initial population using a Latin hypercube to initialize pseudorandom parameter values with minimal clustering.|
|Method||save||(Not implemented yet.)|
|Method||addCallback||Adds callable func to my reporter's list of functions to call
each time there is a significantly better
|Method||replacement||Records the replacement of an
|Method||report||Provides a message via the log messenger about the supplied Individual, optionally with a comparison to another Individual.|
|Method||push||Pushes the supplied
|Method||sample||Returns a sample of N indices from my population that are unique from each other and from any excluded indices supplied as additional arguments.|
|Method||individuals||Immediately returns a list of the individuals at the specified integer index or indices.|
|Method||lock||Obtains the locks for individuals at the specified indices, submits a
request to acquire them, and returns a
|Method||release||Releases any active lock for individuals at the specified index or indices.|
|Method||best||Returns my best individual, or
Trueto show individuals getting replaced. (Results in a very messy log or console display.)
Noneafter instantiation but before
Trueafter setup, and
Falseif ade is aborting.
Population(func, names, bounds, constraints=, popsize=None,
Use only this method (item setting) and
push to replace
Sequence-like container of individuals: length.
My length will be equal to my Np attribute unless setup has not been completed.
def iSorted 0(self):
Property: A list of my individuals, sorted by increasing (worsening) SSE.
Property: "Deleting" my sorted list of individuals forces regeneration of the sorted list that will be returned next time the iSorted property is accessed.
Limits the individual's parameter values to the bounds in the way that
is configured to do, modifying the individual in place.
Spawns a new
Individual with the
supplied values. If fromUnity is set
values are converted from 0-1 range into their proper ranges.
Aborts my operations ASAP. Repeated calls will release any locks that got acquired since the last call.
calls this with ignoreReporter set
True to avoid
def setup(self, uniform=False, blank=False, filePath=None):
Sets up my initial population using a Latin hypercube to initialize pseudorandom parameter values with minimal clustering.
Unless uniform is set, that is. Then each parameter values is just uniformly random without regard to the others.
With parameter constraints, the Latin hypercube doesn't work that well. The initial values matrix must be refreshed, perhaps many times. But it may still be better than uniform initial population sampling.
TODO: Load from filePath.
Sets my running flag
True and returns a
Deferred that fires when the population has been set up.
|kw||uniform||Use uniform random variates instead of a Latin hypercube (LHS). Using LHS (the default) is usually better because initializes pseudorandom parameter values with minimal clustering.|
(Not implemented yet.)
This will save my individuals to a data file at filePath in a way that can repopulate a new instance of me with those same individuals and without any evaluations being required.
Records the replacement of an
Individual in this
generation or iteration.
Call with an integer rounded improvement ratio in a loser's SSE vs. the successful challenger's SSE, unless you are calling to inquire about whether the status quo F value(s) should be maintained or to set my statusQuoteScore with the sqs keyword.
Three types of calls
The rounded improvement ratio rir indicates how much better the challenger is than the individual it replaced. I use that ratio to adjust a running score for the current iteration to inform the status quo inquiry that will occur when the iteration is done, unless I'm not running in adaptive mode.
You can set my target statusQuoScore by setting sqs to a (small) float value. That will replace my default value for future evaluation of replacement individuals.
Finally, a status quo inquiry is a call with no keywords set. I will
determine if the replacements that occurred in the previous
generation/iteration were enough to warrant maintaining the status quo,
and then reset the record. You will receive a result of
if the status quote should be maintained.
The status quo should be maintained if several small improvements are made, or fewer larger ones, with the required number and/or size increasing for a larger population. For small populations where even a single improvement would be significant, the probability of status quo maintenance increases with smaller population and will sometimes happen even with no improvements for a given generation or iteration.
An rir of 1 indicates that the successful challenger was better (i.e., lower) and not considered equivalent to that of the individual it replaced, and that its SSE was no better than 1.5x as good (2/3 as high) as the replaced individual's SSE. An rir of 2 indicates that the challenger had an SSE between 1.5x and 2.5x better than (2/5 to 2/3 as high as) the individual it replaced.
I don't give much weight to an rir of 1. The improvement is
pretty modest and could be as little as 2% (assuming
Reporter.minDiff=0.02, the default). An rir of 2 gets
five times as much weight as that.
An rir of 3 also gets disproportionately more weight, nearly twice as much as rir=2. Beyond that, though, the weight scales in a nearly linear fashion. For example, an rir of 9 adds just a little more than three times to the score (3.67x) as rir=3 does.
Here's a practical example, with a population of 100 individuals: If you see 10 "1" characters on the screen for one iteration with other 90 being "X," your ratio score for that iteration will be 2.5. But if you see just one non-X individual with a "8" character, the score will be 7.25. That one amazing success story counts far more in a sea of failures than a bunch of marginal improvements, which is kind of how evolution works in real life. (See the literature around "hopeful monsters.")
|kw||rir||A rounded improvement ratio obtained from a call to |
Provides a message via the log messenger about the supplied Individual, optionally with a comparison to another Individual.
If no second individual is supplied, the comparison will be with the best individual thus far reported on.
Pushes the supplied
onto my population and kicks out the worst individual there to make
Returns a sample of N indices from my population that are unique from each other and from any excluded indices supplied as additional arguments.
Immediately returns a list of the individuals at the specified integer index or indices.
Obtains the locks for individuals at the specified indices, submits a
request to acquire them, and returns a
Deferred that fires
when all of them have been acquired.
Release the locks (as soon as possible) by calling
the indices that are locked.
If I'm shutting down, the returned
Releases any active lock for individuals at the specified index or indices.
If no indices are supplied, releases all active locks. (This is for aborting only.)