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 Andrei Novikov, Aleksey Kukushkin (pyclustering@yandex.ru)
7 @date 2014-2019
9
11  PyClustering is free software: you can redistribute it and/or modify
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  from pyclustering.cluster.ga import genetic_algorithm, ga_observer, ga_visualizer
170  from pyclustering.samples.definitions import SIMPLE_SAMPLES
171
172
173  # Read data for clustering
175
176  # Create instance of observer that will collect all information:
177  observer_instance = ga_observer(True, True, True)
178
179  # Create genetic algorithm where observer will collect information:
180  ga_instance = genetic_algorithm(data=sample,
181  count_clusters=2,
182  chromosome_count=20,
183  population_count=20,
184  count_mutation_gens=1,
185  observer=observer_instance)
186
187  # Start processing
188  ga_instance.process()
189
190  # Obtain results
191  clusters = ga_instance.get_clusters()
192
193  # Print cluster to console
194  print("Amount of clusters: '%d'. Clusters: '%s'" % (len(clusters), clusters))
195
196  # Show cluster using observer:
197  ga_visualizer.show_clusters(sample, observer_instance)
198  @endcode
199
200  @see cluster_visualizer
201
202  """
203
204  @staticmethod
205  def show_evolution(observer, start_iteration = 0, stop_iteration=None, ax=None, display=True):
206  """!
207  @brief Displays evolution of fitness function for the best chromosome, for the current best chromosome and
208  average value among all chromosomes.
209
210  @param[in] observer (ga_observer): Genetic algorithm observer that was used for collecting evolution in the algorithm and
211  where whole required information for visualization is stored.
212  @param[in] start_iteration (uint): Iteration from that evolution should be shown.
213  @param[in] stop_iteration (uint): Iteration after that evolution shouldn't be shown.
214  @param[in] ax (Axes): Canvas where evolution should be displayed.
215  @param[in] display (bool): If 'True' then visualization of the evolution will be shown by the function.
216  This argument should be 'False' if you want to add something else to the canvas and display it later.
217
218  @return (Axis) Canvas where evolution was shown.
219
220  """
221
222  if (ax is None):
223  _, ax = plt.subplots(1)
224  ax.set_title("Evolution")
225
226  if stop_iteration is None:
227  stop_iteration = len(observer)
228
229  line_best, = ax.plot(observer.get_global_best()['fitness_function'][start_iteration:stop_iteration], 'r')
230  line_current, = ax.plot(observer.get_population_best()['fitness_function'][start_iteration:stop_iteration], 'k')
231  line_mean, = ax.plot(observer.get_mean_fitness_function()[start_iteration:stop_iteration], 'c')
232
233  if start_iteration < (stop_iteration - 1):
234  ax.set_xlim([start_iteration, (stop_iteration - 1)])
235
236  ax.set_xlabel("Iteration")
237  ax.set_ylabel("Fitness function")
238  ax.legend([line_best, line_current, line_mean], ["The best pop.", "Cur. best pop.", "Average"], prop={'size': 10})
239  ax.grid()
240
241  if display is True:
242  plt.show()
243
244  return ax
245
246
247  @staticmethod
248  def show_clusters(data, observer, marker='.', markersize=None):
249  """!
250  @brief Shows allocated clusters by the genetic algorithm.
251
252  @param[in] data (list): Input data that was used for clustering process by the algorithm.
253  @param[in] observer (ga_observer): Observer that was used for collection information about clustering process.
254  @param[in] marker (char): Type of marker that should be used for object (point) representation.
255  @param[in] markersize (uint): Size of the marker that is used for object (point) representation.
256
257  @note If you have clusters instead of observer then 'cluster_visualizer' can be used for visualization purposes.
258
259  @see cluster_visualizer
260
261  """
262
263  figure = plt.figure()
265
266  clusters = ga_math.get_clusters_representation(observer.get_global_best()['chromosome'][-1])
267
268  visualizer = cluster_visualizer(1, 2)
269  visualizer.append_clusters(clusters, data, 0, marker, markersize)
270  visualizer.show(figure, display=False)
271
272  ga_visualizer.show_evolution(observer, 0, None, ax1, True)
273
274
275  @staticmethod
276  def animate_cluster_allocation(data, observer, animation_velocity=75, movie_fps=5, save_movie=None):
277  """!
278  @brief Animate clustering process of genetic clustering algorithm.
279  @details This method can be also used for rendering movie of clustering process and 'ffmpeg' is required for that purpuse.
280
281  @param[in] data (list): Input data that was used for clustering process by the algorithm.
282  @param[in] observer (ga_observer): Observer that was used for collection information about clustering process.
283  Be sure that whole information was collected by the observer.
284  @param[in] animation_velocity (uint): Interval between frames in milliseconds (for run-time animation only).
285  @param[in] movie_fps (uint): Defines frames per second (for rendering movie only).
286  @param[in] save_movie (string): If it is specified then animation will be stored to file that is specified in this parameter.
287
288  """
289
290  figure = plt.figure()
291
292  def init_frame():
293  return frame_generation(0)
294
295  def frame_generation(index_iteration):
296  figure.clf()
297
298  figure.suptitle("Clustering genetic algorithm (iteration: " + str(index_iteration) + ")", fontsize=18, fontweight='bold')
299
300  visualizer = cluster_visualizer(4, 2, ["The best pop. on step #" + str(index_iteration), "The best population"])
301
302  local_minimum_clusters = ga_math.get_clusters_representation(observer.get_population_best()['chromosome'][index_iteration])
303  visualizer.append_clusters(local_minimum_clusters, data, 0)
304
305  global_minimum_clusters = ga_math.get_clusters_representation(observer.get_global_best()['chromosome'][index_iteration])
306  visualizer.append_clusters(global_minimum_clusters, data, 1)
307
308  ax1 = plt.subplot2grid((2, 2), (1, 0), colspan=2)
309  ga_visualizer.show_evolution(observer, 0, index_iteration + 1, ax1, False)
310
311  visualizer.show(figure, shift=0, display=False)
313
314  return [figure.gca()]
315
316  iterations = len(observer)
317  cluster_animation = animation.FuncAnimation(figure, frame_generation, iterations, interval=animation_velocity, init_func=init_frame, repeat_delay=5000)
318
319  if save_movie is not None:
320  cluster_animation.save(save_movie, writer='ffmpeg', fps=movie_fps, bitrate=1500)
321  else:
322  plt.show()
323
324
326  """!
327  @brief Class represents Genetic clustering algorithm.
328  @details The searching capability of genetic algorithms is exploited in order to search for appropriate
329  cluster centres.
330
331  Example of clustering using genetic algorithm:
332  @code
333  from pyclustering.cluster.ga import genetic_algorithm, ga_observer
335  from pyclustering.samples.definitions import SIMPLE_SAMPLES
336
337
338  # Read input data for clustering
340
341  # Create instance of observer that will collect all information:
342  observer_instance = ga_observer(True, True, True)
343
344  # Create genetic algorithm for clustering
345  ga_instance = genetic_algorithm(data=sample,
346  count_clusters=4,
347  chromosome_count=100,
348  population_count=200,
349  count_mutation_gens=1)
350
351  # Start processing
352  ga_instance.process()
353
354  # Obtain results
355  clusters = ga_instance.get_clusters()
356
357  # Print cluster to console
358  print("Amount of clusters: '%d'. Clusters: '%s'" % (len(clusters), clusters))
359  @endcode
360
361  There is an example of clustering results (fitness function evolution and allocated clusters) that were
362  visualized by 'ga_visualizer':
363
364  @image html ga_clustering_sample_simple_04.png
365
366  @see ga_visualizer
367  @see ga_observer
368
369  """
370
371  def __init__(self, data, count_clusters, chromosome_count, population_count, **kwargs):
372  """!
373  @brief Initialize genetic clustering algorithm for cluster analysis.
374
375  @param[in] data (numpy.array|list): Input data for clustering that is represented by two dimensional array
376  where each row is a point, for example, [[0.0, 2.1], [0.1, 2.0], [-0.2, 2.4]].
377  @param[in] count_clusters (uint): Amount of clusters that should be allocated in the data.
378  @param[in] chromosome_count (uint): Amount of chromosomes in each population.
379  @param[in] population_count (uint): Amount of populations.
380  @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'count_mutation_gens', 'coeff_mutation_count', 'select_coeff', 'crossover_rate', 'observer').
381
382  <b>Keyword Args:</b><br>
383  - count_mutation_gens (uint): Amount of genes in chromosome that is mutated on each step.
384  - coeff_mutation_count (float): Percent of chromosomes for mutation, distributed in range (0, 1] and
385  thus amount of chromosomes is defined as follows: 'chromosome_count' * 'coeff_mutation_count'.
386  - select_coeff (float): Exponential coefficient for selection procedure that is used as follows:
387  math.exp(1 + fitness(chromosome) * select_coeff).
388  - crossover_rate (float): Crossover rate.
389  - observer (ga_observer): Observer that is used for collecting information of about clustering process on each step.
390
391  """
392
393  # Initialize random
394  np.random.seed()
395
396  # Clustering data
397  if type(data) is list:
398  self._data = np.array(data)
399  else:
400  self._data = data
401
402  # Count clusters
403  self._count_clusters = count_clusters
404
405  # Home many chromosome in population
406  self._chromosome_count = chromosome_count
407
408  # How many populations
409  self._population_count = population_count
410
411  # Count mutation genes
412  self._count_mutation_gens = kwargs.get('count_mutation_gens', 2)
413
414  # Crossover rate
415  self._crossover_rate = kwargs.get('crossover_rate', 1.0)
416
417  # Count of chromosome for mutation (range [0, 1])
418  self._coeff_mutation_count = kwargs.get('coeff_mutation_count', 0.25)
419
420  # Exponential coeff for selection
421  self._select_coeff = kwargs.get('select_coeff', 1.0)
422
423  # Result of clustering : best chromosome
424  self._result_clustering = {'best_chromosome': [],
425  'best_fitness_function': 0.0}
426
427  # Observer
428  self._observer = kwargs.get('observer', ga_observer())
429
430  def process(self):
431  """!
432  @brief Perform clustering procedure in line with rule of genetic clustering algorithm.
433
434  @see get_clusters()
435
436  """
437
438  # Initialize population
439  chromosomes = self._init_population(self._count_clusters, len(self._data), self._chromosome_count)
440
441  # Initialize the Best solution
442  best_chromosome, best_ff, first_fitness_functions \
443  = self._get_best_chromosome(chromosomes, self._data, self._count_clusters)
444
445  # Save best result into observer
446  if self._observer is not None:
447  self._observer.collect_global_best(best_chromosome, best_ff)
448  self._observer.collect_population_best(best_chromosome, best_ff)
449  self._observer.collect_mean(first_fitness_functions)
450
451  # Next population
452  for _ in range(self._population_count):
453
454  # Select
455  chromosomes = self._select(chromosomes, self._data, self._count_clusters, self._select_coeff)
456
457  # Crossover
458  self._crossover(chromosomes)
459
460  # Mutation
461  self._mutation(chromosomes, self._count_clusters, self._count_mutation_gens, self._coeff_mutation_count)
462
463  # Update the Best Solution
464  new_best_chromosome, new_best_ff, fitness_functions \
465  = self._get_best_chromosome(chromosomes, self._data, self._count_clusters)
466
467  # Get best chromosome
468  if new_best_ff < best_ff:
469  best_ff = new_best_ff
470  best_chromosome = new_best_chromosome
471
472  # Save best result into observer
473  if self._observer is not None:
474  self._observer.collect_global_best(best_chromosome, best_ff)
475  self._observer.collect_population_best(new_best_chromosome, new_best_ff)
476  self._observer.collect_mean(fitness_functions)
477
478  # Save result
479  self._result_clustering['best_chromosome'] = best_chromosome
480  self._result_clustering['best_fitness_function'] = best_ff
481
482  return best_chromosome, best_ff
483
484
485  def get_observer(self):
486  """!
487  @brief Returns genetic algorithm observer.
488
489  """
490  return self._observer
491
492
493  def get_clusters(self):
494  """!
495  @brief Returns list of allocated clusters, each cluster contains indexes of objects from the data.
496
497  @return (list) List of allocated clusters.
498
499  @see process()
500
501  """
502
503  return ga_math.get_clusters_representation(self._result_clustering['best_chromosome'], self._count_clusters)
504
505
506  @staticmethod
507  def _select(chromosomes, data, count_clusters, select_coeff):
508  """!
509  @brief Performs selection procedure where new chromosomes are calculated.
510
511  @param[in] chromosomes (numpy.array): Chromosomes
512
513  """
514
515  # Calc centers
516  centres = ga_math.get_centres(chromosomes, data, count_clusters)
517
518  # Calc fitness functions
519  fitness = genetic_algorithm._calc_fitness_function(centres, data, chromosomes)
520
521  for _idx in range(len(fitness)):
522  fitness[_idx] = math.exp(1 + fitness[_idx] * select_coeff)
523
524  # Calc probability vector
525  probabilities = ga_math.calc_probability_vector(fitness)
526
527  # Select P chromosomes with probabilities
528  new_chromosomes = np.zeros(chromosomes.shape, dtype=np.int)
529
530  # Selecting
531  for _idx in range(len(chromosomes)):
532  new_chromosomes[_idx] = chromosomes[ga_math.get_uniform(probabilities)]
533
534  return new_chromosomes
535
536
537  @staticmethod
538  def _crossover(chromosomes):
539  """!
540  @brief Crossover procedure.
541
542  """
543
544  # Get pairs to Crossover
545  pairs_to_crossover = np.array(range(len(chromosomes)))
546
547  # Set random pairs
548  np.random.shuffle(pairs_to_crossover)
549
550  # Index offset ( pairs_to_crossover split into 2 parts : [V1, V2, .. | P1, P2, ...] crossover between V<->P)
551  offset_in_pair = int(len(pairs_to_crossover) / 2)
552
553  # For each pair
554  for _idx in range(offset_in_pair):
555
556  # Generate random mask for crossover
558
559  # Crossover a pair
560  genetic_algorithm._crossover_a_pair(chromosomes[pairs_to_crossover[_idx]],
561  chromosomes[pairs_to_crossover[_idx + offset_in_pair]],
563
564
565  @staticmethod
566  def _mutation(chromosomes, count_clusters, count_gen_for_mutation, coeff_mutation_count):
567  """!
568  @brief Mutation procedure.
569
570  """
571
572  # Count gens in Chromosome
573  count_gens = len(chromosomes[0])
574
575  # Get random chromosomes for mutation
576  random_idx_chromosomes = np.array(range(len(chromosomes)))
577  np.random.shuffle(random_idx_chromosomes)
578
579  #
580  for _idx_chromosome in range(int(len(random_idx_chromosomes) * coeff_mutation_count)):
581
582  #
583  for _ in range(count_gen_for_mutation):
584
585  # Get random gen
586  gen_num = np.random.randint(count_gens)
587
588  # Set random cluster
589  chromosomes[random_idx_chromosomes[_idx_chromosome]][gen_num] = np.random.randint(count_clusters)
590
591
592  @staticmethod
594  """!
595  @brief Crossovers a pair of chromosomes.
596
597  @param[in] chromosome_1 (numpy.array): The first chromosome for crossover.
598  @param[in] chromosome_2 (numpy.array): The second chromosome for crossover.
599  @param[in] mask (numpy.array): Crossover mask that defines which genes should be swapped.
600
601  """
602
603  for _idx in range(len(chromosome_1)):
604
606  # Swap values
607  chromosome_1[_idx], chromosome_2[_idx] = chromosome_2[_idx], chromosome_1[_idx]
608
609
610  @staticmethod
612  """!
613  @brief Crossover mask to crossover a pair of chromosomes.
614
616
617  """
618
621
622  # Set a half of array to 1
624
625  # Random shuffle
627
629
630
631  @staticmethod
632  def _init_population(count_clusters, count_data, chromosome_count):
633  """!
634  @brief Returns first population as a uniform random choice.
635
636  @param[in] count_clusters (uint): Amount of clusters that should be allocated.
637  @param[in] count_data (uint): Data size that is used for clustering process.
638  @param[in] chromosome_count (uint):Amount of chromosome that is used for clustering.
639
640  """
641
642  population = np.random.randint(count_clusters, size=(chromosome_count, count_data))
643
644  return population
645
646
647  @staticmethod
648  def _get_best_chromosome(chromosomes, data, count_clusters):
649  """!
650  @brief Returns the current best chromosome.
651
652  @param[in] chromosomes (list): Chromosomes that are used for searching.
653  @param[in] data (list): Input data that is used for clustering process.
654  @param[in] count_clusters (uint): Amount of clusters that should be allocated.
655
656  @return (list, float, list) The best chromosome, its fitness function value and fitness function values for
657  all chromosomes.
658
659  """
660
661  # Calc centers
662  centres = ga_math.get_centres(chromosomes, data, count_clusters)
663
664  # Calc Fitness functions
665  fitness_functions = genetic_algorithm._calc_fitness_function(centres, data, chromosomes)
666
667  # Index of the best chromosome
668  best_chromosome_idx = fitness_functions.argmin()
669
670  # Get chromosome with the best fitness function
671  return chromosomes[best_chromosome_idx], fitness_functions[best_chromosome_idx], fitness_functions
672
673
674  @staticmethod
675  def _calc_fitness_function(centres, data, chromosomes):
676  """!
677  @brief Calculate fitness function values for chromosomes.
678
679  @param[in] centres (list): Cluster centers.
680  @param[in] data (list): Input data that is used for clustering process.
681  @param[in] chromosomes (list): Chromosomes whose fitness function's values are calculated.
682
683  @return (list) Fitness function value for each chromosome correspondingly.
684
685  """
686
687  # Get count of chromosomes and clusters
688  count_chromosome = len(chromosomes)
689
690  # Initialize fitness function values
691  fitness_function = np.zeros(count_chromosome)
692
693  # Calc fitness function for each chromosome
694  for _idx_chromosome in range(count_chromosome):
695
696  # Get centers for a selected chromosome
697  centres_data = np.zeros(data.shape)
698
699  # Fill data centres
700  for _idx in range(len(data)):
701  centres_data[_idx] = centres[_idx_chromosome][chromosomes[_idx_chromosome][_idx]]
702
703  # Get City Block distance for a chromosome
704  fitness_function[_idx_chromosome] += np.sum(abs(data - centres_data))
705
706  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:276
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:430
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:205
def __len__(self)
Returns amount of iterations that genetic algorithm was observed.
Definition: ga.py:75
def _crossover(chromosomes)
Crossover procedure.
Definition: ga.py:538
Class represents Genetic clustering algorithm.
Definition: ga.py:325
def _get_best_chromosome(chromosomes, data, count_clusters)
Returns the current best chromosome.
Definition: ga.py:648
def _init_population(count_clusters, count_data, chromosome_count)
Returns first population as a uniform random choice.
Definition: ga.py:632
def _select(chromosomes, data, count_clusters, select_coeff)
Performs selection procedure where new chromosomes are calculated.
Definition: ga.py:507
def __init__(self, data, count_clusters, chromosome_count, population_count, kwargs)
Initialize genetic clustering algorithm for cluster analysis.
Definition: ga.py:371
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:485
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:248
def get_clusters(self)
Returns list of allocated clusters, each cluster contains indexes of objects from the data...
Definition: ga.py:493
def _mutation(chromosomes, count_clusters, count_gen_for_mutation, coeff_mutation_count)
Mutation procedure.
Definition: ga.py:566