A library that generalizes the original 2-dimensional CLUE
Project description
CLUEstering
The CLUE algorithm is a clustering algorithm written at CERN.
The original algorithm was designed to work in 2 dimensions, with the data distributed in parallel layers. Unlike other clustering algorithms, CLUE takes the coordinates of the points and also their weight, which represents their energy, and calculates the energy density of each point. This energy density is used to find the seeds for each cluster, their followers and the outliers, which are dismissed as noise. CLUE takes 4 parameters in input:
dc_
, which is the side of the box inside of which the density of a point is calculated;rhoc
, which is the minimum energy density that a point must have to not be considered an outlier,outlierDeltaFactor
, that multiplied by dc_ gives dm_, the side of the box inside of which the followers of a point are searched;pointsPerBin
, which is the average number of points that are to be found inside a bin. This value allows to control the size of the bins.
This library generalizes the original algorithm, making it N-dimensional, and turns it into a general purpose algorithm, usable by any user and applicaple to a wider range of applications, in particular outside particle physics.
The C++ code is binded using PyBind11, and the module is created locally during the installation of the library.
In the library is defined the clusterer
class, which contains the methods for reading the data, running the algorithm, plotting the data both in input and output, and others.
Outside of the class is also defined the function test_blobs, which takes the number of points and the number of dimensions, and is a way to test quickly the library, producing some N-dimensional blobs.
Below is shown a basic example of how the library can be used:
import CLUEstering as clue
clust = clue.clusterer(1., 5., 1.5)
clust.read_data(clue.test_blobs(1000,2))
clust.run_clue()
clust.cluster_plotter()
The clusterer
class
The clusterer
class represents a wrapper class around the method mainRun
, which is binded from C++
and that is the method that runs the CLUE algorithm.
When an instance of this class is created, it requires at least three parameters: dc
, rhoc
and outlierDeltaFactor
. There is a fourth parameter, pPBin
, which represents the desired average number of points found in each of the bins that the clustering space is divided into. This parameter has a default value of 10
.
The parameters dc
, rhoc
and outlierDeltaFactor
must be floats
or a type convertible to a float
. ppBin
, on the other hand, is an integer
.
The class has several methods:
read_data
, which takes the data in input and inizializes the class members. The data can be in the form of list, numpy array, dictionary, string containing the path to a csv file or pandas DataFrame;change_coordinates
, which allows to change the coordinate system used for clustering;change_domains
, which allows to change the domain ranges of any eventual periodic coordinates;choose_kernel
, which allows to change the convolution kernel used when calculating the local density of each point. The default kernel is a flat kernel with parameter0.5
, but it can be changed to an exponential or gaussian kernel, or a custom kernel, which is user defined and can be any continuous function;run_clue
, which takes no parameters and runs the CLUE algorithm;input_plotter
, which plots all the points in input. This method is useful for getting an idea of the shape of the dataset before clustering. In addition to some plot customizations (like the colour or the size of the points, the addition of a grid, the axis labels and so on) it's also possible to pass the functions for the change of coordinates and change the coordinate system used for plotting.cluster_plotter
, which plots the data using a different colour for each cluster. The seeds are indicated by stars and the outliers by small grey crosses.to_csv
, which takes two strings, the first containing the path to a folder and the second containing the desired name for the csv file (also with the .csv suffix) and produces the csv file containing the cluster informations.
Reading data
Data is read with the read_data
method.
For the data to be acceptable, it must contain the values of at least one coordinate for all the points, and their weights
. The weights
of the points represent their relative importance in the dataset, so in most cases they can all be set to 1. There are several accepted formats for providing the data:
string
, where the string contains the relative path to acsv
file. The file must contain at least one column for the coordinates, which must be named asx*
(x0
,x1
, ecc.) and one column for theweight
pandas.DataFrame
, where the columns for the coordinates must be namedx*
(x1
,x2
, ecc.) and one column should contain theweight
list
ornp.ndarray
, where the coordinate data should be provided as a list of lists (or array of arrays), and the weights inserted in a second, separate list/arraydictionary
, where the coordinate data must be contained in lists, each with keyx*
(,
, ecc.) and the weights in another list with keyweight
Generating a test dataset with test_blobs
If a user wants to test the library without using real data, they can easily do so using the test_blobs
method.
test_blobs
generates a dataset containing any number of gaussian blobs (4 by default), i.e. regular distributions of points distributed gaussianly in a round shape. These blobs can be generated in 2 or 3 dimensions.
It is possible to customize:
- the number of points in the dataset, through the parameter
n_samples
- how spread out the points are, through the
mean
andsigma
parameters - the spatial span over which these blobs are placed, throught the parameters
x_max
andy_max
. By modifying this parameters it's possible to make the blobs more crammed or more well separated, thus making it harder or easier to clusterize them
Change of kernels for the calculation of local density
Since version 1.3.0
it is possible to choose what kernel to use when calculating the local density of each point.
The default choices are gaussian
, exponential
and flat
. Each of the kernels require a list of parameters:
flat
, takes a single parameterexp
, takes two parameters, the amplitude and the mean.gaus
, takes three parameters, the amplitude, the mean and the standard deviation.
The default kernel is a flat kernel with parameter 0.5
.
The different kernels can be chosen using the choose_kernel
method. It is also possible to use a user-defined kernel, by passing it as a function object. Custom kernels require an empty list to be passed as parameters.
The functions used to define a custom kernel should take three parameters:
- The distance
dist_ij
between the two points. - The id
point_id
of the fixed point. - The id
j
of the neighbouring points.
import CLUEstering as clue
clust = clue.clusterer(1., 5., 1.5) # the default kernel is flat(0.5)
# Change to an exponential kernel
clust.choose_kernel('exp', [1. 1.5])
# Now use a custom kernel, a linear function
clust.choose_kernel('custom', [], lambda x, y, z: 2 * x)
Use of periodic coordinates and change of the coordinate system
Since version version 1.4.0
it is possible to use periodic coordinates.
The finite domain of a periodic variable con be specified in the call of the read_data
method by passing a tuple containing the extremes of the domain with a keyword that specifies which coordinate should be bounded (x0
, x1
, x2
, ecc.).
import CLUEstering as clue
from math import pi
clust = clue.clusterer(1., 5., 1.5)
clue.read_data('my_data.csv', x1=(0, 2*pi))
The domain of a periodic variable can also be changed after the call to read_data
, using the method change_domains
.
It is also possible to change the coordinate system used for the clustering. This can be done through the change_coordinates
method, which takes as arguments function objects representing the change of system for each of the coordinates.
import CLUEstering as clue
from math import pi
clust = clue.clusterer(1., 5., 1.5)
clust.read_data('my_data.csv')
# Move from cartesian to polar coordinate system
## x0 is the radius, x1 is the polar angle
clust.change_coordinates(x0=lambda x, y: np.sqrt(x**2 + y**2), x1= lambda x, y: np.arctan2(y, x))
Finally, it's also possible to change the coordiantes system used for plotting. This can be useful when a specific coordinate system is well suited for clustering a given dataset, because it takes advantage of some symmetries in the data, but the plots should still be in cartesian coordinates. To do this the equations for the change of coordinates can be passed as function objects to the two plotting methods.
Input and cluster plotter
methods
The input_plotter
and cluster_plotter
methods two plotting methods based on matplotlib. input_plotter
is intenteded to be used as a way to observe the data before clustering and getting an idea of the expected result, whereas cluster_plotter
plots the results of the clustering, plotting the points corresponding to the same cluster with the same colour and the outliers as small grey crosses.
Both methods allow for a wide range of customizations:
- the title of the plot and its size can be changed with the
plot_title
andtitle_size
parameters - the labels of the axis can be changed with the
x_label
,y_label
andz_label
parameters - the size and colour of the points. In the cluster plotter it is possible to change the size of the three classes of points (normal, seed and outlier) singularly
- it's possible to add a grid to the point with the
grid
boolean parameter, and change its style and size with thegrid_style
andgrid_size
parameters - the ticks on the axis can be changed with the
x_ticks
,y_ticks
andz_ticks
parameters
Since version 1.4.0
both plotting methods can take function objects as kwargs, where the functions represent equations for the change of coordinates, thus allowing to change the coordinate system used for plotting.
import CLUEstering as clue
clust = clue.clusterer(1., 5., 1.5)
clust.read_data(data)
# Plot the data in polar coordinates
clust.input_plotter(x0=lambda x: np.sqrt(x[0]**2 + x[1]**2),
x1=lambda x: np.arctan2(x[1], x[0]))
clust.run_clue()
This is particularly useful when the data has some kind of simmetry, which allows it to be clustered more easily in another coordinate system.
Writing the results of the clustering to file
The results of the clustering can be saved to a csv file for later analysis, using the method to_csv
.
This method taks as parameter the path to the output_folder
and the file_name
, where the name of the file must include the .csv
suffix.
The data saved on the file include the entire input, so the points' coordinates and weights, as well as their cluster_id
s, an integer that indicates to what cluster they belong, and is_seed
, a boolean value indicating whether a point is a seed or not.
import CLUEstering as clue
clust = clue.clusterer(1., 5., 1.5)
clust.read_data(data)
clust.run_clue()
clust.to_csv('./output/', 'data_results.csv')
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.