3 @brief Cluster analysis algorithm: Sync 4 @details Implementation based on paper @cite article::syncnet::1. 6 @authors Andrei Novikov (pyclustering@yandex.ru) 8 @copyright GNU Public License 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. 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. 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/>. 31 import matplotlib.pyplot
as plt
32 import matplotlib.animation
as animation
33 except Exception
as error_instance:
34 warnings.warn(
"Impossible to import matplotlib (please, install 'matplotlib'), pyclustering's visualization " 35 "functionality is not available (details: '%s')." % str(error_instance))
40 from pyclustering.core.syncnet_wrapper
import syncnet_create_network, syncnet_process, syncnet_destroy_network, syncnet_analyser_destroy
41 from pyclustering.core.sync_wrapper
import sync_connectivity_matrix
42 from pyclustering.core.wrapper
import ccore_library
52 @brief Performs analysis of output dynamic of the oscillatory network syncnet to extract information about cluster allocation. 56 def __init__(self, phase, time, pointer_sync_analyser):
58 @brief Constructor of the analyser. 60 @param[in] phase (list): Output dynamic of the oscillatory network, where one iteration consists of all phases of oscillators. 61 @param[in] time (list): Simulation time. 62 @param[in] pointer_sync_analyser (POINTER): Pointer to CCORE analyser, if specified then other arguments can be omitted. 65 super().
__init__(phase, time, pointer_sync_analyser);
70 @brief Desctructor of the analyser. 81 @brief Returns list of clusters in line with state of ocillators (phases). 83 @param[in] eps (double): Tolerance level that define maximal difference between phases of oscillators in one cluster. 84 @param[in] indexes (list): List of real object indexes and it should be equal to amount of oscillators (in case of 'None' - indexes are in range [0; amount_oscillators]). 85 @param[in] iteration (uint): Iteration of simulation that should be used for allocation. 87 @return (list) List of clusters, for example [ [cluster1], [cluster2], ... ].) 96 @brief Returns clustering result representation type that indicate how clusters are encoded. 98 @return (type_encoding) Clustering result representation. 104 return type_encoding.CLUSTER_INDEX_LIST_SEPARATION;
110 @brief Visualizer of output dynamic of oscillatory network 'syncnet' for cluster analysis. 117 @brief Shows animation of output dynamic (output of each oscillator) during simulation on a circle from [0; 2pi]. 119 @param[in] dataset (list): Input data that was used for processing by the network. 120 @param[in] analyser (syncnet_analyser): Output dynamic analyser of the Sync network. 121 @param[in] animation_velocity (uint): Interval between frames in milliseconds. 122 @param[in] tolerance (double): Tolerance level that define maximal difference between phases of oscillators in one cluster. 123 @param[in] save_movie (string): If it is specified then animation will be stored to file that is specified in this parameter. 124 @param[in] title (string): If it is specified then title will be displayed on the animation plot. 128 figure = plt.figure();
131 return frame_generation(0);
133 def frame_generation(index_dynamic):
135 if (title
is not None):
136 figure.suptitle(title, fontsize = 26, fontweight =
'bold');
138 ax1 = figure.add_subplot(121, projection=
'polar');
140 clusters = analyser.allocate_clusters(eps = tolerance, iteration = index_dynamic);
141 dynamic = analyser.output[index_dynamic];
144 visualizer.append_clusters(clusters, dataset);
146 artist1, = ax1.plot(dynamic, [1.0] * len(dynamic), marker =
'o', color =
'blue', ls =
'');
148 visualizer.show(figure, display =
False);
149 artist2 = figure.gca();
151 return [ artist1, artist2 ];
153 cluster_animation = animation.FuncAnimation(figure, frame_generation, len(analyser), interval = animation_velocity, init_func = init_frame, repeat_delay = 5000);
155 if (save_movie
is not None):
159 cluster_animation.save(save_movie, writer =
'ffmpeg', fps = 15, bitrate = 1500);
166 @brief Class represents clustering algorithm SyncNet. 167 @details SyncNet is bio-inspired algorithm that is based on oscillatory network that uses modified Kuramoto model. Each attribute of a data object 168 is considered as a phase oscillator. 170 CCORE option can be used to use the pyclustering core - C/C++ shared library for processing that significantly increases performance. 174 # read sample for clustering from some file 175 sample = read_sample(path_to_file); 177 # create oscillatory network with connectivity radius 0.5 using CCORE (C++ implementation of pyclustering) 178 network = syncnet(sample, 0.5, ccore = True); 180 # run cluster analysis and collect output dynamic of the oscillatory network, 181 # network simulation is performed by Runge Kutta Fehlberg 45. 182 (dyn_time, dyn_phase) = network.process(0.998, solve_type.RFK45, True); 184 # show oscillatory network 185 network.show_network(); 187 # obtain clustering results 188 clusters = network.get_clusters(); 191 draw_clusters(sample, clusters); 196 def __init__(self, sample, radius, conn_repr = conn_represent.MATRIX, initial_phases = initial_type.RANDOM_GAUSSIAN, enable_conn_weight = False, ccore = True):
198 @brief Contructor of the oscillatory network SYNC for cluster analysis. 200 @param[in] sample (list): Input data that is presented as list of points (objects), each point should be represented by list or tuple. 201 @param[in] radius (double): Connectivity radius between points, points should be connected if distance between them less then the radius. 202 @param[in] conn_repr (conn_represent): Internal representation of connection in the network: matrix or list. Ignored in case of usage of CCORE library. 203 @param[in] initial_phases (initial_type): Type of initialization of initial phases of oscillators (random, uniformly distributed, etc.). 204 @param[in] enable_conn_weight (bool): If True - enable mode when strength between oscillators depends on distance between two oscillators. 205 If False - all connection between oscillators have the same strength that equals to 1 (True). 206 @param[in] ccore (bool): Defines should be CCORE C++ library used instead of Python code or not. 214 if ( (ccore
is True)
and ccore_library.workable() ):
221 super().
__init__(len(sample), 1, 0, conn_type.DYNAMIC, conn_repr, initial_phases,
False);
227 if (radius
is not None):
233 @brief Destructor of oscillatory network is based on Kuramoto model. 242 def _create_connections(self, radius):
244 @brief Create connections between oscillators in line with input radius of connectivity. 246 @param[in] radius (double): Connectivity radius between oscillators. 253 maximum_distance = 0;
254 minimum_distance = float(
'inf');
257 for i
in range(0, self.
_num_osc, 1):
258 for j
in range(i + 1, self.
_num_osc, 1):
265 if (dist > maximum_distance): maximum_distance = dist;
266 if (dist < minimum_distance): minimum_distance = dist;
275 if (maximum_distance != minimum_distance):
276 multiplier = (maximum_distance - minimum_distance);
277 subtractor = minimum_distance;
279 for i
in range(0, self.
_num_osc, 1):
280 for j
in range(i + 1, self.
_num_osc, 1):
281 value_conn_weight = (self.
_conn_weight[i][j] - subtractor) / multiplier;
287 def process(self, order = 0.998, solution = solve_type.FAST, collect_dynamic = True):
289 @brief Peforms cluster analysis using simulation of the oscillatory network. 291 @param[in] order (double): Order of synchronization that is used as indication for stopping processing. 292 @param[in] solution (solve_type): Specified type of solving diff. equation. 293 @param[in] collect_dynamic (bool): Specified requirement to collect whole dynamic of the network. 295 @return (syncnet_analyser) Returns analyser of results of clustering. 303 output_sync_dynamic = self.
simulate_dynamic(order, solution, collect_dynamic);
304 return syncnet_analyser(output_sync_dynamic.output, output_sync_dynamic.time,
None);
307 def _phase_kuramoto(self, teta, t, argv):
309 @brief Overrided method for calculation of oscillator phase. 311 @param[in] teta (double): Current value of phase. 312 @param[in] t (double): Time (can be ignored). 313 @param[in] argv (uint): Index of oscillator whose phase represented by argument teta. 315 @return (double) New value of phase of oscillator with index 'argv'. 328 phase += conn_weight * self.
_weight * math.sin(self.
_phases[k] - teta);
330 divider = len(neighbors);
334 return ( self.
_freq[index] + (phase / divider) );
339 @brief Shows connections in the network. It supports only 2-d and 3-d representation. 347 if ( (dimension != 3)
and (dimension != 2) ):
348 raise NameError(
'Network that is located in different from 2-d and 3-d dimensions can not be represented');
350 from matplotlib.font_manager
import FontProperties;
351 from matplotlib
import rcParams;
353 rcParams[
'font.sans-serif'] = [
'Arial'];
354 rcParams[
'font.size'] = 12;
359 axes = fig.add_subplot(111);
360 elif (dimension == 3):
361 axes = fig.gca(projection=
'3d');
363 surface_font = FontProperties();
364 surface_font.set_name(
'Arial');
365 surface_font.set_size(
'12');
367 for i
in range(0, self.
_num_osc, 1):
371 for j
in range(i, self.
_num_osc, 1):
380 elif (dimension == 3):
384 for j
in range(i, self.
_num_osc, 1):
Common visualizer of clusters on 1D, 2D or 3D surface.
pyclustering module for cluster analysis.
def simulate_dynamic(self, order=0.998, solution=solve_type.FAST, collect_dynamic=False, step=0.1, int_step=0.01, threshold_changes=0.0000001)
Performs dynamic simulation of the network until stop condition is not reached.
def allocate_clusters(self, eps=0.01, indexes=None, iteration=None)
Returns list of clusters in line with state of ocillators (phases).
def get_cluster_encoding(self)
Returns clustering result representation type that indicate how clusters are encoded.
Visualizer of output dynamic of oscillatory network 'syncnet' for cluster analysis.
Represents output dynamic of Sync.
def process(self, order=0.998, solution=solve_type.FAST, collect_dynamic=True)
Peforms cluster analysis using simulation of the oscillatory network.
Utils that are used by modules of pyclustering.
Performs analysis of output dynamic of the oscillatory network syncnet to extract information about c...
def __del__(self)
Destructor of oscillatory network is based on Kuramoto model.
Module for representing clustering results.
def __init__(self, phase, time, pointer_sync_analyser)
Constructor of the analyser.
def allocate_sync_ensembles(self, tolerance=0.01, indexes=None, iteration=None)
Allocate clusters in line with ensembles of synchronous oscillators where each synchronous ensemble c...
def set_connection(self, i, j)
Couples two specified oscillators in the network with dynamic connections.
Class represents clustering algorithm SyncNet.
_ccore_sync_dynamic_pointer
def has_connection(self, i, j)
Returns True if there is connection between i and j oscillators and False - if connection doesn't exi...
def get_neighbors(self, index)
Finds neighbors of the oscillator with specified index.
Neural Network: Oscillatory Neural Network based on Kuramoto model.
def animate_cluster_allocation(dataset, analyser, animation_velocity=75, tolerance=0.1, save_movie=None, title=None)
Shows animation of output dynamic (output of each oscillator) during simulation on a circle from [0; ...
def __del__(self)
Desctructor of the analyser.
def __init__(self, sample, radius, conn_repr=conn_represent.MATRIX, initial_phases=initial_type.RANDOM_GAUSSIAN, enable_conn_weight=False, ccore=True)
Contructor of the oscillatory network SYNC for cluster analysis.
Visualizer of output dynamic of sync network (Sync).
def show_network(self)
Shows connections in the network.
Neural and oscillatory network module.
Model of oscillatory network that is based on the Kuramoto model of synchronization.
def _create_connections(self, radius)
Create connections between oscillators in line with input radius of connectivity. ...