pyclustering  0.10.1
pyclustring is a Python, C++ data mining library.
bang.py
1 """!
2 
3 @brief Cluster analysis algorithm: BANG.
4 @details Implementation based on paper @cite inproceedings::bang::1.
5 
6 @authors Andrei Novikov (pyclustering@yandex.ru)
7 @date 2014-2020
8 @copyright BSD-3-Clause
9 
10 """
11 
12 import itertools
13 import warnings
14 
15 import matplotlib
16 import matplotlib.gridspec as gridspec
17 import matplotlib.pyplot as plt
18 import matplotlib.patches as patches
19 import matplotlib.animation as animation
20 
21 from pyclustering.cluster import cluster_visualizer
22 from pyclustering.cluster.encoder import type_encoding
23 
24 from pyclustering.utils import data_corners
25 from pyclustering.utils.color import color as color_list
26 
27 
28 
30  """!
31  @brief Visualizer of BANG algorithm's results.
32  @details BANG visualizer provides visualization services that are specific for BANG algorithm.
33 
34  """
35 
36  __maximum_density_alpha = 0.6
37 
38 
39  @staticmethod
40  def show_blocks(directory):
41  """!
42  @brief Show BANG-blocks (leafs only) in data space.
43  @details BANG-blocks represents grid that was used for clustering process.
44 
45  @param[in] directory (bang_directory): Directory that was created by BANG algorithm during clustering process.
46 
47  """
48 
49  dimension = len(directory.get_data()[0])
50 
51  amount_canvases = 1
52  if dimension > 1:
53  amount_canvases = int(dimension * (dimension - 1) / 2)
54 
55  figure = plt.figure()
56  grid_spec = gridspec.GridSpec(1, amount_canvases)
57 
58  pairs = list(itertools.combinations(range(dimension), 2))
59  if len(pairs) == 0: pairs = [(0, 0)]
60 
61  for index in range(amount_canvases):
62  ax = figure.add_subplot(grid_spec[index])
63  bang_visualizer.__draw_blocks(ax, directory.get_leafs(), pairs[index])
64  bang_visualizer.__draw_two_dimension_data(ax, directory.get_data(), pairs[index])
65 
66  plt.show()
67 
68 
69  @staticmethod
70  def show_dendrogram(dendrogram):
71  """!
72  @brief Display dendrogram of BANG-blocks.
73 
74  @param[in] dendrogram (list): List representation of dendrogram of BANG-blocks.
75 
76  @see bang.get_dendrogram()
77 
78  """
79  plt.figure()
80  axis = plt.subplot(1, 1, 1)
81 
82  current_position = 0
83  for index_cluster in range(len(dendrogram)):
84  densities = [ block.get_density() for block in dendrogram[index_cluster] ]
85  xrange = range(current_position, current_position + len(densities))
86 
87  axis.bar(xrange, densities, 1.0, linewidth=0.0, color=color_list.get_color(index_cluster))
88 
89  current_position += len(densities)
90 
91  axis.set_ylabel("density")
92  axis.set_xlabel("block")
93  axis.xaxis.set_ticklabels([])
94 
95  plt.xlim([-0.5, current_position - 0.5])
96  plt.show()
97 
98 
99  @staticmethod
100  def show_clusters(data, clusters, noise=None):
101  """!
102  @brief Display BANG clustering results.
103 
104  @param[in] data (list): Dataset that was used for clustering.
105  @param[in] clusters (array_like): Clusters that were allocated by the algorithm.
106  @param[in] noise (array_like): Noise that were allocated by the algorithm.
107 
108  """
109  visualizer = cluster_visualizer()
110  visualizer.append_clusters(clusters, data)
111  visualizer.append_cluster(noise or [], data, marker='x')
112  visualizer.show()
113 
114 
115  @staticmethod
116  def __draw_two_dimension_data(ax, data, pair):
117  """!
118  @brief Display data in two-dimensional canvas.
119 
120  @param[in] ax (Axis): Canvas where data should be displayed.
121  @param[in] data (list): Data points that should be displayed.
122  @param[in] pair (tuple): Pair of dimension indexes.
123 
124  """
125  ax.set_xlabel("x%d" % pair[0])
126  ax.set_ylabel("x%d" % pair[1])
127 
128  for point in data:
129  if len(data[0]) > 1:
130  ax.plot(point[pair[0]], point[pair[1]], color='red', marker='.')
131  else:
132  ax.plot(point[pair[0]], 0, color='red', marker='.')
133  ax.yaxis.set_ticklabels([])
134 
135 
136  @staticmethod
137  def __draw_blocks(ax, blocks, pair):
138  """!
139  @brief Display BANG-blocks on specified figure.
140 
141  @param[in] ax (Axis): Axis where bang-blocks should be displayed.
142  @param[in] blocks (list): List of blocks that should be displyed.
143  @param[in] pair (tuple): Pair of coordinate index that should be displayed.
144 
145  """
146  ax.grid(False)
147 
148  density_scale = blocks[-1].get_density()
149  for block in blocks:
150  bang_visualizer.__draw_block(ax, pair, block, density_scale)
151 
152 
153  @staticmethod
154  def __draw_block(ax, pair, block, density_scale):
155  """!
156  @brief Display BANG-block on the specified ax.
157 
158  @param[in] ax (Axis): Axis where block should be displayed.
159  @param[in] pair (tuple): Pair of coordinate index that should be displayed.
160  @param[in] block (bang_block): BANG-block that should be displayed.
161  @param[in] density_scale (double): Max density to display density of the block by appropriate tone.
162 
163  """
164  max_corner, min_corner = bang_visualizer.__get_rectangle_description(block, pair)
165 
166  belong_cluster = block.get_cluster() is not None
167 
168  if density_scale != 0.0:
169  density_scale = bang_visualizer.__maximum_density_alpha * block.get_density() / density_scale
170 
171  face_color = matplotlib.colors.to_rgba('blue', alpha=density_scale)
172  edge_color = matplotlib.colors.to_rgba('black', alpha=1.0)
173 
174  rect = patches.Rectangle(min_corner, max_corner[0] - min_corner[0], max_corner[1] - min_corner[1],
175  fill=belong_cluster,
176  facecolor=face_color,
177  edgecolor=edge_color,
178  linewidth=0.5)
179  ax.add_patch(rect)
180 
181 
182  @staticmethod
183  def __get_rectangle_description(block, pair):
184  """!
185  @brief Create rectangle description for block in specific dimension.
186 
187  @param[in] pair (tuple): Pair of coordinate index that should be displayed.
188  @param[in] block (bang_block): BANG-block that should be displayed
189 
190  @return (tuple) Pair of corners that describes rectangle.
191 
192  """
193  max_corner, min_corner = block.get_spatial_block().get_corners()
194 
195  max_corner = [max_corner[pair[0]], max_corner[pair[1]]]
196  min_corner = [min_corner[pair[0]], min_corner[pair[1]]]
197 
198  if pair == (0, 0):
199  max_corner[1], min_corner[1] = 1.0, -1.0
200 
201  return max_corner, min_corner
202 
203 
205  """!
206  @brief Provides service for creating 2-D animation using BANG clustering results.
207  @details The animator does not support visualization of clustering process where non 2-dimensional was used.
208 
209  Code example of animation of BANG clustering process:
210  @code
211  from pyclustering.cluster.bang import bang, bang_animator
212  from pyclustering.utils import read_sample
213  from pyclustering.samples.definitions import FCPS_SAMPLES
214 
215  # Read data two dimensional data.
216  data = read_sample(FCPS_SAMPLES.SAMPLE_LSUN)
217 
218  # Create instance of BANG algorithm.
219  bang_instance = bang(data, 9)
220  bang_instance.process()
221 
222  # Obtain clustering results.
223  clusters = bang_instance.get_clusters()
224  noise = bang_instance.get_noise()
225  directory = bang_instance.get_directory()
226 
227  # Create BANG animation using class 'bang_animator':
228  animator = bang_animator(directory, clusters)
229  animator.animate()
230  @endcode
231 
232 """
233  def __init__(self, directory, clusters):
234  """!
235  @brief Creates BANG animator instance.
236 
237  @param[in] directory (bang_directory): BANG directory that was formed during BANG clustering process.
238  @param[in] clusters (list): Allocated clusters during BANG clustering process.
239 
240  """
241  self.__directory = directory
242  self.__clusters = clusters
243  self.__noise = []
244 
245  self.__current_block = 0
246  self.__current_level = 0
247  self.__level_blocks = directory.get_level(0)
248 
249  self.__figure = plt.figure()
250  self.__ax = self.__figure.add_subplot(1, 1, 1)
251  self.__special_frame = 0
252 
253  self.__validate_arguments()
254 
255 
256  def __validate_arguments(self):
257  """!
258  @brief Check correctness of input arguments and throw exception if incorrect is found.
259 
260  """
261  if len(self.__directory.get_data()[0]) != 2:
262  raise ValueError("Impossible to animate BANG clustering process for non 2D data.")
263 
264 
265  def __increment_block(self):
266  """!
267  @brief Increment BANG block safely by updating block index, level and level block.
268 
269  """
270  self.__current_block += 1
271  if self.__current_block >= len(self.__level_blocks):
272  self.__current_block = 0
273  self.__current_level += 1
274 
275  if self.__current_level < self.__directory.get_height():
276  self.__level_blocks = self.__directory.get_level(self.__current_level)
277 
278 
279  def __draw_block(self, block, block_alpha=0.0):
280  """!
281  @brief Display single BANG block on axis.
282 
283  @param[in] block (bang_block): BANG block that should be displayed.
284  @param[in] block_alpha (double): Transparency level - value of alpha.
285 
286  """
287  max_corner, min_corner = block.get_spatial_block().get_corners()
288 
289  face_color = matplotlib.colors.to_rgba('blue', alpha=block_alpha)
290  edge_color = matplotlib.colors.to_rgba('black', alpha=1.0)
291 
292  rect = patches.Rectangle(min_corner, max_corner[0] - min_corner[0], max_corner[1] - min_corner[1],
293  fill=True,
294  facecolor=face_color,
295  edgecolor=edge_color,
296  linewidth=0.5)
297  self.__ax.add_patch(rect)
298 
299 
300  def __draw_leaf_density(self):
301  """!
302  @brief Display densities by filling blocks by appropriate colors.
303 
304  """
305  leafs = self.__directory.get_leafs()
306  density_scale = leafs[-1].get_density()
307 
308  if density_scale == 0.0: density_scale = 1.0
309 
310  for block in leafs:
311  alpha = 0.8 * block.get_density() / density_scale
312  self.__draw_block(block, alpha)
313 
314 
315  def __draw_clusters(self):
316  """!
317  @brief Display clusters and outliers using different colors.
318 
319  """
320  data = self.__directory.get_data()
321  for index_cluster in range(len(self.__clusters)):
322  color = color_list.get_color(index_cluster)
323  self.__draw_cluster(data, self.__clusters[index_cluster], color, '.')
324 
325  self.__draw_cluster(self.__directory.get_data(), self.__noise, 'gray', 'x')
326 
327 
328  def __draw_cluster(self, data, cluster, color, marker):
329  """!
330  @brief Draw 2-D single cluster on axis using specified color and marker.
331 
332  """
333  for item in cluster:
334  self.__ax.plot(data[item][0], data[item][1], color=color, marker=marker)
335 
336 
337  def animate(self, animation_velocity=75, movie_fps=25, movie_filename=None):
338  """!
339  @brief Animates clustering process that is performed by BANG algorithm.
340 
341  @param[in] animation_velocity (uint): Interval between frames in milliseconds (for run-time animation only).
342  @param[in] movie_fps (uint): Defines frames per second (for rendering movie only).
343  @param[in] movie_filename (string): If it is specified then animation will be stored to file that is specified in this parameter.
344 
345  """
346  def init_frame():
347  self.__figure.clf()
348  self.__ax = self.__figure.add_subplot(1, 1, 1)
349  self.__figure.suptitle("BANG algorithm", fontsize=18, fontweight='bold')
350 
351  for point in self.__directory.get_data():
352  self.__ax.plot(point[0], point[1], color='red', marker='.')
353 
354  return frame_generation(0)
355 
356 
357  def frame_generation(index_iteration):
358  if self.__current_level < self.__directory.get_height():
359  block = self.__level_blocks[self.__current_block]
360  self.__draw_block(block)
361  self.__increment_block()
362 
363  else:
364  if self.__special_frame == 0:
365  self.__draw_leaf_density()
366 
367  elif self.__special_frame == 15:
368  self.__draw_clusters()
369 
370  elif self.__special_frame == 30:
371  self.__figure.clf()
372  self.__ax = self.__figure.add_subplot(1, 1, 1)
373  self.__figure.suptitle("BANG algorithm", fontsize=18, fontweight='bold')
374 
375  self.__draw_clusters()
376 
377  self.__special_frame += 1
378 
379 
380 
381  iterations = len(self.__directory) + 60
382  # print("Total number of iterations: %d" % iterations)
383  cluster_animation = animation.FuncAnimation(self.__figure, frame_generation, iterations,
384  interval=animation_velocity,
385  init_func=init_frame,
386  repeat_delay=5000)
387 
388  if movie_filename is not None:
389  cluster_animation.save(movie_filename, writer = 'ffmpeg', fps = movie_fps, bitrate = 3500)
390  else:
391  plt.show()
392 
393 
394 
396  """!
397  @brief BANG directory stores BANG-blocks that represents grid in data space.
398  @details The directory build BANG-blocks in binary tree manner. Leafs of the tree stored separately to provide
399  a direct access to the leafs that should be analysed. Leafs cache data-points.
400 
401  """
402  def __init__(self, data, levels, **kwargs):
403  """!
404  @brief Create BANG directory - basically tree structure with direct access to leafs.
405 
406  @param[in] data (list): Input data that is clustered.
407  @param[in] levels (uint): Height of the tree of blocks.
408  @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'observe').
409 
410  <b>Keyword Args:</b><br>
411  - observe (bool): If 'True' then blocks on each level are stored.
412  - density_threshold (double): The lowest level of density when contained data in bang-block is
413  considered as a noise and there is no need to split it till the last level. Be aware that this
414  parameter is used with 'amount_threshold' parameter.
415  - amount_threshold (uint): Amount of points in the block when it contained data in bang-block is
416  considered as a noise and there is no need to split it till the last level.
417 
418  """
419  self.__data = data
420  self.__levels = levels
421  self.__density_threshold = kwargs.get('density_threshold', 0.0)
422  self.__amount_density = kwargs.get('amount_threshold', 0)
423  self.__leafs = []
424  self.__root = None
425  self.__level_blocks = []
426  self.__size = 0
427  self.__observe = kwargs.get('observe', True)
428 
429  self.__create_directory()
430 
431 
432  def __len__(self):
433  """!
434  @brief Returns amount of blocks that is stored in the directory
435 
436  @return (uint) Amount of blocks in the BANG directory.
437 
438  """
439  return self.__size
440 
441 
442  def get_data(self):
443  """!
444  @brief Return data that is stored in the directory.
445 
446  @return (list) List of points that represents stored data.
447 
448  """
449  return self.__data
450 
451 
452  def get_leafs(self):
453  """!
454  @brief Return leafs - the smallest blocks.
455  @details Some leafs can be bigger than others because splitting is not performed for blocks whose density is
456  less than threshold.
457 
458  @return (list) List of blocks that are leafs of BANG directory.
459 
460  """
461  return self.__leafs
462 
463 
464  def get_level(self, level):
465  """!
466  @brief Returns BANG blocks on the specific level.
467 
468  @param[in] level (uint): Level of tree where BANG blocks are located.
469 
470  @return (list) List of BANG blocks on the specific level.
471 
472  """
473  return self.__level_blocks[level]
474 
475 
476  def get_height(self):
477  """!
478  @brief Returns height of BANG tree where blocks are stored.
479 
480  @return (uint) Height of BANG tree.
481 
482  """
483  return len(self.__level_blocks)
484 
485 
486  def __create_directory(self):
487  """!
488  @brief Create BANG directory as a tree with separate storage for leafs.
489 
490  """
491 
492  min_corner, max_corner = data_corners(self.__data)
493  data_block = spatial_block(max_corner, min_corner)
494 
495  cache_require = (self.__levels == 1)
496  self.__root = bang_block(self.__data, 0, 0, data_block, cache_require)
497 
498  if cache_require:
499  self.__leafs.append(self.__root)
500  self.__store_level_blocks([self.__root])
501  else:
503 
504 
505  def __store_level_blocks(self, level_blocks):
506  """!
507  @brief Store level blocks if observing is enabled.
508 
509  @param[in] level_blocks (list): Created blocks on a new level.
510 
511  """
512  self.__size += len(level_blocks)
513  if self.__observe is True:
514  self.__level_blocks.append(level_blocks)
515 
516 
517 
518  def __build_directory_levels(self):
519  """!
520  @brief Build levels of direction if amount of level is greater than one.
521 
522  """
523 
524  previous_level_blocks = [ self.__root ]
525 
526  for level in range(1, self.__levels):
527  previous_level_blocks = self.__build_level(previous_level_blocks, level)
528  self.__store_level_blocks(previous_level_blocks)
529 
530  self.__leafs = sorted(self.__leafs, key=lambda block: block.get_density())
531 
532 
533  def __build_level(self, previous_level_blocks, level):
534  """!
535  @brief Build new level of directory.
536 
537  @param[in] previous_level_blocks (list): BANG-blocks on the previous level.
538  @param[in] level (uint): Level number that should be built.
539 
540  @return (list) New block on the specified level.
541 
542  """
543  current_level_blocks = []
544 
545  split_dimension = level % len(self.__data[0])
546  cache_require = (level == self.__levels - 1)
547 
548  for block in previous_level_blocks:
549  self.__split_block(block, split_dimension, cache_require, current_level_blocks)
550 
551  if cache_require:
552  self.__leafs += current_level_blocks
553 
554  return current_level_blocks
555 
556 
557  def __split_block(self, block, split_dimension, cache_require, current_level_blocks):
558  """!
559  @brief Split specific block in specified dimension.
560  @details Split is not performed for block whose density is lower than threshold value, such blocks are putted to
561  leafs.
562 
563  @param[in] block (bang_block): BANG-block that should be split.
564  @param[in] split_dimension (uint): Dimension at which splitting should be performed.
565  @param[in] cache_require (bool): Defines when points in cache should be stored during density calculation.
566  @param[in|out] current_level_blocks (list): Block storage at the current level where new blocks should be added.
567 
568  """
569  if block.get_density() <= self.__density_threshold or len(block) <= self.__amount_density:
570  self.__leafs.append(block)
571 
572  else:
573  left, right = block.split(split_dimension, cache_require)
574  current_level_blocks.append(left)
575  current_level_blocks.append(right)
576 
577 
579  """!
580  @brief Geometrical description of BANG block in data space.
581  @details Provides services related to spatial functionality and used by bang_block
582 
583  @see bang_block
584 
585  """
586 
587  def __init__(self, max_corner, min_corner):
588  """!
589  @brief Creates spatial block in data space.
590 
591  @param[in] max_corner (array_like): Maximum corner coordinates of the block.
592  @param[in] min_corner (array_like): Minimal corner coordinates of the block.
593 
594  """
595  self.__max_corner = max_corner
596  self.__min_corner = min_corner
597  self.__volume = self.__calculate_volume()
598 
599 
600  def __str__(self):
601  """!
602  @brief Returns string block description.
603 
604  @return String representation of the block.
605 
606  """
607  return "(max: %s; min: %s)" % (self.__max_corner, self.__min_corner)
608 
609 
610  def __contains__(self, point):
611  """!
612  @brief Point is considered as contained if it lies in block (belong to it).
613 
614  @return (bool) True if point is in block, otherwise False.
615 
616  """
617  for i in range(len(point)):
618  if point[i] < self.__min_corner[i] or point[i] > self.__max_corner[i]:
619  return False
620 
621  return True
622 
623 
624  def get_corners(self):
625  """!
626  @brief Return spatial description of current block.
627 
628  @return (tuple) Pair of maximum and minimum corners (max_corner, min_corner).
629 
630  """
631  return self.__max_corner, self.__min_corner
632 
633 
634  def get_volume(self):
635  """!
636  @brief Returns volume of current block.
637  @details Volume block has uncommon mining here: for 1D is length of a line, for 2D is square of rectangle,
638  for 3D is volume of 3D figure, and for ND is volume of ND figure.
639 
640  @return (double) Volume of current block.
641 
642  """
643  return self.__volume
644 
645 
646  def split(self, dimension):
647  """!
648  @brief Split current block into two spatial blocks in specified dimension.
649 
650  @param[in] dimension (uint): Dimension where current block should be split.
651 
652  @return (tuple) Pair of new split blocks from current block.
653 
654  """
655  first_max_corner = self.__max_corner[:]
656  second_min_corner = self.__min_corner[:]
657 
658  split_border = (self.__max_corner[dimension] + self.__min_corner[dimension]) / 2.0
659 
660  first_max_corner[dimension] = split_border
661  second_min_corner[dimension] = split_border
662 
663  return spatial_block(first_max_corner, self.__min_corner), spatial_block(self.__max_corner, second_min_corner)
664 
665 
666  def is_neighbor(self, block):
667  """!
668  @brief Performs calculation to identify whether specified block is neighbor of current block.
669  @details It also considers diagonal blocks as neighbors.
670 
671  @param[in] block (spatial_block): Another block that is check whether it is neighbor.
672 
673  @return (bool) True is blocks are neighbors, False otherwise.
674 
675  """
676  if block is not self:
677  block_max_corner, _ = block.get_corners()
678  dimension = len(block_max_corner)
679  neighborhood_score = self.__calculate_neighborhood(block_max_corner)
680 
681  if neighborhood_score == dimension:
682  return True
683 
684  return False
685 
686 
687  def __calculate_neighborhood(self, block_max_corner):
688  """!
689  @brief Calculates neighborhood score that defined whether blocks are neighbors.
690 
691  @param[in] block_max_corner (list): Maximum coordinates of other block.
692 
693  @return (uint) Neighborhood score.
694 
695  """
696  dimension = len(block_max_corner)
697 
698  length_edges = [self.__max_corner[i] - self.__min_corner[i] for i in range(dimension)]
699 
700  neighborhood_score = 0
701  for i in range(dimension):
702  diff = abs(block_max_corner[i] - self.__max_corner[i])
703 
704  if diff <= length_edges[i] + length_edges[i] * 0.0001:
705  neighborhood_score += 1
706 
707  return neighborhood_score
708 
709 
710  def __calculate_volume(self):
711  """!
712  @brief Calculates volume of current spatial block.
713  @details If empty dimension is detected (where all points has the same value) then such dimension is ignored
714  during calculation of volume.
715 
716  @return (double) Volume of current spatial block.
717 
718  """
719 
720  volume = 0.0
721  for i in range(0, len(self.__max_corner)):
722  side_length = self.__max_corner[i] - self.__min_corner[i]
723 
724  if side_length != 0.0:
725  if volume == 0.0: volume = side_length
726  else: volume *= side_length
727 
728  return volume
729 
730 
732  """!
733  @brief BANG-block that represent spatial region in data space.
734 
735  """
736  def __init__(self, data, region, level, space_block, cache_points=False):
737  """!
738  @brief Create BANG-block.
739 
740  @param[in] data (list): List of points that are processed.
741  @param[in] region (uint): Region number - unique value on a level.
742  @param[in] level (uint): Level number where block is created.
743  @param[in] space_block (spatial_block): Spatial block description in data space.
744  @param[in] cache_points (bool): if True then points are stored in memory (used for leaf blocks).
745 
746  """
747  self.__data = data
748  self.__region_number = region
749  self.__level = level
750  self.__spatial_block = space_block
751  self.__cache_points = cache_points
752 
753  self.__cluster = None
754  self.__points = None
757 
758 
759  def __str__(self):
760  """!
761  @brief Returns string representation of BANG-block using region number and level where block is located.
762 
763  """
764  return "(" + str(self.__region_number) + ", " + str(self.__level) + ")"
765 
766 
767  def __len__(self):
768  """!
769  @brief Returns block size defined by amount of points that are contained by this block.
770 
771  """
772  return self.__amount_points
773 
774 
775  def get_region(self):
776  """!
777  @brief Returns region number of BANG-block.
778  @details Region number is unique on among region numbers on a directory level. Pair of region number and level
779  is unique for all directory.
780 
781  @return (uint) Region number.
782 
783  """
784  return self.__region_number
785 
786 
787  def get_density(self):
788  """!
789  @brief Returns density of the BANG-block.
790 
791  @return (double) BANG-block density.
792 
793  """
794  return self.__density
795 
796 
797  def get_cluster(self):
798  """!
799  @brief Return index of cluster to which the BANG-block belongs to.
800  @details Index of cluster may have None value if the block was not assigned to any cluster.
801 
802  @return (uint) Index of cluster or None if the block does not belong to any cluster.
803 
804  """
805  return self.__cluster
806 
807 
808  def get_spatial_block(self):
809  """!
810  @brief Return spatial block - BANG-block description in data space.
811 
812  @return (spatial_block) Spatial block of the BANG-block.
813 
814  """
815  return self.__spatial_block
816 
817 
818  def get_points(self):
819  """!
820  @brief Return points that covers by the BANG-block.
821 
822  @return (list) List of point indexes that are covered by the block.
823 
824  """
825  if self.__points is None:
826  self.__cache_covered_data()
827 
828  return self.__points
829 
830 
831  def set_cluster(self, index):
832  """!
833  @brief Assign cluster to the BANG-block by index.
834 
835  @param[in] index (uint): Index cluster that is assigned to BANG-block.
836 
837  """
838  self.__cluster = index
839 
840 
841  def is_neighbor(self, block):
842  """!
843  @brief Performs calculation to check whether specified block is neighbor to the current.
844 
845  @param[in] block (bang_block): Other BANG-block that should be checked for neighborhood.
846 
847  @return (bool) True if blocks are neighbors, False if blocks are not neighbors.
848 
849  """
850  return self.get_spatial_block().is_neighbor(block.get_spatial_block())
851 
852 
853  def split(self, split_dimension, cache_points):
854  """!
855  @brief Split BANG-block into two new blocks in specified dimension.
856 
857  @param[in] split_dimension (uint): Dimension where block should be split.
858  @param[in] cache_points (bool): If True then covered points are cached. Used for leaf blocks.
859 
860  @return (tuple) Pair of BANG-block that were formed from the current.
861 
862  """
863  left_region_number = self.__region_number
864  right_region_number = self.__region_number + 2 ** self.__level
865 
866  first_spatial_block, second_spatial_block = self.__spatial_block.split(split_dimension)
867 
868  left = bang_block(self.__data, left_region_number, self.__level + 1, first_spatial_block, cache_points)
869  right = bang_block(self.__data, right_region_number, self.__level + 1, second_spatial_block, cache_points)
870 
871  return left, right
872 
873 
874  def __calculate_density(self, amount_points):
875  """!
876  @brief Calculates BANG-block density.
877 
878  @param[in] amount_points (uint): Amount of points in block.
879 
880  @return (double) BANG-block density.
881 
882  """
883  volume = self.__spatial_block.get_volume()
884  if volume != 0.0:
885  return amount_points / volume
886 
887  return 0.0
888 
889 
890  def __get_amount_points(self):
891  """!
892  @brief Count covered points by the BANG-block and if cache is enable then covered points are stored.
893 
894  @return (uint) Amount of covered points.
895 
896  """
897  amount = 0
898  for index in range(len(self.__data)):
899  if self.__data[index] in self.__spatial_block:
900  self.__cache_point(index)
901  amount += 1
902 
903  return amount
904 
905 
906  def __cache_covered_data(self):
907  """!
908  @brief Cache covered data.
909 
910  """
911  self.__cache_points = True
912  self.__points = []
913 
914  for index_point in range(len(self.__data)):
915  if self.__data[index_point] in self.__spatial_block:
916  self.__cache_point(index_point)
917 
918 
919  def __cache_point(self, index):
920  """!
921  @brief Store index points.
922 
923  @param[in] index (uint): Index point that should be stored.
924 
925  """
926  if self.__cache_points:
927  if self.__points is None:
928  self.__points = []
929 
930  self.__points.append(index)
931 
932 
933 
934 class bang:
935  """!
936  @brief Class implements BANG grid based clustering algorithm.
937  @details BANG clustering algorithms uses a multidimensional grid structure to organize the value space surrounding
938  the pattern values. The patterns are grouped into blocks and clustered with respect to the blocks by
939  a topological neighbor search algorithm @cite inproceedings::bang::1.
940 
941  Code example of BANG usage:
942  @code
943  from pyclustering.cluster.bang import bang, bang_visualizer
944  from pyclustering.utils import read_sample
945  from pyclustering.samples.definitions import FCPS_SAMPLES
946 
947  # Read data three dimensional data.
948  data = read_sample(FCPS_SAMPLES.SAMPLE_CHAINLINK)
949 
950  # Prepare algorithm's parameters.
951  levels = 11
952 
953  # Create instance of BANG algorithm.
954  bang_instance = bang(data, levels)
955  bang_instance.process()
956 
957  # Obtain clustering results.
958  clusters = bang_instance.get_clusters()
959  noise = bang_instance.get_noise()
960  directory = bang_instance.get_directory()
961  dendrogram = bang_instance.get_dendrogram()
962 
963  # Visualize BANG clustering results.
964  bang_visualizer.show_blocks(directory)
965  bang_visualizer.show_dendrogram(dendrogram)
966  bang_visualizer.show_clusters(data, clusters, noise)
967  @endcode
968 
969  There is visualization of BANG-clustering of three-dimensional data 'chainlink'. BANG-blocks that were formed during
970  processing are shown on following figure. The darkest color means highest density, blocks that does not cover points
971  are transparent:
972  @image html bang_blocks_chainlink.png "Fig. 1. BANG-blocks that cover input data."
973 
974  Here is obtained dendrogram that can be used for further analysis to improve clustering results:
975  @image html bang_dendrogram_chainlink.png "Fig. 2. BANG dendrogram where the X-axis contains BANG-blocks, the Y-axis contains density."
976 
977  BANG clustering result of 'chainlink' data:
978  @image html bang_clustering_chainlink.png "Fig. 3. BANG clustering result. Data: 'chainlink'."
979 
980  """
981 
982  def __init__(self, data, levels, ccore=False, **kwargs):
983  """!
984  @brief Create BANG clustering algorithm.
985 
986  @param[in] data (list): Input data (list of points) that should be clustered.
987  @param[in] levels (uint): Amount of levels in tree that is used for splitting (how many times block should be
988  split). For example, if amount of levels is two then surface will be divided into two blocks and
989  each obtained block will be divided into blocks also.
990  @param[in] ccore (bool): Reserved positional argument - not used yet.
991  @param[in] **kwargs: Arbitrary keyword arguments (available arguments: 'observe').
992 
993  <b>Keyword Args:</b><br>
994  - density_threshold (double): If block density is smaller than this value then contained data by this
995  block is considered as a noise and its points as outliers. Block density is defined by amount of
996  points in block divided by block volume: <i>amount_block_points</i>/<i>block_volume</i>. By default
997  it is 0.0 - means than only empty blocks are considered as noise. Be aware that this parameter is used
998  with parameter 'amount_threshold' - the maximum threshold is considered during processing.
999  - amount_threshold (uint): Amount of points in the block when it contained data in bang-block is
1000  considered as a noise and there is no need to split it till the last level. Be aware that this parameter
1001  is used with parameter 'density_threshold' - the maximum threshold is considered during processing.
1002 
1003  """
1004  self.__data = data
1005  self.__levels = levels
1006  self.__directory = None
1007  self.__clusters = []
1008  self.__noise = []
1009  self.__cluster_blocks = []
1010  self.__dendrogram = []
1011  self.__density_threshold = kwargs.get('density_threshold', 0.0)
1012  self.__amount_threshold = kwargs.get('amount_threshold', 0)
1013  self.__ccore = ccore
1014 
1015  self.__validate_arguments()
1016 
1017 
1018  def process(self):
1019  """!
1020  @brief Performs clustering process in line with rules of BANG clustering algorithm.
1021 
1022  @return (bang) Returns itself (BANG instance).
1023 
1024  @see get_clusters()
1025  @see get_noise()
1026  @see get_directory()
1027  @see get_dendrogram()
1028 
1029  """
1030  self.__directory = bang_directory(self.__data, self.__levels,
1031  density_threshold=self.__density_threshold,
1032  amount_threshold=self.__amount_threshold)
1033  self.__allocate_clusters()
1034 
1035  return self
1036 
1037 
1038  def get_clusters(self):
1039  """!
1040  @brief Returns allocated clusters.
1041 
1042  @remark Allocated clusters are returned only after data processing (method process()). Otherwise empty list is returned.
1043 
1044  @return (list) List of allocated clusters, each cluster contains indexes of objects in list of data.
1045 
1046  @see process()
1047  @see get_noise()
1048 
1049  """
1050  return self.__clusters
1051 
1052 
1053  def get_noise(self):
1054  """!
1055  @brief Returns allocated noise.
1056 
1057  @remark Allocated noise is returned only after data processing (method process()). Otherwise empty list is returned.
1058 
1059  @return (list) List of indexes that are marked as a noise.
1060 
1061  @see process()
1062  @see get_clusters()
1063 
1064  """
1065  return self.__noise
1066 
1067 
1068  def get_directory(self):
1069  """!
1070  @brief Returns grid directory that describes grid of the processed data.
1071 
1072  @remark Grid directory is returned only after data processing (method process()). Otherwise None value is returned.
1073 
1074  @return (bang_directory) BANG directory that describes grid of process data.
1075 
1076  @see process()
1077 
1078  """
1079  return self.__directory
1080 
1081 
1082  def get_dendrogram(self):
1083  """!
1084  @brief Returns dendrogram of clusters.
1085  @details Dendrogram is created in following way: the density indices of all regions are calculated and sorted
1086  in decreasing order for each cluster during clustering process.
1087 
1088  @remark Dendrogram is returned only after data processing (method process()). Otherwise empty list is returned.
1089 
1090  """
1091  return self.__dendrogram
1092 
1093 
1095  """!
1096  @brief Returns clustering result representation type that indicate how clusters are encoded.
1097 
1098  @return (type_encoding) Clustering result representation.
1099 
1100  @see get_clusters()
1101 
1102  """
1103 
1104  return type_encoding.CLUSTER_INDEX_LIST_SEPARATION
1105 
1106 
1107  def __validate_arguments(self):
1108  """!
1109  @brief Check input arguments of BANG algorithm and if one of them is not correct then appropriate exception
1110  is thrown.
1111 
1112  """
1113  if len(self.__data) == 0:
1114  raise ValueError("Input data is empty (size: '%d')." % len(self.__data))
1115 
1116  if self.__levels < 1:
1117  raise ValueError("Height of the tree should be greater than 0 (current value: '%d')." % self.__levels)
1118 
1119  if self.__density_threshold < 0.0:
1120  raise ValueError("Density threshold should be greater or equal to 0 (current value: '%d')." %
1121  self.__density_threshold)
1122 
1123  if self.__amount_threshold < 0:
1124  raise ValueError("Amount of points threshold should be greater than 0 (current value: '%d')" %
1125  self.__amount_threshold)
1126 
1127 
1128  def __allocate_clusters(self):
1129  """!
1130  @brief Performs cluster allocation using leafs of tree in BANG directory (the smallest cells).
1131 
1132  """
1133  leaf_blocks = self.__directory.get_leafs()
1134  unhandled_block_indexes = set([i for i in range(len(leaf_blocks)) if leaf_blocks[i].get_density() > self.__density_threshold])
1135 
1136  current_block = self.__find_block_center(leaf_blocks, unhandled_block_indexes)
1137  cluster_index = 0
1138 
1139  while current_block is not None:
1140  if current_block.get_density() <= self.__density_threshold or len(current_block) <= self.__amount_threshold:
1141  break
1142 
1143  self.__expand_cluster_block(current_block, cluster_index, leaf_blocks, unhandled_block_indexes)
1144 
1145  current_block = self.__find_block_center(leaf_blocks, unhandled_block_indexes)
1146  cluster_index += 1
1147 
1148  self.__store_clustering_results(cluster_index, leaf_blocks)
1149 
1150 
1151  def __expand_cluster_block(self, block, cluster_index, leaf_blocks, unhandled_block_indexes):
1152  """!
1153  @brief Expand cluster from specific block that is considered as a central block.
1154 
1155  @param[in] block (bang_block): Block that is considered as a central block for cluster.
1156  @param[in] cluster_index (uint): Index of cluster that is assigned to blocks that forms new cluster.
1157  @param[in] leaf_blocks (list): Leaf BANG-blocks that are considered during cluster formation.
1158  @param[in] unhandled_block_indexes (set): Set of candidates (BANG block indexes) to become a cluster member. The
1159  parameter helps to reduce traversing among BANG-block providing only restricted set of block that
1160  should be considered.
1161 
1162  """
1163 
1164  block.set_cluster(cluster_index)
1165  self.__update_cluster_dendrogram(cluster_index, [block])
1166 
1167  neighbors = self.__find_block_neighbors(block, leaf_blocks, unhandled_block_indexes)
1168  self.__update_cluster_dendrogram(cluster_index, neighbors)
1169 
1170  for neighbor in neighbors:
1171  neighbor.set_cluster(cluster_index)
1172  neighbor_neighbors = self.__find_block_neighbors(neighbor, leaf_blocks, unhandled_block_indexes)
1173  self.__update_cluster_dendrogram(cluster_index, neighbor_neighbors)
1174 
1175  neighbors += neighbor_neighbors
1176 
1177 
1178  def __store_clustering_results(self, amount_clusters, leaf_blocks):
1179  """!
1180  @brief Stores clustering results in a convenient way.
1181 
1182  @param[in] amount_clusters (uint): Amount of cluster that was allocated during processing.
1183  @param[in] leaf_blocks (list): Leaf BANG-blocks (the smallest cells).
1184 
1185  """
1186  self.__clusters = [[] for _ in range(amount_clusters)]
1187  for block in leaf_blocks:
1188  index = block.get_cluster()
1189 
1190  if index is not None:
1191  self.__clusters[index] += block.get_points()
1192  else:
1193  self.__noise += block.get_points()
1194 
1195  self.__clusters = [ list(set(cluster)) for cluster in self.__clusters ]
1196  self.__noise = list(set(self.__noise))
1197 
1198 
1199  def __find_block_center(self, level_blocks, unhandled_block_indexes):
1200  """!
1201  @brief Search block that is cluster center for new cluster.
1202 
1203  @return (bang_block) Central block for new cluster, if cluster is not found then None value is returned.
1204 
1205  """
1206  for i in reversed(range(len(level_blocks))):
1207  if level_blocks[i].get_density() <= self.__density_threshold:
1208  return None
1209 
1210  if level_blocks[i].get_cluster() is None:
1211  unhandled_block_indexes.remove(i)
1212  return level_blocks[i]
1213 
1214  return None
1215 
1216 
1217  def __find_block_neighbors(self, block, level_blocks, unhandled_block_indexes):
1218  """!
1219  @brief Search block neighbors that are parts of new clusters (density is greater than threshold and that are
1220  not cluster members yet), other neighbors are ignored.
1221 
1222  @param[in] block (bang_block): BANG-block for which neighbors should be found (which can be part of cluster).
1223  @param[in] level_blocks (list): BANG-blocks on specific level.
1224  @param[in] unhandled_block_indexes (set): Blocks that have not been processed yet.
1225 
1226  @return (list) Block neighbors that can become part of cluster.
1227 
1228  """
1229  neighbors = []
1230 
1231  handled_block_indexes = []
1232  for unhandled_index in unhandled_block_indexes:
1233  if block.is_neighbor(level_blocks[unhandled_index]):
1234  handled_block_indexes.append(unhandled_index)
1235  neighbors.append(level_blocks[unhandled_index])
1236 
1237  # Maximum number of neighbors is eight
1238  if len(neighbors) == 8:
1239  break
1240 
1241  for handled_index in handled_block_indexes:
1242  unhandled_block_indexes.remove(handled_index)
1243 
1244  return neighbors
1245 
1246 
1247  def __update_cluster_dendrogram(self, index_cluster, blocks):
1248  """!
1249  @brief Append clustered blocks to dendrogram.
1250 
1251  @param[in] index_cluster (uint): Cluster index that was assigned to blocks.
1252  @param[in] blocks (list): Blocks that were clustered.
1253 
1254  """
1255  if len(self.__dendrogram) <= index_cluster:
1256  self.__dendrogram.append([])
1257 
1258  blocks = sorted(blocks, key=lambda block: block.get_density(), reverse=True)
1259  self.__dendrogram[index_cluster] += blocks
1260 
pyclustering.cluster.bang.spatial_block.__volume
__volume
Definition: bang.py:597
pyclustering.cluster.bang.bang_block.__init__
def __init__(self, data, region, level, space_block, cache_points=False)
Create BANG-block.
Definition: bang.py:736
pyclustering.cluster.bang.bang_directory.get_leafs
def get_leafs(self)
Return leafs - the smallest blocks.
Definition: bang.py:452
pyclustering.cluster.bang.bang.__allocate_clusters
def __allocate_clusters(self)
Performs cluster allocation using leafs of tree in BANG directory (the smallest cells).
Definition: bang.py:1128
pyclustering.cluster.bang.bang.__find_block_neighbors
def __find_block_neighbors(self, block, level_blocks, unhandled_block_indexes)
Search block neighbors that are parts of new clusters (density is greater than threshold and that are...
Definition: bang.py:1217
pyclustering.cluster.bang.bang_directory.get_height
def get_height(self)
Returns height of BANG tree where blocks are stored.
Definition: bang.py:476
pyclustering.cluster.bang.bang_animator.__special_frame
__special_frame
Definition: bang.py:251
pyclustering.cluster.bang.bang_directory.__build_level
def __build_level(self, previous_level_blocks, level)
Build new level of directory.
Definition: bang.py:533
pyclustering.cluster.bang.spatial_block.__min_corner
__min_corner
Definition: bang.py:596
pyclustering.cluster.bang.bang_animator.__draw_block
def __draw_block(self, block, block_alpha=0.0)
Display single BANG block on axis.
Definition: bang.py:279
pyclustering.cluster.cluster_visualizer
Common visualizer of clusters on 1D, 2D or 3D surface.
Definition: __init__.py:370
pyclustering.cluster.bang.bang.__store_clustering_results
def __store_clustering_results(self, amount_clusters, leaf_blocks)
Stores clustering results in a convenient way.
Definition: bang.py:1178
pyclustering.cluster.bang.bang_block.__cluster
__cluster
Definition: bang.py:753
pyclustering.cluster.bang.bang_block.__calculate_density
def __calculate_density(self, amount_points)
Calculates BANG-block density.
Definition: bang.py:874
pyclustering.cluster.bang.spatial_block
Geometrical description of BANG block in data space.
Definition: bang.py:578
pyclustering.cluster.bang.bang_animator.__noise
__noise
Definition: bang.py:243
pyclustering.cluster.bang.bang_directory.__build_directory_levels
def __build_directory_levels(self)
Build levels of direction if amount of level is greater than one.
Definition: bang.py:518
pyclustering.cluster.bang.bang_block.__len__
def __len__(self)
Returns block size defined by amount of points that are contained by this block.
Definition: bang.py:767
pyclustering.cluster.bang.bang_block.__cache_covered_data
def __cache_covered_data(self)
Cache covered data.
Definition: bang.py:906
pyclustering.cluster.bang.bang_animator.__init__
def __init__(self, directory, clusters)
Creates BANG animator instance.
Definition: bang.py:233
pyclustering.cluster.bang.bang_directory.__root
__root
Definition: bang.py:424
pyclustering.cluster.bang.bang_visualizer.show_dendrogram
def show_dendrogram(dendrogram)
Display dendrogram of BANG-blocks.
Definition: bang.py:70
pyclustering.cluster.bang.bang_directory.__len__
def __len__(self)
Returns amount of blocks that is stored in the directory.
Definition: bang.py:432
pyclustering.cluster.bang.bang_directory.__levels
__levels
Definition: bang.py:420
pyclustering.cluster.bang.spatial_block.is_neighbor
def is_neighbor(self, block)
Performs calculation to identify whether specified block is neighbor of current block.
Definition: bang.py:666
pyclustering.cluster.bang.bang_directory.__size
__size
Definition: bang.py:426
pyclustering.cluster.bang.bang_directory.__split_block
def __split_block(self, block, split_dimension, cache_require, current_level_blocks)
Split specific block in specified dimension.
Definition: bang.py:557
pyclustering.cluster.bang.bang.__clusters
__clusters
Definition: bang.py:1007
pyclustering.cluster.bang.bang_directory.__store_level_blocks
def __store_level_blocks(self, level_blocks)
Store level blocks if observing is enabled.
Definition: bang.py:505
pyclustering.cluster.bang.bang_animator.animate
def animate(self, animation_velocity=75, movie_fps=25, movie_filename=None)
Animates clustering process that is performed by BANG algorithm.
Definition: bang.py:337
pyclustering.cluster.bang.bang_block.get_density
def get_density(self)
Returns density of the BANG-block.
Definition: bang.py:787
pyclustering.cluster.bang.spatial_block.split
def split(self, dimension)
Split current block into two spatial blocks in specified dimension.
Definition: bang.py:646
pyclustering.cluster.bang.bang.__noise
__noise
Definition: bang.py:1008
pyclustering.cluster.bang.bang_animator.__current_block
__current_block
Definition: bang.py:245
pyclustering.cluster.bang.bang_block.split
def split(self, split_dimension, cache_points)
Split BANG-block into two new blocks in specified dimension.
Definition: bang.py:853
pyclustering.cluster
pyclustering module for cluster analysis.
Definition: __init__.py:1
pyclustering.cluster.bang.bang_directory.__amount_density
__amount_density
Definition: bang.py:422
pyclustering.cluster.bang.bang_visualizer
Visualizer of BANG algorithm's results.
Definition: bang.py:29
pyclustering.cluster.bang.bang_block.__points
__points
Definition: bang.py:754
pyclustering.cluster.bang.bang_block.get_cluster
def get_cluster(self)
Return index of cluster to which the BANG-block belongs to.
Definition: bang.py:797
pyclustering.cluster.bang.bang_block.__amount_points
__amount_points
Definition: bang.py:755
pyclustering.cluster.bang.bang_block.__cache_point
def __cache_point(self, index)
Store index points.
Definition: bang.py:919
pyclustering.cluster.bang.bang_animator
Provides service for creating 2-D animation using BANG clustering results.
Definition: bang.py:204
pyclustering.cluster.bang.bang.__cluster_blocks
__cluster_blocks
Definition: bang.py:1009
pyclustering.cluster.bang.bang_visualizer.show_clusters
def show_clusters(data, clusters, noise=None)
Display BANG clustering results.
Definition: bang.py:100
pyclustering.cluster.bang.bang.__dendrogram
__dendrogram
Definition: bang.py:1010
pyclustering.cluster.bang.bang.process
def process(self)
Performs clustering process in line with rules of BANG clustering algorithm.
Definition: bang.py:1018
pyclustering.cluster.bang.bang_directory.__leafs
__leafs
Definition: bang.py:423
pyclustering.cluster.bang.bang_block.get_spatial_block
def get_spatial_block(self)
Return spatial block - BANG-block description in data space.
Definition: bang.py:808
pyclustering.cluster.bang.bang.__expand_cluster_block
def __expand_cluster_block(self, block, cluster_index, leaf_blocks, unhandled_block_indexes)
Expand cluster from specific block that is considered as a central block.
Definition: bang.py:1151
pyclustering.cluster.bang.bang_directory
BANG directory stores BANG-blocks that represents grid in data space.
Definition: bang.py:395
pyclustering.cluster.bang.bang.__ccore
__ccore
Definition: bang.py:1013
pyclustering.cluster.bang.bang
Class implements BANG grid based clustering algorithm.
Definition: bang.py:934
pyclustering.cluster.bang.bang_animator.__increment_block
def __increment_block(self)
Increment BANG block safely by updating block index, level and level block.
Definition: bang.py:265
pyclustering.cluster.bang.bang_directory.__density_threshold
__density_threshold
Definition: bang.py:421
pyclustering.cluster.bang.bang_animator.__draw_cluster
def __draw_cluster(self, data, cluster, color, marker)
Draw 2-D single cluster on axis using specified color and marker.
Definition: bang.py:328
pyclustering.cluster.bang.bang_block.set_cluster
def set_cluster(self, index)
Assign cluster to the BANG-block by index.
Definition: bang.py:831
pyclustering.cluster.bang.bang_block.__level
__level
Definition: bang.py:749
pyclustering.cluster.bang.bang_animator.__current_level
__current_level
Definition: bang.py:246
pyclustering.cluster.bang.bang_directory.__level_blocks
__level_blocks
Definition: bang.py:425
pyclustering.cluster.bang.spatial_block.__calculate_volume
def __calculate_volume(self)
Calculates volume of current spatial block.
Definition: bang.py:710
pyclustering.cluster.bang.bang.__levels
__levels
Definition: bang.py:1005
pyclustering.cluster.bang.bang.__validate_arguments
def __validate_arguments(self)
Check input arguments of BANG algorithm and if one of them is not correct then appropriate exception ...
Definition: bang.py:1107
pyclustering.cluster.bang.bang_block.__data
__data
Definition: bang.py:747
pyclustering.cluster.bang.bang_animator.__validate_arguments
def __validate_arguments(self)
Check correctness of input arguments and throw exception if incorrect is found.
Definition: bang.py:256
pyclustering.cluster.bang.spatial_block.get_volume
def get_volume(self)
Returns volume of current block.
Definition: bang.py:634
pyclustering.cluster.bang.bang.__density_threshold
__density_threshold
Definition: bang.py:1011
pyclustering.cluster.bang.bang.get_directory
def get_directory(self)
Returns grid directory that describes grid of the processed data.
Definition: bang.py:1068
pyclustering.cluster.bang.bang_animator.__draw_leaf_density
def __draw_leaf_density(self)
Display densities by filling blocks by appropriate colors.
Definition: bang.py:300
pyclustering.cluster.bang.bang.__data
__data
Definition: bang.py:1004
pyclustering.cluster.bang.bang_block.get_points
def get_points(self)
Return points that covers by the BANG-block.
Definition: bang.py:818
pyclustering.cluster.bang.bang_block.is_neighbor
def is_neighbor(self, block)
Performs calculation to check whether specified block is neighbor to the current.
Definition: bang.py:841
pyclustering.cluster.bang.spatial_block.__str__
def __str__(self)
Returns string block description.
Definition: bang.py:600
pyclustering.cluster.bang.bang_block
BANG-block that represent spatial region in data space.
Definition: bang.py:731
pyclustering.cluster.bang.bang_animator.__ax
__ax
Definition: bang.py:250
pyclustering.cluster.bang.bang_directory.__observe
__observe
Definition: bang.py:427
pyclustering.cluster.bang.bang.get_dendrogram
def get_dendrogram(self)
Returns dendrogram of clusters.
Definition: bang.py:1082
pyclustering.utils.color
Colors used by pyclustering library for visualization.
Definition: color.py:1
pyclustering.cluster.bang.bang.__update_cluster_dendrogram
def __update_cluster_dendrogram(self, index_cluster, blocks)
Append clustered blocks to dendrogram.
Definition: bang.py:1247
pyclustering.cluster.bang.bang.__directory
__directory
Definition: bang.py:1006
pyclustering.cluster.bang.bang_block.__spatial_block
__spatial_block
Definition: bang.py:750
pyclustering.cluster.bang.spatial_block.__max_corner
__max_corner
Definition: bang.py:595
pyclustering.cluster.bang.bang_animator.__figure
__figure
Definition: bang.py:249
pyclustering.cluster.bang.bang_animator.__level_blocks
__level_blocks
Definition: bang.py:247
pyclustering.cluster.bang.bang_block.__region_number
__region_number
Definition: bang.py:748
pyclustering.utils
Utils that are used by modules of pyclustering.
Definition: __init__.py:1
pyclustering.cluster.bang.bang_animator.__directory
__directory
Definition: bang.py:241
pyclustering.cluster.bang.spatial_block.get_corners
def get_corners(self)
Return spatial description of current block.
Definition: bang.py:624
pyclustering.cluster.bang.spatial_block.__init__
def __init__(self, max_corner, min_corner)
Creates spatial block in data space.
Definition: bang.py:587
pyclustering.cluster.bang.bang.__amount_threshold
__amount_threshold
Definition: bang.py:1012
pyclustering.cluster.bang.bang_block.__get_amount_points
def __get_amount_points(self)
Count covered points by the BANG-block and if cache is enable then covered points are stored.
Definition: bang.py:890
pyclustering.cluster.bang.bang_block.get_region
def get_region(self)
Returns region number of BANG-block.
Definition: bang.py:775
pyclustering.cluster.bang.bang.__init__
def __init__(self, data, levels, ccore=False, **kwargs)
Create BANG clustering algorithm.
Definition: bang.py:982
pyclustering.cluster.bang.bang_directory.__init__
def __init__(self, data, levels, **kwargs)
Create BANG directory - basically tree structure with direct access to leafs.
Definition: bang.py:402
pyclustering.cluster.bang.spatial_block.__calculate_neighborhood
def __calculate_neighborhood(self, block_max_corner)
Calculates neighborhood score that defined whether blocks are neighbors.
Definition: bang.py:687
pyclustering.cluster.bang.bang.__find_block_center
def __find_block_center(self, level_blocks, unhandled_block_indexes)
Search block that is cluster center for new cluster.
Definition: bang.py:1199
pyclustering.cluster.bang.bang_directory.__data
__data
Definition: bang.py:419
pyclustering.cluster.bang.bang_animator.__clusters
__clusters
Definition: bang.py:242
pyclustering.cluster.bang.bang_animator.__draw_clusters
def __draw_clusters(self)
Display clusters and outliers using different colors.
Definition: bang.py:315
pyclustering.cluster.bang.bang_directory.get_level
def get_level(self, level)
Returns BANG blocks on the specific level.
Definition: bang.py:464
pyclustering.cluster.bang.bang_block.__cache_points
__cache_points
Definition: bang.py:751
pyclustering.cluster.encoder
Module for representing clustering results.
Definition: encoder.py:1
pyclustering.cluster.bang.bang_directory.get_data
def get_data(self)
Return data that is stored in the directory.
Definition: bang.py:442
pyclustering.cluster.bang.bang.get_clusters
def get_clusters(self)
Returns allocated clusters.
Definition: bang.py:1038
pyclustering.cluster.bang.bang.get_cluster_encoding
def get_cluster_encoding(self)
Returns clustering result representation type that indicate how clusters are encoded.
Definition: bang.py:1094
pyclustering.cluster.bang.bang_directory.__create_directory
def __create_directory(self)
Create BANG directory as a tree with separate storage for leafs.
Definition: bang.py:486
pyclustering.cluster.bang.bang_visualizer.show_blocks
def show_blocks(directory)
Show BANG-blocks (leafs only) in data space.
Definition: bang.py:40
pyclustering.cluster.bang.bang_block.__str__
def __str__(self)
Returns string representation of BANG-block using region number and level where block is located.
Definition: bang.py:759
pyclustering.cluster.bang.bang.get_noise
def get_noise(self)
Returns allocated noise.
Definition: bang.py:1053
pyclustering.cluster.bang.spatial_block.__contains__
def __contains__(self, point)
Point is considered as contained if it lies in block (belong to it).
Definition: bang.py:610
pyclustering.cluster.bang.bang_block.__density
__density
Definition: bang.py:756