ga.py
1 """!
2 
3 @brief Cluster analysis algorithm: Genetic clustering algorithm (GA).
4 @details Implementation based on papers @cite article::ga::1, @cite article::ga::2.
5 
6 @authors Andrey Novikov, Aleksey Kukushkin (pyclustering@yandex.ru)
7 @date 2014-2018
8 @copyright GNU Public License
9 
10 @cond GNU_PUBLIC_LICENSE
11  PyClustering is free software: you can redistribute it and/or modify
12  it under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  PyClustering is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  GNU General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with this program. If not, see <http://www.gnu.org/licenses/>.
23 @endcond
24 
25 """
26 
27 
28 import numpy as np
29 import math
30 import warnings
31 
32 try:
33  import matplotlib.pyplot as plt
34  import matplotlib.animation as animation
35 except Exception as error_instance:
36  warnings.warn("Impossible to import matplotlib (please, install 'matplotlib'), pyclustering's visualization "
37  "functionality is not available (details: '%s')." % str(error_instance))
38 
39 from pyclustering.cluster import cluster_visualizer
40 from pyclustering.cluster.ga_maths import ga_math
41 
42 
43 
45  """!
46  @brief Genetic algorithm observer that is used to collect information about clustering process on each iteration.
47 
48  """
49 
50  def __init__(self, need_global_best=False, need_population_best=False, need_mean_ff=False):
51  """!
52  @brief Constructs genetic algorithm observer to collect specific information.
53 
54  @param[in] need_global_best (bool): If 'True' then the best chromosomes and its fitness function value (global optimum) for each iteration are stored.
55  @param[in] need_population_best (bool): If 'True' then current (on each iteration) best chromosomes and its fitness function value (local optimum) are stored.
56  @param[in] need_mean_ff (bool): If 'True' then average value of fitness function on each iteration is stored.
57 
58  """
59 
60  # Global best chromosome and fitness function for each population
61  self._global_best_result = {'chromosome': [], 'fitness_function': []};
62 
63  # Best chromosome and fitness function on a population
64  self._best_population_result = {'chromosome': [], 'fitness_function': []};
65 
66  # Mean fitness function on each population
67  self._mean_ff_result = [];
68 
69  # Flags to collect
70  self._need_global_best = need_global_best;
71  self._need_population_best = need_population_best;
72  self._need_mean_ff = need_mean_ff;
73 
74 
75  def __len__(self):
76  """!
77  @brief Returns amount of iterations that genetic algorithm was observed.
78 
79  """
80  global_length = len(self._global_best_result['chromosome']);
81  local_length = len(self._best_population_result['chromosome']);
82  average_length = len(self._mean_ff_result);
83 
84  return max(global_length, local_length, average_length);
85 
86 
87  def collect_global_best(self, best_chromosome, best_fitness_function):
88  """!
89  @brief Stores the best chromosome and its fitness function's value.
90 
91  @param[in] best_chromosome (list): The best chromosome that were observed.
92  @param[in] best_fitness_function (float): Fitness function value of the best chromosome.
93 
94  """
95 
96  if not self._need_global_best:
97  return;
98 
99  self._global_best_result['chromosome'].append(best_chromosome);
100  self._global_best_result['fitness_function'].append(best_fitness_function);
101 
102 
103  def collect_population_best(self, best_chromosome, best_fitness_function):
104  """!
105  @brief Stores the best chromosome for current specific iteration and its fitness function's value.
106 
107  @param[in] best_chromosome (list): The best chromosome on specific iteration.
108  @param[in] best_fitness_function (float): Fitness function value of the chromosome.
109 
110  """
111 
112  if not self._need_population_best:
113  return;
114 
115  self._best_population_result['chromosome'].append(best_chromosome);
116  self._best_population_result['fitness_function'].append(best_fitness_function);
117 
118 
119  def collect_mean(self, fitness_functions):
120  """!
121  @brief Stores average value of fitness function among chromosomes on specific iteration.
122 
123  @param[in] fitness_functions (float): Average value of fitness functions among chromosomes.
124 
125  """
126 
127  if not self._need_mean_ff:
128  return;
129 
130  self._mean_ff_result.append(np.mean(fitness_functions));
131 
132 
133  def get_global_best(self):
134  """!
135  @return (dict) Returns dictionary with keys 'chromosome' and 'fitness_function' where evolution of the best chromosome
136  and its fitness function's value (evolution of global optimum) are stored in lists.
137 
138  """
139  return self._global_best_result;
140 
141 
143  """!
144  @brief (dict) Returns dictionary with keys 'chromosome' and 'fitness_function' where evolution of the current best chromosome
145  and its fitness function's value (evolution of local optimum) are stored in lists.
146 
147  """
148  return self._best_population_result;
149 
150 
152  """!
153  @brief (list) Returns fitness function's values on each iteration.
154 
155  """
156  return self._mean_ff_result;
157 
158 
159 
161  """!
162  @brief Genetic algorithm visualizer is used to show clustering results that are specific for
163  this particular algorithm: clusters, evolution of global and local optimum.
164  @details The visualizer requires 'ga_observer' that collects evolution of clustering process in
165  genetic algorithm. The observer is created by user and passed to genetic algorithm. There
166  is usage example of the visualizer using the observer:
167  @code
168  # Read data for clustering
169  sample = read_sample(SIMPLE_SAMPLES.SAMPLE_SIMPLE1);
170 
171  # Create instance of observer that will collect all information:
172  observer_instance = ga_observer(True, True, True);
173 
174  # Create genetic algorithm where observer will collect information:
175  ga_instance = genetic_algorithm(data=sample,
176  count_clusters=2,
177  chromosome_count=20,
178  population_count=20,
179  count_mutation_gens=1,
180  observer=observer_instance);
181 
182  # Start processing
183  ga_instance.process();
184 
185  # Show cluster using observer:
186  ga_visualizer.show_clusters(sample, observer_instance);
187  @endcode
188 
189  @see cluster_visualizer
190 
191  """
192 
193  @staticmethod
194  def show_evolution(observer, start_iteration = 0, stop_iteration = None, ax = None, display = True):
195  """!
196  @brief Displays evolution of fitness function for the best chromosome, for the current best chromosome and
197  average value among all chromosomes.
198 
199  @param[in] observer (ga_observer): Genetic algorithm observer that was used for collecting evolution in the algorithm and
200  where whole required information for visualization is stored.
201  @param[in] start_iteration (uint): Iteration from that evolution should be shown.
202  @param[in] stop_iteration (uint): Iteration after that evolution shouldn't be shown.
203  @param[in] ax (Axes): Canvas where evolution should be displayed.
204  @param[in] display (bool): If 'True' then visualization of the evolution will be shown by the function.
205  This argument should be 'False' if you want to add something else to the canvas and display it later.
206 
207  @return (Axis) Canvas where evolution was shown.
208 
209  """
210 
211  if (ax is None):
212  _, ax = plt.subplots(1);
213  ax.set_title("Evolution");
214 
215  if (stop_iteration is None):
216  stop_iteration = len(observer);
217 
218  line_best, = ax.plot(observer.get_global_best()['fitness_function'][start_iteration:stop_iteration], 'r');
219  line_current, = ax.plot(observer.get_population_best()['fitness_function'][start_iteration:stop_iteration], 'k');
220  line_mean, = ax.plot(observer.get_mean_fitness_function()[start_iteration:stop_iteration], 'c');
221 
222  if (start_iteration < (stop_iteration - 1)):
223  ax.set_xlim([start_iteration, (stop_iteration - 1)]);
224 
225  ax.set_xlabel("Iteration");
226  ax.set_ylabel("Fitness function");
227  ax.legend([line_best, line_current, line_mean], ["The best pop.", "Cur. best pop.", "Average"], prop={'size': 10});
228  ax.grid();
229 
230  if (display is True):
231  plt.show();
232 
233  return ax;
234 
235 
236  @staticmethod
237  def show_clusters(data, observer, marker = '.', markersize = None):
238  """!
239  @brief Shows allocated clusters by the genetic algorithm.
240 
241  @param[in] data (list): Input data that was used for clustering process by the algorithm.
242  @param[in] observer (ga_observer): Observer that was used for collection information about clustering process.
243  @param[in] marker (char): Type of marker that should be used for object (point) representation.
244  @param[in] markersize (uint): Size of the marker that is used for object (point) representation.
245 
246  @note If you have clusters instead of observer then 'cluster_visualizer' can be used for visualization purposes.
247 
248  @see cluster_visualizer
249 
250  """
251 
252  figure = plt.figure();
253  ax1 = figure.add_subplot(121);
254 
255  clusters = ga_math.get_clusters_representation(observer.get_global_best()['chromosome'][-1]);
256 
257  visualizer = cluster_visualizer(1, 2);
258  visualizer.append_clusters(clusters, data, 0, marker, markersize);
259  visualizer.show(figure, display = False);
260 
261  ga_visualizer.show_evolution(observer, 0, None, ax1, True);
262 
263 
264  @staticmethod
265  def animate_cluster_allocation(data, observer, animation_velocity = 75, movie_fps = 5, save_movie = None):
266  """!
267  @brief Animate clustering process of genetic clustering algorithm.
268  @details This method can be also used for rendering movie of clustering process and 'ffmpeg' is required for that purpuse.
269 
270  @param[in] data (list): Input data that was used for clustering process by the algorithm.
271  @param[in] observer (ga_observer): Observer that was used for collection information about clustering process.
272  Be sure that whole information was collected by the observer.
273  @param[in] animation_velocity (uint): Interval between frames in milliseconds (for run-time animation only).
274  @param[in] movie_fps (uint): Defines frames per second (for rendering movie only).
275  @param[in] save_movie (string): If it is specified then animation will be stored to file that is specified in this parameter.
276 
277  """
278 
279  figure = plt.figure();
280 
281  def init_frame():
282  return frame_generation(0);
283 
284  def frame_generation(index_iteration):
285  figure.clf();
286 
287  figure.suptitle("Clustering genetic algorithm (iteration: " + str(index_iteration) +")", fontsize = 18, fontweight = 'bold');
288 
289  visualizer = cluster_visualizer(4, 2, ["The best pop. on step #" + str(index_iteration), "The best population"]);
290 
291  local_minimum_clusters = ga_math.get_clusters_representation(observer.get_population_best()['chromosome'][index_iteration]);
292  visualizer.append_clusters(local_minimum_clusters, data, 0);
293 
294  global_minimum_clusters = ga_math.get_clusters_representation(observer.get_global_best()['chromosome'][index_iteration]);
295  visualizer.append_clusters(global_minimum_clusters, data, 1);
296 
297  ax1 = plt.subplot2grid((2, 2), (1, 0), colspan = 2);
298  ga_visualizer.show_evolution(observer, 0, index_iteration + 1, ax1, False);
299 
300  visualizer.show(figure, shift = 0, display = False);
301  figure.subplots_adjust(top = 0.85);
302 
303  return [ figure.gca() ];
304 
305  iterations = len(observer);
306  cluster_animation = animation.FuncAnimation(figure, frame_generation, iterations, interval = animation_velocity, init_func = init_frame, repeat_delay = 5000);
307 
308  if (save_movie is not None):
309  cluster_animation.save(save_movie, writer = 'ffmpeg', fps = movie_fps, bitrate = 1500);
310  else:
311  plt.show();
312 
313 
315  """!
316  @brief Class represents Genetic clustering algorithm.
317  @details The searching capability of genetic algorithms is exploited in order to search for appropriate
318  cluster centres.
319 
320  Example of clustering using genetic algorithm:
321  @code
322  # Read input data for clustering
323  sample = read_sample(SIMPLE_SAMPLES.SAMPLE_SIMPLE4);
324 
325  # Create genetic algorithm for clustering
326  ga_instance = genetic_algorithm(data=sample,
327  count_clusters=4,
328  chromosome_count=100,
329  population_count=200,
330  count_mutation_gens=1);
331 
332  # Start clustering process
333  ga_instance.process();
334 
335  # Extract extracted clusters by the algorithm
336  clusters = ga_instance.get_clusters();
337  print(clusters);
338  @endcode
339 
340  There is an example of clustering results (fitness function evolution and allocated clusters) that were
341  visualized by 'ga_visualizer':
342 
343  @image html ga_clustering_sample_simple_04.png
344 
345  @see ga_visualizer
346  @see ga_observer
347 
348  """
349 
350  def __init__(self, data, count_clusters, chromosome_count, population_count, count_mutation_gens=2,
351  coeff_mutation_count=0.25, select_coeff=1.0, observer=ga_observer()):
352  """!
353  @brief Initialize genetic clustering algorithm for cluster analysis.
354 
355  @param[in] data (numpy.array|list): Input data for clustering that is represented by two dimensional array
356  where each row is a point, for example, [[0.0, 2.1], [0.1, 2.0], [-0.2, 2.4]].
357  @param[in] count_clusters (uint): Amount of clusters that should be allocated in the data.
358  @param[in] chromosome_count (uint): Amount of chromosomes in each population.
359  @param[in] population_count (uint): Amount of populations.
360  @param[in] count_mutation_gens (uint): Amount of genes in chromosome that is mutated on each step.
361  @param[in] coeff_mutation_count (float): Percent of chromosomes for mutation, destributed in range (0, 1] and
362  thus amount of chromosomes is defined as follows: 'chromosome_count' * 'coeff_mutation_count'.
363  @param[in] select_coeff (float): Exponential coefficient for selection procedure that is used as follows:
364  math.exp(1 + fitness(chromosome) * select_coeff).
365  @param[in] observer (ga_observer): Observer that is used for collecting information of about clustering process on each step.
366 
367  """
368 
369  # Initialize random
370  np.random.seed()
371 
372  # Clustering data
373  if type(data) is list:
374  self._data = np.array(data)
375  else:
376  self._data = data
377 
378  # Count clusters
379  self._count_clusters = count_clusters
380 
381  # Home many chromosome in population
382  self._chromosome_count = chromosome_count
383 
384  # How many populations
385  self._population_count = population_count
386 
387  # Count mutation genes
388  self._count_mutation_gens = count_mutation_gens
389 
390  # Crossover rate
391  self._crossover_rate = 1.0
392 
393  # Count of chromosome for mutation (range [0, 1])
394  self._coeff_mutation_count = coeff_mutation_count
395 
396  # Exponential coeff for selection
397  self._select_coeff = select_coeff
398 
399  # Result of clustering : best chromosome
400  self._result_clustering = {'best_chromosome': [],
401  'best_fitness_function': 0.0}
402 
403  # Observer
404  self._observer = observer
405 
406  def process(self):
407  """!
408  @brief Perform clustering procedure in line with rule of genetic clustering algorithm.
409 
410  @see get_clusters()
411 
412  """
413 
414  # Initialize population
415  chromosomes = self._init_population(self._count_clusters, len(self._data), self._chromosome_count)
416 
417  # Initialize the Best solution
418  best_chromosome, best_ff, first_fitness_functions \
419  = self._get_best_chromosome(chromosomes, self._data, self._count_clusters)
420 
421  # Save best result into observer
422  if self._observer is not None:
423  self._observer.collect_global_best(best_chromosome, best_ff)
424  self._observer.collect_population_best(best_chromosome, best_ff)
425  self._observer.collect_mean(first_fitness_functions)
426 
427  # Next population
428  for _ in range(self._population_count):
429 
430  # Select
431  chromosomes = self._select(chromosomes, self._data, self._count_clusters, self._select_coeff)
432 
433  # Crossover
434  self._crossover(chromosomes)
435 
436  # Mutation
437  self._mutation(chromosomes, self._count_clusters, self._count_mutation_gens, self._coeff_mutation_count)
438 
439  # Update the Best Solution
440  new_best_chromosome, new_best_ff, fitness_functions \
441  = self._get_best_chromosome(chromosomes, self._data, self._count_clusters)
442 
443  # Get best chromosome
444  if new_best_ff < best_ff:
445  best_ff = new_best_ff
446  best_chromosome = new_best_chromosome
447 
448  # Save best result into observer
449  if self._observer is not None:
450  self._observer.collect_global_best(best_chromosome, best_ff)
451  self._observer.collect_population_best(new_best_chromosome, new_best_ff)
452  self._observer.collect_mean(fitness_functions)
453 
454  # Save result
455  self._result_clustering['best_chromosome'] = best_chromosome
456  self._result_clustering['best_fitness_function'] = best_ff
457 
458  return best_chromosome, best_ff
459 
460 
461  def get_observer(self):
462  """!
463  @brief Returns genetic algorithm observer.
464 
465  """
466  return self._observer
467 
468 
469  def get_clusters(self):
470  """!
471  @brief Returns list of allocated clusters, each cluster contains indexes of objects from the data.
472 
473  @return (list) List of allocated clusters.
474 
475  @see process()
476 
477  """
478 
479  return ga_math.get_clusters_representation(self._result_clustering['best_chromosome'], self._count_clusters)
480 
481 
482  @staticmethod
483  def _select(chromosomes, data, count_clusters, select_coeff):
484  """!
485  @brief Performs selection procedure where new chromosomes are calculated.
486 
487  @param[in] chromosomes (numpy.array): Chromosomes
488 
489  """
490 
491  # Calc centers
492  centres = ga_math.get_centres(chromosomes, data, count_clusters)
493 
494  # Calc fitness functions
495  fitness = genetic_algorithm._calc_fitness_function(centres, data, chromosomes)
496 
497  for _idx in range(len(fitness)):
498  fitness[_idx] = math.exp(1 + fitness[_idx] * select_coeff)
499 
500  # Calc probability vector
501  probabilities = ga_math.calc_probability_vector(fitness)
502 
503  # Select P chromosomes with probabilities
504  new_chromosomes = np.zeros(chromosomes.shape, dtype=np.int)
505 
506  # Selecting
507  for _idx in range(len(chromosomes)):
508  new_chromosomes[_idx] = chromosomes[ga_math.get_uniform(probabilities)]
509 
510  return new_chromosomes
511 
512 
513  @staticmethod
514  def _crossover(chromosomes):
515  """!
516  @brief Crossover procedure.
517 
518  """
519 
520  # Get pairs to Crossover
521  pairs_to_crossover = np.array(range(len(chromosomes)))
522 
523  # Set random pairs
524  np.random.shuffle(pairs_to_crossover)
525 
526  # Index offset ( pairs_to_crossover split into 2 parts : [V1, V2, .. | P1, P2, ...] crossover between V<->P)
527  offset_in_pair = int(len(pairs_to_crossover) / 2)
528 
529  # For each pair
530  for _idx in range(offset_in_pair):
531 
532  # Generate random mask for crossover
533  crossover_mask = genetic_algorithm._get_crossover_mask(len(chromosomes[_idx]))
534 
535  # Crossover a pair
536  genetic_algorithm._crossover_a_pair(chromosomes[pairs_to_crossover[_idx]],
537  chromosomes[pairs_to_crossover[_idx + offset_in_pair]],
538  crossover_mask)
539 
540 
541  @staticmethod
542  def _mutation(chromosomes, count_clusters, count_gen_for_mutation, coeff_mutation_count):
543  """!
544  @brief Mutation procedure.
545 
546  """
547 
548  # Count gens in Chromosome
549  count_gens = len(chromosomes[0])
550 
551  # Get random chromosomes for mutation
552  random_idx_chromosomes = np.array(range(len(chromosomes)))
553  np.random.shuffle(random_idx_chromosomes)
554 
555  #
556  for _idx_chromosome in range(int(len(random_idx_chromosomes) * coeff_mutation_count)):
557 
558  #
559  for _ in range(count_gen_for_mutation):
560 
561  # Get random gen
562  gen_num = np.random.randint(count_gens)
563 
564  # Set random cluster
565  chromosomes[random_idx_chromosomes[_idx_chromosome]][gen_num] = np.random.randint(count_clusters)
566 
567 
568  @staticmethod
569  def _crossover_a_pair(chromosome_1, chromosome_2, mask):
570  """!
571  @brief Crossovers a pair of chromosomes.
572 
573  @param[in] chromosome_1 (numpy.array): The first chromosome for crossover.
574  @param[in] chromosome_2 (numpy.array): The second chromosome for crossover.
575  @param[in] mask (numpy.array): Crossover mask that defines which genes should be swapped.
576 
577  """
578 
579  for _idx in range(len(chromosome_1)):
580 
581  if mask[_idx] == 1:
582  # Swap values
583  chromosome_1[_idx], chromosome_2[_idx] = chromosome_2[_idx], chromosome_1[_idx]
584 
585 
586  @staticmethod
587  def _get_crossover_mask(mask_length):
588  """!
589  @brief Crossover mask to crossover a pair of chromosomes.
590 
591  @param[in] mask_length (uint): Length of the mask.
592 
593  """
594 
595  # Initialize mask
596  mask = np.zeros(mask_length)
597 
598  # Set a half of array to 1
599  mask[:int(int(mask_length) / 6)] = 1
600 
601  # Random shuffle
602  np.random.shuffle(mask)
603 
604  return mask
605 
606 
607  @staticmethod
608  def _init_population(count_clusters, count_data, chromosome_count):
609  """!
610  @brief Returns first population as a uniform random choice.
611 
612  @param[in] count_clusters (uint): Amount of clusters that should be allocated.
613  @param[in] count_data (uint): Data size that is used for clustering process.
614  @param[in] chromosome_count (uint):Amount of chromosome that is used for clustering.
615 
616  """
617 
618  population = np.random.randint(count_clusters, size=(chromosome_count, count_data))
619 
620  return population
621 
622 
623  @staticmethod
624  def _get_best_chromosome(chromosomes, data, count_clusters):
625  """!
626  @brief Returns the current best chromosome.
627 
628  @param[in] chromosomes (list): Chromosomes that are used for searching.
629  @param[in] data (list): Input data that is used for clustering process.
630  @param[in] count_clusters (uint): Amount of clusters that should be allocated.
631 
632  @return (list, float, list) The best chromosome, its fitness function value and fitness function values for
633  all chromosomes.
634 
635  """
636 
637  # Calc centers
638  centres = ga_math.get_centres(chromosomes, data, count_clusters)
639 
640  # Calc Fitness functions
641  fitness_functions = genetic_algorithm._calc_fitness_function(centres, data, chromosomes)
642 
643  # Index of the best chromosome
644  best_chromosome_idx = fitness_functions.argmin()
645 
646  # Get chromosome with the best fitness function
647  return chromosomes[best_chromosome_idx], fitness_functions[best_chromosome_idx], fitness_functions
648 
649 
650  @staticmethod
651  def _calc_fitness_function(centres, data, chromosomes):
652  """!
653  @brief Calculate fitness function values for chromosomes.
654 
655  @param[in] centres (list): Cluster centers.
656  @param[in] data (list): Input data that is used for clustering process.
657  @param[in] chromosomes (list): Chromosomes whose fitness function's values are calculated.
658 
659  @return (list) Fitness function value for each chromosome correspondingly.
660 
661  """
662 
663  # Get count of chromosomes and clusters
664  count_chromosome = len(chromosomes)
665 
666  # Initialize fitness function values
667  fitness_function = np.zeros(count_chromosome)
668 
669  # Calc fitness function for each chromosome
670  for _idx_chromosome in range(count_chromosome):
671 
672  # Get centers for a selected chromosome
673  centres_data = np.zeros(data.shape)
674 
675  # Fill data centres
676  for _idx in range(len(data)):
677  centres_data[_idx] = centres[_idx_chromosome][chromosomes[_idx_chromosome][_idx]]
678 
679  # Get City Block distance for a chromosome
680  fitness_function[_idx_chromosome] += np.sum(abs(data - centres_data))
681 
682  return fitness_function
Common visualizer of clusters on 1D, 2D or 3D surface.
Definition: __init__.py:359
def animate_cluster_allocation(data, observer, animation_velocity=75, movie_fps=5, save_movie=None)
Animate clustering process of genetic clustering algorithm.
Definition: ga.py:265
pyclustering module for cluster analysis.
Definition: __init__.py:1
Genetic algorithm visualizer is used to show clustering results that are specific for this particular...
Definition: ga.py:160
def __init__(self, need_global_best=False, need_population_best=False, need_mean_ff=False)
Constructs genetic algorithm observer to collect specific information.
Definition: ga.py:50
def collect_global_best(self, best_chromosome, best_fitness_function)
Stores the best chromosome and its fitness function&#39;s value.
Definition: ga.py:87
def collect_population_best(self, best_chromosome, best_fitness_function)
Stores the best chromosome for current specific iteration and its fitness function&#39;s value...
Definition: ga.py:103
def process(self)
Perform clustering procedure in line with rule of genetic clustering algorithm.
Definition: ga.py:406
def show_evolution(observer, start_iteration=0, stop_iteration=None, ax=None, display=True)
Displays evolution of fitness function for the best chromosome, for the current best chromosome and a...
Definition: ga.py:194
def __len__(self)
Returns amount of iterations that genetic algorithm was observed.
Definition: ga.py:75
def _crossover(chromosomes)
Crossover procedure.
Definition: ga.py:514
Class represents Genetic clustering algorithm.
Definition: ga.py:314
def _get_best_chromosome(chromosomes, data, count_clusters)
Returns the current best chromosome.
Definition: ga.py:624
def _init_population(count_clusters, count_data, chromosome_count)
Returns first population as a uniform random choice.
Definition: ga.py:608
def _select(chromosomes, data, count_clusters, select_coeff)
Performs selection procedure where new chromosomes are calculated.
Definition: ga.py:483
Genetic algorithm observer that is used to collect information about clustering process on each itera...
Definition: ga.py:44
def collect_mean(self, fitness_functions)
Stores average value of fitness function among chromosomes on specific iteration. ...
Definition: ga.py:119
def get_population_best(self)
(dict) Returns dictionary with keys &#39;chromosome&#39; and &#39;fitness_function&#39; where evolution of the curren...
Definition: ga.py:142
def get_observer(self)
Returns genetic algorithm observer.
Definition: ga.py:461
def get_mean_fitness_function(self)
(list) Returns fitness function&#39;s values on each iteration.
Definition: ga.py:151
def show_clusters(data, observer, marker='.', markersize=None)
Shows allocated clusters by the genetic algorithm.
Definition: ga.py:237
def __init__(self, data, count_clusters, chromosome_count, population_count, count_mutation_gens=2, coeff_mutation_count=0.25, select_coeff=1.0, observer=ga_observer())
Initialize genetic clustering algorithm for cluster analysis.
Definition: ga.py:351
def get_clusters(self)
Returns list of allocated clusters, each cluster contains indexes of objects from the data...
Definition: ga.py:469
def _mutation(chromosomes, count_clusters, count_gen_for_mutation, coeff_mutation_count)
Mutation procedure.
Definition: ga.py:542