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,
202 enable_conn_weight=False, ccore=True):
204 @brief Contructor of the oscillatory network SYNC for cluster analysis. 206 @param[in] sample (list): Input data that is presented as list of points (objects), each point should be represented by list or tuple. 207 @param[in] radius (double): Connectivity radius between points, points should be connected if distance between them less then the radius. 208 @param[in] conn_repr (conn_represent): Internal representation of connection in the network: matrix or list. Ignored in case of usage of CCORE library. 209 @param[in] initial_phases (initial_type): Type of initialization of initial phases of oscillators (random, uniformly distributed, etc.). 210 @param[in] enable_conn_weight (bool): If True - enable mode when strength between oscillators depends on distance between two oscillators. 211 If False - all connection between oscillators have the same strength that equals to 1 (True). 212 @param[in] ccore (bool): Defines should be CCORE C++ library used instead of Python code or not. 222 if (ccore
is True)
and ccore_library.workable():
229 super().
__init__(len(sample), 1, 0, conn_type.DYNAMIC, conn_repr, initial_phases,
False)
235 if radius
is not None:
241 @brief Destructor of oscillatory network is based on Kuramoto model. 250 def _verify_arguments(self):
252 @brief Verify input parameters for the algorithm and throw exception in case of incorrectness. 256 raise ValueError(
"Input data is empty (size: '%d')." % self.
_num_osc)
259 def _create_connections(self, radius):
261 @brief Create connections between oscillators in line with input radius of connectivity. 263 @param[in] radius (double): Connectivity radius between oscillators. 271 minimum_distance = float(
'inf')
274 for i
in range(0, self.
_num_osc, 1):
275 for j
in range(i + 1, self.
_num_osc, 1):
282 if (dist > maximum_distance): maximum_distance = dist
283 if (dist < minimum_distance): minimum_distance = dist
292 if maximum_distance != minimum_distance:
293 multiplier = (maximum_distance - minimum_distance)
294 subtractor = minimum_distance
296 for i
in range(0, self.
_num_osc, 1):
297 for j
in range(i + 1, self.
_num_osc, 1):
298 value_conn_weight = (self.
_conn_weight[i][j] - subtractor) / multiplier
304 def process(self, order = 0.998, solution=solve_type.FAST, collect_dynamic=True):
306 @brief Peforms cluster analysis using simulation of the oscillatory network. 308 @param[in] order (double): Order of synchronization that is used as indication for stopping processing. 309 @param[in] solution (solve_type): Specified type of solving diff. equation. 310 @param[in] collect_dynamic (bool): Specified requirement to collect whole dynamic of the network. 312 @return (syncnet_analyser) Returns analyser of results of clustering. 320 output_sync_dynamic = self.
simulate_dynamic(order, solution, collect_dynamic)
321 return syncnet_analyser(output_sync_dynamic.output, output_sync_dynamic.time,
None)
324 def _phase_kuramoto(self, teta, t, argv):
326 @brief Overrided method for calculation of oscillator phase. 328 @param[in] teta (double): Current value of phase. 329 @param[in] t (double): Time (can be ignored). 330 @param[in] argv (uint): Index of oscillator whose phase represented by argument teta. 332 @return (double) New value of phase of oscillator with index 'argv'. 345 phase += conn_weight * self.
_weight * math.sin(self.
_phases[k] - teta)
347 divider = len(neighbors)
351 return self.
_freq[index] + (phase / divider)
356 @brief Shows connections in the network. It supports only 2-d and 3-d representation. 364 if (dimension != 3)
and (dimension != 2):
365 raise NameError(
'Network that is located in different from 2-d and 3-d dimensions can not be represented');
367 from matplotlib.font_manager
import FontProperties
368 from matplotlib
import rcParams
370 rcParams[
'font.sans-serif'] = [
'Arial']
371 rcParams[
'font.size'] = 12
376 axes = fig.add_subplot(111)
378 axes = fig.gca(projection=
'3d')
380 surface_font = FontProperties()
381 surface_font.set_name(
'Arial')
382 surface_font.set_size(
'12')
384 for i
in range(0, self.
_num_osc, 1):
388 for j
in range(i, self.
_num_osc, 1):
401 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.
def _verify_arguments(self)
Verify input parameters for the algorithm and throw exception in case of incorrectness.
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. ...