Fitness Normalizers¶
Fitness normalizers are classes which are responsible for normalizing
the fitness values in an EAPopulation. They analyze the
fitness values across the entire population and calculate new ones.
To see how FitnessNormalizer can be used, look at the
documention of the classes which inherit it, for example
Power, Sum DivideByMean. In addition,
multiple FitnessNormalizer can be chained using
Sequence().
Making New Fitness Normalizers¶
A new class inheriting FitnessNormalizer must be made.
This is an abstract base class so its virtual methods need to be
implemented.
-
class
DivideByMean(filter=<function DivideByMean.<lambda>>)¶ Bases:
stk.calculators.ea.fitness_normalizers._FilteringNormalizer,stk.calculators.ea.fitness_normalizers.FitnessNormalizerDivides fitness values by the population mean.
While this function can be used if the fitness value of each
Moleculein theEAPopulationis a single number, it is most useful when the fitness values is alistof numbers. In this case, it is necessary to somehow combine the numbers so that a single fitness value is produced. For example, take a fitness value which is the vector holding the properties[energy, diameter, num_atoms]. For a given molecule these numbers may be something like[200,000, 12, 140]. If we were to sum these numbers, the energy term would dominate the final fitness value. In order to combine these numbers we can divide them by the population averages. For example, if the average energy of molecules in the population is300,000the average diameter is10and the average number of atoms is70then the fitness vector would be scaled to[0.5, 1.2, 2]. These numbers are now of a similar magnitude and can be summed to give a reasonable value. After division , each value represents how much better than the population average each property value is. In essence we have removed the units from each parameter.Examples
Scale fitness values
import stk mean_scaler = stk.DivideByMean() # Normalize the fitness values. # Assume the fitness values are # {mol1: 1, mol2: 2, mol3: 3} normalized = mean_scaler.normalize(pop) # normalized is # {mol1: 0.5, mol2: 1, mol3: 1.5}
Scale fitness vectors
# Create the normalizer. # mean_scaler = DivideByMean() # Normalize the fitness values. # Assume the fitness values are # {mol1: [1, 10, 100], mol2: [2, 20, 100], mol3: [3, 30, 100]}. normalized = mean_scaler.normalize(pop) # normalized is # { # mol1: [0.5, 0.5, 0.5], # mol2: [1, 1, 1], # mol3: [1.5, 1.5, 1.5] # }.
Methods
normalize(self, population)Normalize the fitness values in population.
-
__init__(self, filter=<function DivideByMean.<lambda> at 0x7fcf9d155d40>)¶ Initialize a
DivideByMeaninstance.- Parameters
filter (
callable, optional) – Takes a two parameters, first is aEAPopulationand the second is aMolecule, and returnsTrueorFalse. Only molecules which returnTruewill have fitness values normalized. By default, all molecules will have fitness values normalized. TheEAPopulationon whichnormalize()is called is passed as the first argument while the second argument will be passed everyMoleculein it.
-
normalize(self, population)¶ Normalize the fitness values in population.
- Parameters
population (
EAPopulation) – The molecules which need to have their fitness values normalized.- Returns
Maps every molecule in population to its normalized fitness value.
- Return type
dict
-
-
class
FitnessNormalizer¶ Bases:
stk.calculators.base_calculators.CalculatorAbstract base class for fitness normalizers.
A fitness normalizer takes an
EAPopulationand returns a new set of normalized fitness values for all molecules in it. The primary benefit of a normalizer vs aFitnessCalculatoris that aFitnessNormalizerhas access to all members in the population when it is calculating the new fitness value, whereas aFitnessCalculatordoes not.Methods
normalize(self, population)Normalize the fitness values in population.
-
__init__(self, /, *args, **kwargs)¶ Initialize self. See help(type(self)) for accurate signature.
-
normalize(self, population)¶ Normalize the fitness values in population.
- Parameters
population (
EAPopulation) – The molecules which need to have their fitness values normalized.- Returns
Maps every molecule in population to its normalized fitness value.
- Return type
dict
-
-
class
Multiply(coefficient, filter=<function Multiply.<lambda>>)¶ Bases:
stk.calculators.ea.fitness_normalizers._FilteringNormalizer,stk.calculators.ea.fitness_normalizers.FitnessNormalizerMultiplies the fitness values by some coefficient.
Examples
Multiplying a fitness value by a coefficient.
import stk # Create the normalizer. multiply = stk.Multiply(2) # Normalize the fitness values. Assume the fitness values are # {mol1: 1, mol2: 2, mol3: 3}. normalized = multiply.normalize(pop) # normalized is # {mol1: 2, mol2: 4, mol3: 6}.
Multiplying a vector of fitness values by some coefficient
multiply = stk.Multiply(2) # Normalize the fitness values. Assume the fitness values are # {mol1: [1, 2, 3], mol2: [4, 5, 6], mol3: [7, 8, 9]}. normalized = multiply.normalize(pop) # normalized is # {mol1: [2, 4, 6], mol2: [8, 10, 12], mol3: [14, 16, 18]}.
Multiplying a vector of fitness values by different coefficients
multiple = stk.Multiply([1, 2, 3]) # Normalize the fitness values. Assume the fitness values are # {mol1: [1, 2, 3], mol2: [4, 5, 6], mol3: [7, 8, 9]}. normalized = multiply.normalize(pop) # normalized is # {mol1: [1, 4, 9], mol2: [4, 10, 18], mol3: [7, 16, 27]}.
Methods
normalize(self, population)Normalize the fitness values in population.
-
__init__(self, coefficient, filter=<function Multiply.<lambda> at 0x7fcf9d1559e0>)¶ Initialize a
Multiplyinstance.- Parameters
coefficient (
floatorlistoffloat) – The coefficients eachfitnessvalue by. Can be a single number or multiple numbers.filter (
callable, optional) – Takes a two parameters, first is aEAPopulationand the second is aMolecule, and returnsTrueorFalse. Only molecules which returnTruewill have fitness values normalized. By default, all molecules will have fitness values normalized. TheEAPopulationon whichnormalize()is called is passed as the first argument while the second argument will be passed everyMoleculein it.
-
normalize(self, population)¶ Normalize the fitness values in population.
- Parameters
population (
EAPopulation) – The molecules which need to have their fitness values normalized.- Returns
Maps every molecule in population to its normalized fitness value.
- Return type
dict
-
-
class
NullFitnessNormalizer¶ Bases:
stk.calculators.ea.fitness_normalizers.FitnessNormalizerDoes nothing.
Methods
normalize(self, population)Normalize the fitness values in population.
-
__init__(self, /, *args, **kwargs)¶ Initialize self. See help(type(self)) for accurate signature.
-
normalize(self, population)¶ Normalize the fitness values in population.
- Parameters
population (
EAPopulation) – The molecules which need to have their fitness values normalized.- Returns
Maps every molecule in population to its normalized fitness value.
- Return type
dict
-
-
class
Power(power, filter=<function Power.<lambda>>)¶ Bases:
stk.calculators.ea.fitness_normalizers._FilteringNormalizer,stk.calculators.ea.fitness_normalizers.FitnessNormalizerRaises fitness values to some power.
This works for cases where the fitness value is single
floatand where it islistoffloat.Examples
Raising a fitness value by some power
import stk pop = stk.Population(...) # Assume this returns {mol1: 1, mol2: 2, mol3: 3}. pop.get_fitness_values() # Create the normalizer. power = stk.Power(2) # Normalize the fitness values. normalized = power.normalize(pop) # normalized is {mol1: 1, mol2: 4, mol3: 9}.
Raising vector valued fitness values by some power
# Create the normalizer. power = stk.Power(2) # Normalize the fitness values. Assume the fitness values are # {mol1: [1, 2, 3], mol2: [4, 5, 6], mol3: [7, 8, 9]}. normalized = power.normalize(pop) # normalized is # {mol1: [1, 4, 9], mol2: [16, 25, 36], mol3: [49, 64, 81]}.
Raising vector valued fitness values by different powers
# Create the normalizer. power = stk.Power([1, 2, 3]) # Normalize the fitness values. Assume the fitness values are # {mol1: [1, 2, 3], mol2: [4, 5, 6], mol3: [7, 8, 9]}. # Normalize the fitness values. normalized = power.normalize(pop) # normalized is # {mol1: [1, 4, 27], mol2: [4, 25, 216], mol3: [7, 64, 729]}.
Methods
normalize(self, population)Normalize the fitness values in population.
-
__init__(self, power, filter=<function Power.<lambda> at 0x7fcf9d155830>)¶ Initialize a
Powerinstance.- Parameters
power (
floatorlistoffloat) – The power to raise eachfitnessvalue to. Can be a single number or multiple numbers.filter (
callable, optional) – Takes a two parameters, first is aEAPopulationand the second is aMolecule, and returnsTrueorFalse. Only molecules which returnTruewill have fitness values normalized. By default, all molecules will have fitness values normalized. TheEAPopulationon whichnormalize()is called is passed as the first argument while the second argument will be passed everyMoleculein it.
-
normalize(self, population)¶ Normalize the fitness values in population.
- Parameters
population (
EAPopulation) – The molecules which need to have their fitness values normalized.- Returns
Maps every molecule in population to its normalized fitness value.
- Return type
dict
-
-
class
ReplaceFitness(replacement_fn, filter=<function ReplaceFitness.<lambda>>)¶ Bases:
stk.calculators.ea.fitness_normalizers.FitnessNormalizerReplaces fitness values of a certain value with a new value.
Examples
Replace all fitness values which are
Nonewith the half the minimum fitness value in the populationimport stk replacer = stk.ReplaceFitness( replacement_fn=lambda population: min( f for _, f in population.get_fitness_values() if f is not None ) / 2, filter=lambda population, mol: population.get_fitness_values()[mol] is None, )
Methods
normalize(self, population)Normalize the fitness values in population.
-
__init__(self, replacement_fn, filter=<function ReplaceFitness.<lambda> at 0x7fcf9d1570e0>)¶ Initialize a
ReplaceFitnessinstance.- Parameters
replacement_fn (
callable) – Takes a single parameter, thePopulationwhich needs to be normalized, before it is filtered, and returns anobjectwhich is used as the new fitness value for all molecules which pass the filter.filter (
callable, optional) – Takes a two parameters, first is aEAPopulationand the second is aMolecule, and returnsTrueorFalse. Only molecules which returnTruewill have fitness values replaced. By default, all molecules will have fitness values replaced. TheEAPopulationon whichnormalize()is called is passed as the first argument while the second argument will be passed everyMoleculein it.
-
normalize(self, population)¶ Normalize the fitness values in population.
- Parameters
population (
EAPopulation) – The molecules which need to have their fitness values normalized.- Returns
Maps every molecule in population to its normalized fitness value.
- Return type
dict
-
-
class
ShiftUp(filter=<function ShiftUp.<lambda>>)¶ Bases:
stk.calculators.ea.fitness_normalizers._FilteringNormalizer,stk.calculators.ea.fitness_normalizers.FitnessNormalizerShifts negative fitness values to be positive.
Assume you have a vector-valued fitness value, where each number represents a different property of the molecule
{mol1: [1, -10, 1]}
One way to convert the vector-valued fitness value into a scalar fitness value is by summing the elements, and the result in this case would be
-8. Clearly this doesn’t work, because the resulting fitness value is not a positive number. To fix this, the-10should be shifted to a positive value.ShiftUpfinds the minimum value of each element in the vector-valued fitness value across the entire population, and for element where this minimum value is less than0, shifts up the element value for every molecule in the population, so that the minimum value in the entire population is1.For example, take a population with the vector-valued fitness values
fitness_values = { mol1: [1, -5, 5], mol2: [3, -10, 2], mol3: [2, 20, 1], }
After normalization the fitness values will be.
normalized = { mol1: [1, 6, 5], mol2: [3, 1, 2], mol3: [2, 31, 1], }
This
ShiftUpalso works when the fitness value is a single value.Examples
# Create the normalizer. shifter = ShiftUp() # Normalize the fitness values. Assume the fitness values are # {mol1: [1, -2, 3], mol2: [4, 5, -6], mol3: [7, 8, 9]}. normalized = shifter.normalize(pop) # normalized is # {mol1: [1, 1, 10], mol2: [4, 8, 1], mol3: [7, 11, 16]}.
Methods
normalize(self, population)Normalize the fitness values in population.
-
__init__(self, filter=<function ShiftUp.<lambda> at 0x7fcf9d155ef0>)¶ Initialize a
ShiftUpinstance.- Parameters
filter (
callable, optional) – Takes a two parameters, first is aEAPopulationand the second is aMolecule, and returnsTrueorFalse. Only molecules which returnTruewill have fitness values normalized. By default, all molecules will have fitness values normalized. TheEAPopulationon whichnormalize()is called is passed as the first argument while the second argument will be passed everyMoleculein it.
-
normalize(self, population)¶ Normalize the fitness values in population.
- Parameters
population (
EAPopulation) – The molecules which need to have their fitness values normalized.- Returns
Maps every molecule in population to its normalized fitness value.
- Return type
dict
-
-
class
Sum(filter=<function Sum.<lambda>>)¶ Bases:
stk.calculators.ea.fitness_normalizers._FilteringNormalizer,stk.calculators.ea.fitness_normalizers.FitnessNormalizerSums the values in a
list.Examples
# Create the normalizer. sum_normalizer = stk.Sum() # Normalize the fitness values. Assume the fitness values are # {mol1: [1, 2, 3], mol2: [4, 5, 6], mol3: [7, 8, 9]}. normalized = sum_normalizer.normalize(pop) # normalized is # {mol1: 6, mol2: 15, mol3: 24}
Methods
normalize(self, population)Normalize the fitness values in population.
-
__init__(self, filter=<function Sum.<lambda> at 0x7fcf9d155b90>)¶ Initialize a
Suminstance.- Parameters
filter (
callable, optional) – Takes a two parameters, first is aEAPopulationand the second is aMolecule, and returnsTrueorFalse. Only molecules which returnTruewill have fitness values normalized. By default, all molecules will have fitness values normalized. TheEAPopulationon whichnormalize()is called is passed as the first argument while the second argument will be passed everyMoleculein it.
-
normalize(self, population)¶ Normalize the fitness values in population.
- Parameters
population (
EAPopulation) – The molecules which need to have their fitness values normalized.- Returns
Maps every molecule in population to its normalized fitness value.
- Return type
dict
-