3 @brief Elbow method to determine the optimal number of clusters for k-means clustering. 4 @details Implementation based on paper @cite article::cluster::elbow::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/>. 32 from pyclustering.core.wrapper
import ccore_library
34 import pyclustering.core.elbow_wrapper
as wrapper
39 @brief Class represents Elbow method that is used to find out appropriate amount of clusters in a dataset. 40 @details The elbow is a heuristic method of interpretation and validation of consistency within cluster analysis 41 designed to help find the appropriate number of clusters in a dataset.Elbow method performs clustering 42 using K-Means algorithm for each K and estimate clustering results using sum of square erros. By default 43 K-Means++ algorithm is used to calculate initial centers that are used by K-Means algorithm. 45 The Elbow is determined by max distance from each point (x, y) to segment from kmin-point (x0, y0) to kmax-point (x1, y1), 46 where 'x' is K (amount of clusters), and 'y' is within-cluster error. Following expression is used to calculate Elbow 48 \f[Elbow_{k} = \frac{\left ( y_{0} - y_{1} \right )x_{k} + \left ( x_{1} - x_{0} \right )y_{k} + \left ( x_{0}y_{1} - x_{1}y_{0} \right )}{\sqrt{\left ( x_{1} - x_{0} \right )^{2} + \left ( y_{1} - y_{0} \right )^{2}}}\f] 50 Usage example of Elbow method for cluster analysis: 52 from pyclustering.cluster.kmeans import kmeans, kmeans_visualizer 53 from pyclustering.cluster.center_initializer import kmeans_plusplus_initializer 54 from pyclustering.cluster.elbow import elbow 55 from pyclustering.utils import read_sample 56 from pyclustering.samples.definitions import SIMPLE_SAMPLES 58 # read sample 'Simple3' from file (sample contains four clusters) 59 sample = read_sample(SIMPLE_SAMPLES.SAMPLE_SIMPLE3) 61 # create instance of Elbow method using K value from 1 to 10. 63 elbow_instance = elbow(sample, kmin, kmax) 65 # process input data and obtain results of analysis 66 elbow_instance.process() 67 amount_clusters = elbow_instance.get_amount() # most probable amount of clusters 68 wce = elbow_instance.get_wce() # total within-cluster errors for each K 70 # perform cluster analysis using K-Means algorithm 71 centers = kmeans_plusplus_initializer(sample, amount_clusters, 72 amount_candidates=kmeans_plusplus_initializer.FARTHEST_CENTER_CANDIDATE).initialize() 73 kmeans_instance = kmeans(sample, centers) 74 kmeans_instance.process() 76 # obtain clustering results and visualize them 77 clusters = kmeans_instance.get_clusters() 78 centers = kmeans_instance.get_centers() 79 kmeans_visualizer.show_clusters(sample, clusters, centers) 82 By default Elbow uses K-Means++ initializer to calculate initial centers for K-Means algorithm, it can be changed 83 using argument 'initializer': 85 # perform analysis using Elbow method with random center initializer for K-Means algorithm inside of the method. 87 elbow_instance = elbow(sample, kmin, kmax, initializer=random_center_initializer) 88 elbow_instance.process() 91 @image html elbow_example_simple_03.png "Elbows analysis with further K-Means clustering." 95 def __init__(self, data, kmin, kmax, **kwargs):
97 @brief Construct Elbow method. 99 @param[in] data (array_like): Input data that is presented as array of points (objects), each point should be represented by array_like data structure. 100 @param[in] kmin (int): Minimum amount of clusters that should be considered. 101 @param[in] kmax (int): Maximum amount of clusters that should be considered. 102 @param[in] **kwargs: Arbitrary keyword arguments (available arguments: `ccore`, `initializer`, `random_state`). 104 <b>Keyword Args:</b><br> 105 - ccore (bool): If `True` then C++ implementation of pyclustering library is used (by default `True`). 106 - initializer (callable): Center initializer that is used by K-Means algorithm (by default K-Means++). 107 - random_state (int): Seed for random state (by default is `None`, current system time is used). 111 self.
__initializer = kwargs.get(
'initializer', kmeans_plusplus_initializer)
114 self.
__ccore = kwargs.get(
'ccore',
True)
or \
115 isinstance(self.
__initializer, kmeans_plusplus_initializer)
or \
119 self.
__ccore = ccore_library.workable()
134 @brief Performs analysis to find out appropriate amount of clusters. 136 @return (elbow) Returns itself (Elbow instance). 149 def __process_by_ccore(self):
151 @brief Performs processing using C++ implementation. 154 if isinstance(self.
__initializer, kmeans_plusplus_initializer):
155 initializer = wrapper.elbow_center_initializer.KMEANS_PLUS_PLUS
157 initializer = wrapper.elbow_center_initializer.RANDOM
162 self.
__wce = result[1]
165 def __process_by_python(self):
167 @brief Performs processing using python implementation. 175 self.
__wce.append(instance.get_total_wce())
183 @brief Returns appropriate amount of clusters. 191 @brief Returns list of total within cluster errors for each K-value (kmin, kmin + 1, ..., kmax - 1). 198 def __calculate_elbows(self):
200 @brief Calculates potential elbows. 201 @details Elbow is calculated as a distance from each point (x, y) to segment from kmin-point (x0, y0) to kmax-point (x1, y1). 205 x0, y0 = 0.0, self.
__wce[0]
206 x1, y1 = float(len(self.
__wce)), self.
__wce[-1]
208 for index_elbow
in range(1, len(self.
__wce) - 1):
209 x, y = float(index_elbow), self.
__wce[index_elbow]
211 segment = abs((y0 - y1) * x + (x1 - x0) * y + (x0 * y1 - x1 * y0))
212 norm = math.sqrt((x1 - x0) ** 2 + (y1 - y0) ** 2)
213 distance = segment / norm
218 def __find_optimal_kvalue(self):
220 @brief Finds elbow and returns corresponding K-value. 223 optimal_elbow_value = max(self.
__elbows)
227 def __verify_arguments(self):
229 @brief Verify input parameters for the algorithm and throw exception in case of incorrectness. 233 raise ValueError(
"Input data is empty (size: '%d')." % len(self.
__data))
236 raise ValueError(
"K min value (current value '%d') should be greater or equal to 1." % self.
__kmin)
239 raise ValueError(
"Amount of K (" + str(self.
__kmax - self.
__kmin) +
") is too small for analysis. " 240 "It is require to have at least three K to build elbow.")
243 raise ValueError(
"K max value '%d' is greater than amount of points in data '%d'." %
def __calculate_elbows(self)
Calculates potential elbows.
The module contains K-Means algorithm and other related services.
def __process_by_python(self)
Performs processing using python implementation.
def __find_optimal_kvalue(self)
Finds elbow and returns corresponding K-value.
Class implements K-Means clustering algorithm.
def __init__(self, data, kmin, kmax, kwargs)
Construct Elbow method.
def __process_by_ccore(self)
Performs processing using C++ implementation.
def process(self)
Performs analysis to find out appropriate amount of clusters.
def __verify_arguments(self)
Verify input parameters for the algorithm and throw exception in case of incorrectness.
Collection of center initializers for algorithm that uses initial centers, for example, for K-Means or X-Means.
Class represents Elbow method that is used to find out appropriate amount of clusters in a dataset...
def get_amount(self)
Returns appropriate amount of clusters.
def get_wce(self)
Returns list of total within cluster errors for each K-value (kmin, kmin + 1, ..., kmax - 1).