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 oscillators (phases). 83 @param[in] eps (double): Tolerance that defines the maximum difference between phases of oscillators that belong to 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.\
154 FuncAnimation(figure, frame_generation, len(analyser), interval=animation_velocity, init_func=init_frame,
157 if save_movie
is not None:
161 cluster_animation.save(save_movie, writer=
'ffmpeg', fps=15, bitrate=1500)
168 @brief Class represents clustering algorithm SyncNet. 169 @details SyncNet is bio-inspired algorithm that is based on oscillatory network that uses modified Kuramoto model. Each attribute of a data object 170 is considered as a phase oscillator. 174 from pyclustering.cluster import cluster_visualizer 175 from pyclustering.cluster.syncnet import syncnet, solve_type 176 from pyclustering.samples.definitions import SIMPLE_SAMPLES 177 from pyclustering.utils import read_sample 179 # Read sample for clustering from some file. 180 sample = read_sample(SIMPLE_SAMPLES.SAMPLE_SIMPLE3) 182 # Create oscillatory network with connectivity radius 1.0. 183 network = syncnet(sample, 1.0) 185 # Run cluster analysis and collect output dynamic of the oscillatory network. 186 # Network simulation is performed by Runge Kutta 4. 187 analyser = network.process(0.998, solve_type.RK4) 189 # Show oscillatory network. 190 network.show_network() 192 # Obtain clustering results. 193 clusters = analyser.allocate_clusters() 195 # Visualize clustering results. 196 visualizer = cluster_visualizer() 197 visualizer.append_clusters(clusters, sample) 203 def __init__(self, sample, radius, conn_repr=conn_represent.MATRIX, initial_phases=initial_type.RANDOM_GAUSSIAN,
204 enable_conn_weight=False, ccore=True):
206 @brief Contructor of the oscillatory network SYNC for cluster analysis. 208 @param[in] sample (list): Input data that is presented as list of points (objects), each point should be represented by list or tuple. 209 @param[in] radius (double): Connectivity radius between points, points should be connected if distance between them less then the radius. 210 @param[in] conn_repr (conn_represent): Internal representation of connection in the network: matrix or list. Ignored in case of usage of CCORE library. 211 @param[in] initial_phases (initial_type): Type of initialization of initial phases of oscillators (random, uniformly distributed, etc.). 212 @param[in] enable_conn_weight (bool): If True - enable mode when strength between oscillators depends on distance between two oscillators. 213 If False - all connection between oscillators have the same strength that equals to 1 (True). 214 @param[in] ccore (bool): Defines should be CCORE C++ library used instead of Python code or not. 224 if (ccore
is True)
and ccore_library.workable():
231 super().
__init__(len(sample), 1, 0, conn_type.DYNAMIC, conn_repr, initial_phases,
False)
237 if radius
is not None:
243 @brief Destructor of oscillatory network is based on Kuramoto model. 252 def _verify_arguments(self):
254 @brief Verify input parameters for the algorithm and throw exception in case of incorrectness. 258 raise ValueError(
"Input data is empty (size: '%d')." % self.
_num_osc)
261 def _create_connections(self, radius):
263 @brief Create connections between oscillators in line with input radius of connectivity. 265 @param[in] radius (double): Connectivity radius between oscillators. 273 minimum_distance = float(
'inf')
276 for i
in range(0, self.
_num_osc, 1):
277 for j
in range(i + 1, self.
_num_osc, 1):
284 if (dist > maximum_distance): maximum_distance = dist
285 if (dist < minimum_distance): minimum_distance = dist
294 if maximum_distance != minimum_distance:
295 multiplier = (maximum_distance - minimum_distance)
296 subtractor = minimum_distance
298 for i
in range(0, self.
_num_osc, 1):
299 for j
in range(i + 1, self.
_num_osc, 1):
300 value_conn_weight = (self.
_conn_weight[i][j] - subtractor) / multiplier
306 def process(self, order = 0.998, solution=solve_type.FAST, collect_dynamic=True):
308 @brief Peforms cluster analysis using simulation of the oscillatory network. 310 @param[in] order (double): Order of synchronization that is used as indication for stopping processing. 311 @param[in] solution (solve_type): Specified type of solving diff. equation. 312 @param[in] collect_dynamic (bool): Specified requirement to collect whole dynamic of the network. 314 @return (syncnet_analyser) Returns analyser of results of clustering. 322 output_sync_dynamic = self.
simulate_dynamic(order, solution, collect_dynamic)
323 return syncnet_analyser(output_sync_dynamic.output, output_sync_dynamic.time,
None)
326 def _phase_kuramoto(self, teta, t, argv):
328 @brief Overrided method for calculation of oscillator phase. 330 @param[in] teta (double): Current value of phase. 331 @param[in] t (double): Time (can be ignored). 332 @param[in] argv (uint): Index of oscillator whose phase represented by argument teta. 334 @return (double) New value of phase of oscillator with index 'argv'. 347 phase += conn_weight * self.
_weight * math.sin(self.
_phases[k] - teta)
349 divider = len(neighbors)
353 return self.
_freq[index] + (phase / divider)
358 @brief Shows connections in the network. It supports only 2-d and 3-d representation. 366 if (dimension != 3)
and (dimension != 2):
367 raise NameError(
'Network that is located in different from 2-d and 3-d dimensions can not be represented');
369 from matplotlib.font_manager
import FontProperties
370 from matplotlib
import rcParams
372 rcParams[
'font.sans-serif'] = [
'Arial']
373 rcParams[
'font.size'] = 12
378 axes = fig.add_subplot(111)
380 axes = fig.gca(projection=
'3d')
382 surface_font = FontProperties()
383 surface_font.set_name(
'Arial')
384 surface_font.set_size(
'12')
386 for i
in range(0, self.
_num_osc, 1):
390 for j
in range(i, self.
_num_osc, 1):
403 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 oscillators (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. ...