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