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. 172 from pyclustering.cluster import cluster_visualizer 173 from pyclustering.cluster.syncnet import syncnet, solve_type 174 from pyclustering.samples.definitions import SIMPLE_SAMPLES 175 from pyclustering.utils import read_sample 177 # Read sample for clustering from some file. 178 sample = read_sample(SIMPLE_SAMPLES.SAMPLE_SIMPLE3) 180 # Create oscillatory network with connectivity radius 1.0. 181 network = syncnet(sample, 1.0) 183 # Run cluster analysis and collect output dynamic of the oscillatory network. 184 # Network simulation is performed by Runge Kutta 4. 185 analyser = network.process(0.998, solve_type.RK4) 187 # Show oscillatory network. 188 network.show_network() 190 # Obtain clustering results. 191 clusters = analyser.allocate_clusters() 193 # Visualize clustering results. 194 visualizer = cluster_visualizer() 195 visualizer.append_clusters(clusters, sample) 201 def __init__(self, sample, radius, conn_repr = conn_represent.MATRIX, initial_phases = initial_type.RANDOM_GAUSSIAN, enable_conn_weight = False, ccore = True):
203 @brief Contructor of the oscillatory network SYNC for cluster analysis. 205 @param[in] sample (list): Input data that is presented as list of points (objects), each point should be represented by list or tuple. 206 @param[in] radius (double): Connectivity radius between points, points should be connected if distance between them less then the radius. 207 @param[in] conn_repr (conn_represent): Internal representation of connection in the network: matrix or list. Ignored in case of usage of CCORE library. 208 @param[in] initial_phases (initial_type): Type of initialization of initial phases of oscillators (random, uniformly distributed, etc.). 209 @param[in] enable_conn_weight (bool): If True - enable mode when strength between oscillators depends on distance between two oscillators. 210 If False - all connection between oscillators have the same strength that equals to 1 (True). 211 @param[in] ccore (bool): Defines should be CCORE C++ library used instead of Python code or not. 219 if ( (ccore
is True)
and ccore_library.workable() ):
226 super().
__init__(len(sample), 1, 0, conn_type.DYNAMIC, conn_repr, initial_phases,
False);
232 if (radius
is not None):
238 @brief Destructor of oscillatory network is based on Kuramoto model. 247 def _create_connections(self, radius):
249 @brief Create connections between oscillators in line with input radius of connectivity. 251 @param[in] radius (double): Connectivity radius between oscillators. 258 maximum_distance = 0;
259 minimum_distance = float(
'inf');
262 for i
in range(0, self.
_num_osc, 1):
263 for j
in range(i + 1, self.
_num_osc, 1):
270 if (dist > maximum_distance): maximum_distance = dist;
271 if (dist < minimum_distance): minimum_distance = dist;
280 if (maximum_distance != minimum_distance):
281 multiplier = (maximum_distance - minimum_distance);
282 subtractor = minimum_distance;
284 for i
in range(0, self.
_num_osc, 1):
285 for j
in range(i + 1, self.
_num_osc, 1):
286 value_conn_weight = (self.
_conn_weight[i][j] - subtractor) / multiplier;
292 def process(self, order = 0.998, solution = solve_type.FAST, collect_dynamic = True):
294 @brief Peforms cluster analysis using simulation of the oscillatory network. 296 @param[in] order (double): Order of synchronization that is used as indication for stopping processing. 297 @param[in] solution (solve_type): Specified type of solving diff. equation. 298 @param[in] collect_dynamic (bool): Specified requirement to collect whole dynamic of the network. 300 @return (syncnet_analyser) Returns analyser of results of clustering. 308 output_sync_dynamic = self.
simulate_dynamic(order, solution, collect_dynamic);
309 return syncnet_analyser(output_sync_dynamic.output, output_sync_dynamic.time,
None);
312 def _phase_kuramoto(self, teta, t, argv):
314 @brief Overrided method for calculation of oscillator phase. 316 @param[in] teta (double): Current value of phase. 317 @param[in] t (double): Time (can be ignored). 318 @param[in] argv (uint): Index of oscillator whose phase represented by argument teta. 320 @return (double) New value of phase of oscillator with index 'argv'. 333 phase += conn_weight * self.
_weight * math.sin(self.
_phases[k] - teta);
335 divider = len(neighbors);
339 return ( self.
_freq[index] + (phase / divider) );
344 @brief Shows connections in the network. It supports only 2-d and 3-d representation. 352 if ( (dimension != 3)
and (dimension != 2) ):
353 raise NameError(
'Network that is located in different from 2-d and 3-d dimensions can not be represented');
355 from matplotlib.font_manager
import FontProperties;
356 from matplotlib
import rcParams;
358 rcParams[
'font.sans-serif'] = [
'Arial'];
359 rcParams[
'font.size'] = 12;
364 axes = fig.add_subplot(111);
365 elif (dimension == 3):
366 axes = fig.gca(projection=
'3d');
368 surface_font = FontProperties();
369 surface_font.set_name(
'Arial');
370 surface_font.set_size(
'12');
372 for i
in range(0, self.
_num_osc, 1):
376 for j
in range(i, self.
_num_osc, 1):
385 elif (dimension == 3):
389 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. ...