Selecting the number of clusters k
Here is an example using exclusively PyCVI in order to guess the number of clusters in a dataset. The preprocessing steps and the clustering steps can be integrated into the PyCVI pipeline by providing sklearn-like classes of clustering models (e.g. KMeans) and data preprocessor (e.g. StandardScaler).
In this example, we use time-series data and non-time-series data. In addition we use classes from scikit-learn, scikit-learn extra and aeon in order to illustrate the compatibility of PyCVI with sklearn-like libraries.
Here we assume that we are in real conditions, which means that we don’t have access to the true labels (except that we plot the true data for illustrative purposes). We then don’t use the features included in the pycvi.vi module.
If you wish to run the example scripts on your own computer, please first follow the instructions detailed in Running example scripts on your computer.
1
2import numpy as np
3import time
4from sklearn.cluster import AgglomerativeClustering, KMeans
5from sklearn.preprocessing import StandardScaler
6from aeon.clustering import TimeSeriesKMeans
7
8from pycvi.cluster import generate_all_clusterings, get_clustering
9from pycvi.cvi import CVIs
10from pycvi.compute_scores import compute_all_scores
11from pycvi.vi import variation_information
12from pycvi.datasets.benchmark import load_data
13from pycvi.exceptions import SelectionError
14
15from pycvi_examples_utils import plot_true_best, plot_hist_selected, plot_only_selected
16
17def pipeline(
18 X: np.ndarray,
19 y: np.ndarray,
20 model_class,
21 model_kw: dict,
22 k_max: int = 25,
23 scaler = StandardScaler(),
24 ts_dist:bool = False,
25 fig_title: str = "",
26 fig_name: str = "",
27) -> None:
28 """
29 This function gives an example of typical pipeline using PyCVI.
30
31 In this example we assume that we are in real conditions, which
32 means that we don't have access to the true labels (except for the
33 final figure). We then don't use the features included in the
34 :mod:`pycvi.vi` module. In this function we:
35
36 - Standardize the data
37 - Generate all clusterings for a given range of number of clusters.
38 - For each CVI available in PyCVI, compute their values for all
39 generated clusterings
40 - For each CVI, select the best clustering according to its CVI
41 values
42 - Create a summary plot containing the true clustering, the
43 clustering assuming the correct number of clusters, for each
44 potential number of clusters :math:`k`, the number of CVI that
45 selected :math:`k` and the selected clusterings of each CVI.
46 """
47 print(f'\n ***** {fig_title} ***** \n')
48 k_range = range(k_max)
49
50 # ------------------------------------------------------------------
51 # ------------------ Define true clustering -----------------------
52 # ------------------------------------------------------------------
53 # From the label for each datapoint to a list of
54 # datapoints for each cluster.
55 # true clusters: List[List[int]]
56 true_clusters = get_clustering(y)
57 k_true = len(true_clusters)
58
59 # ------------------------------------------------------------------
60 # ------------------ Generate clusterings -------------------------
61 # ------------------------------------------------------------------
62
63 t_start = time.time()
64
65 clusterings = generate_all_clusterings(
66 X,
67 model_class,
68 model_kw=model_kw,
69 n_clusters_range = k_range,
70 ts_dist = ts_dist,
71 scaler=scaler,
72 )
73
74 t_end = time.time()
75 dt = t_end - t_start
76
77 print(f"Clusterings generated in: {dt:.2f}s")
78
79 # ------------------------------------------------------------------
80 # ------------ Compute CVI values and select k ---------------------
81 # ------------------------------------------------------------------
82 summary = {}
83
84 for cvi_class in CVIs:
85
86 # Instantiate a CVI model
87 cvi = cvi_class()
88 t_start = time.time()
89 print(f" ====== {cvi} ====== ")
90
91 # Compute CVI values for all clusterings
92 scores = compute_all_scores(
93 cvi,
94 X,
95 clusterings,
96 ts_dist=ts_dist,
97 scaler=StandardScaler(),
98 )
99
100 t_end = time.time()
101 dt = t_end - t_start
102
103 # Print CVI values and selected k
104 for k in clusterings:
105 print(k, scores[k])
106 print('Code executed in %.2f s' %(dt))
107
108 # Select k
109 try:
110 k_selected = cvi.select(scores)
111 # If no k could be selected with this CVI don't do anything...
112 except SelectionError as e:
113 k_selected = None
114
115 # Otherwise update summary info related to the selected clusterings
116 else:
117 if k_selected not in summary:
118 summary[k_selected] = {}
119 summary[k_selected]["clustering"] = clusterings[k_selected]
120 summary[k_selected]["#CVI"] = summary[k_selected].pop("#CVI", 0) + 1
121 ax_title = f'k={k_selected}, #CVI={summary[k_selected]["#CVI"]}'
122 summary[k_selected]["ax_title"] = ax_title
123 finally:
124 print(f"Selected k: {k_selected} | True k: {k_true}")
125
126 # ------------------------------------------------------------------
127 # --------------------- Plot true clustering -----------------------
128 # ------------------------------------------------------------------
129
130 best_clusters = clusterings[k_true]
131
132 # -- Plot true clusters & clusters when assuming k_true clusters ---
133 vi = variation_information(true_clusters, clusterings[k_true])
134 fig = plot_true_best(
135 X, y, best_clusters, n_plots=len(summary) + 2, VI_best=vi
136 )
137
138 # ------------------------------------------------------------------
139 # ----------------------- Summary plot -----------------------------
140 # ------------------------------------------------------------------
141
142 fig_hist = plot_hist_selected(summary)
143 fig_hist.savefig(fig_name + "-histogram.png")
144
145 fig = plot_only_selected(X, summary, fig)
146 fig.suptitle(fig_title)
147 fig.savefig(fig_name + ".png")
148
149# ======================================================================
150# PyCVI on non time-series data
151# ======================================================================
152
153# ------------- KMeans ------------------------
154X, y = load_data("zelnik1", "barton")
155ts_dist = False
156k_max = 10
157
158model_class = KMeans
159model_kw = {}
160scaler = StandardScaler()
161
162fig_title = "Non time-series data with KMeans"
163fig_name = "select-Barton_data_KMeans"
164pipeline(X, y, model_class, model_kw, k_max, scaler, ts_dist, fig_title, fig_name)
165
166# --------- AgglomerativeClustering ----------
167X, y = load_data("zelnik1", "barton")
168ts_dist = False
169k_max = 10
170
171model_class = AgglomerativeClustering
172
173# Custom kwargs for sklearn.cluster.AgglomerativeClustering
174model_kw = {"linkage" : "single"}
175scaler = StandardScaler()
176
177fig_title = "Non time-series data with AgglomerativeClustering-Single"
178fig_name = "select-Barton_data_AgglomerativeClustering_Single"
179
180pipeline(X, y, model_class, model_kw, k_max, scaler, ts_dist, fig_title, fig_name)
181
182# ======================================================================
183# PyCVI on time series data
184# ======================================================================
185
186X, y = load_data("Trace", "UCR")
187
188# ==========================
189# PyCVI using a time series distance
190# ==========================
191
192ts_dist = True
193
194model_class = TimeSeriesKMeans
195
196# Custom kwargs for aeon.clustering.TimeSeriesKMeans
197model_kw = {
198 "distance" : "msm",
199 "distance_params" : {"window": 0.2},
200}
201scaler = StandardScaler()
202
203fig_title = "Time-series data using MSM with TimeSeriesKMeans"
204fig_name = "select-UCR_data_MSM_TimeSeriesKMeans"
205
206pipeline(X, y, model_class, model_kw, k_max, scaler, ts_dist, fig_title, fig_name)
207
208# ==========================
209# PyCVI not using a time series distance
210# ==========================
211
212ts_dist = False
213
214model_class = KMeans
215model_kw = {}
216scaler = StandardScaler()
217fig_title = "Time-series data without MSM with KMeans"
218fig_name = "select-UCR_data_no_MSM_KMeans"
219
220pipeline(X, y, model_class, model_kw, k_max, scaler, ts_dist, fig_title, fig_name)
221
***** Non time-series data with KMeans *****
Clusterings generated in: 0.13s
====== Hartigan_monotonous ======
0 232.06549348253276
1 119.2671791270624
2 117.72802744595317
3 75.64543494463972
4 93.02857075422685
5 57.911763211015206
6 54.883675957104344
7 57.81119713457491
8 57.5078124738331
9 None
Code executed in 0.01 s
Selected k: 1 | True k: 3
====== CalinskiHarabasz_original ======
0 None
1 0.0
2 119.26717912706246
3 141.9350150012302
4 143.70065256939563
5 164.6544092488522
6 168.80458140406105
7 175.68753449069192
8 188.14654839883408
9 203.78502647764276
Code executed in 0.00 s
Selected k: 9 | True k: 3
====== GapStatistic_original ======
0 None
1 -0.004049261254301939
2 -0.16307586692342646
3 -0.2652095140865578
4 -0.4937608855971787
5 -0.4160404121970718
6 -0.43650549334690636
7 -0.3923946574674715
8 -0.42462618347440184
9 -0.3137992381108097
Code executed in 0.12 s
Selected k: 1 | True k: 3
====== Silhouette ======
0 None
1 None
2 0.2985786111836367
3 0.31204659184575273
4 0.29796035253281916
5 0.37742368170829343
6 0.39999596786642316
7 0.41114757004041963
8 0.4265988987929737
9 0.4548108887436638
Code executed in 0.12 s
Selected k: 9 | True k: 3
====== ScoreFunction ======
0 None
1 0.12657698150688346
2 0.0716356542174802
3 0.057765281482714426
4 0.025027522517509615
5 0.03271266781565629
6 0.03361921840147941
7 0.03252362040347312
8 0.029646982088434637
9 0.04735587050461998
Code executed in 0.00 s
Selected k: 1 | True k: 3
====== MaulikBandyopadhyay_absolute ======
0 None
1 0.0
2 0.8408153724037896
3 0.8336217660080479
4 1.0770915621539068
5 1.2565267318050637
6 1.4845414943234108
7 1.2950809632054674
8 1.1989668231359776
9 1.2595302720381796
Code executed in 0.00 s
Selected k: 6 | True k: 3
====== SD ======
0 None
1 None
2 656.39515384398
3 456.61405111314394
4 461.8302545834915
5 357.83952680674724
6 292.98669000567173
7 249.42395627989563
8 225.13998944062234
9 173.02538330529276
Code executed in 0.03 s
Selected k: 9 | True k: 3
====== SDbw ======
0 None
1 None
2 1.6902722644442292
3 2.0174373215564083
4 1.2082481264176257
5 1.1825943379868584
6 0.5585335207414894
7 0.41246869581365275
8 0.3601301521465961
9 0.25986623459802766
Code executed in 0.01 s
Selected k: 9 | True k: 3
====== Dunn ======
0 None
1 None
2 0.015452827825296852
3 0.017890000558072185
4 0.01856746735579822
5 0.02297873516930471
6 0.018908323845384174
7 0.03640373451170917
8 0.03904677943093645
9 0.04535746456065664
Code executed in 0.00 s
Selected k: 9 | True k: 3
====== XB ======
0 None
1 None
2 0.5543016884733878
3 0.37003401314306605
4 0.3918485553976189
5 0.2739331954729799
6 0.2525761345285564
7 0.455297814558528
8 0.3843571866363381
9 0.3207513043550097
Code executed in 0.00 s
Selected k: 6 | True k: 3
====== XB_star ======
0 None
1 None
2 0.579136952440696
3 0.4164786251081707
4 0.6989741771604062
5 0.3981589057890254
6 0.3530011823908151
7 0.7249735927240049
8 0.7244511131185852
9 0.5673298199950779
Code executed in 0.00 s
Selected k: 6 | True k: 3
====== DB ======
0 None
1 None
2 1.4970958405675614
3 1.2092200935052948
4 1.108064975800825
5 0.9902124469766174
6 1.052159884272726
7 1.0810814805947035
8 1.0031680345794394
9 1.0031680345794391
Code executed in 0.00 s
Selected k: 5 | True k: 3
====== Inertia_sum ======
0 524.0762519879294
1 349.0214135130419
2 305.35553213871884
3 268.3294010250791
4 234.3290417501058
5 209.32102705880183
6 193.0362819284009
7 175.96179285721414
8 159.11700926958062
9 147.13245480187476
Code executed in 0.00 s
Selected k: 1 | True k: 3
====== Diameter_max ======
0 6.225889127666499
1 4.737154354950527
2 4.687181441144579
3 3.858736585127345
4 3.900920163638556
5 3.184734629381389
6 2.651140669580718
7 2.54835120455792
8 2.5928271318607923
9 2.2320813145303875
Code executed in 0.00 s
Selected k: 1 | True k: 3
***** Non time-series data with AgglomerativeClustering-Single *****
Clusterings generated in: 0.01s
====== Hartigan_monotonous ======
0 243.17059353383985
1 0.017211966847463733
2 0.011381644034187843
3 34.58290182504763
4 35.42587757523952
5 1.2950951116888347
6 60.33785949064855
7 114.59147910894787
8 1.8539186101937388
9 None
Code executed in 0.00 s
Selected k: 1 | True k: 3
====== CalinskiHarabasz_original ======
0 None
1 0.0
2 0.01721196684745756
3 0.0142681588644381
4 11.538225250696613
5 18.520003238398484
6 15.089892803326249
7 25.17787001256915
8 46.34652110326673
9 40.90394626337436
Code executed in 0.00 s
Selected k: 8 | True k: 3
====== GapStatistic_original ======
0 None
1 -0.006801696816472358
2 -0.47953607482629135
3 -0.965214611191529
4 -1.2820955513063375
5 -1.368922185821857
6 -1.5239873347683948
7 -1.5386281631982723
8 -1.376368821011336
9 -1.4891341789691714
Code executed in 0.13 s
Selected k: 1 | True k: 3
====== Silhouette ======
0 None
1 None
2 0.19510829001256025
3 0.12276877018507622
4 0.2666718402395447
5 0.31348555456323224
6 0.36558953430010227
7 0.3731558417803549
8 0.4027680246588693
9 0.4166374121873863
Code executed in 0.12 s
Selected k: 9 | True k: 3
====== ScoreFunction ======
0 None
1 0.12657698150688346
2 0.004135311875640868
3 0.0032293485050610693
4 0.0029632576876932326
5 0.003264097402863153
6 0.0037227535316397553
7 0.0049664095832882005
8 0.010149481944074723
9 0.011314974675989298
Code executed in 0.00 s
Selected k: 1 | True k: 3
====== MaulikBandyopadhyay_absolute ======
0 None
1 0.0
2 0.00013083550172281476
3 8.475580765301406e-05
4 0.427718738217691
5 0.37675811580288987
6 0.2736495991736414
7 0.3198667973300651
8 0.5148041633787491
9 0.4148452726415676
Code executed in 0.00 s
Selected k: 8 | True k: 3
====== SD ======
0 None
1 None
2 1235.2412717775123
3 895.0734489387124
4 760.3737998020256
5 586.6586545582198
6 480.8898870658816
7 427.8769607892363
8 366.0067509925373
9 327.9051238357357
Code executed in 0.03 s
Selected k: 9 | True k: 3
====== SDbw ======
0 None
1 None
2 2.361153676117582
3 inf
4 inf
5 inf
6 inf
7 inf
8 inf
9 inf
Code executed in 0.01 s
Selected k: 2 | True k: 3
====== Dunn ======
0 None
1 None
2 0.22248894960242496
3 0.09930825342423276
4 0.07694370083375403
5 0.06829859591450839
6 0.06533380025087833
7 0.06397229612167823
8 0.060820685569083446
9 0.06081222025210591
Code executed in 0.00 s
Selected k: 2 | True k: 3
====== XB ======
0 None
1 None
2 3821.6310955892613
3 5646.56635055878
4 3300.5590447734985
5 2945.6227492079197
6 2932.660040393725
7 2430.441999712767
8 1743.7709082799424
9 1732.6941019304872
Code executed in 0.00 s
Selected k: 9 | True k: 3
====== XB_star ======
0 None
1 None
2 9446.229005417188
3 13957.603039842359
4 8989.974686370095
5 8641.081615403013
6 8641.081615403013
7 7751.014168430339
8 5854.809633100443
9 5854.809633100443
Code executed in 0.00 s
Selected k: 8 | True k: 3
====== DB ======
0 None
1 None
2 129.40126293281918
3 125.11207732852509
4 43.39706303619012
5 43.39706303619012
6 43.39706303619011
7 43.39706303619011
8 43.39706303619012
9 43.39706303619011
Code executed in 0.00 s
Selected k: 6 | True k: 3
====== Inertia_sum ======
0 534.4874209327967
1 349.0214135130419
2 349.0095479285938
3 349.0536409924574
4 325.43055668310694
5 303.72575042981157
6 300.60978707111775
7 272.065674157918
8 233.85530390170882
9 231.56485922473567
Code executed in 0.00 s
Selected k: 1 | True k: 3
====== Diameter_max ======
0 6.141355878094843
1 4.737154354950527
2 4.737154354950527
3 4.737154354950527
4 4.737154354950527
5 4.737154354950527
6 4.737154354950527
7 4.737154354950527
8 4.665215171139693
9 4.665215171139693
Code executed in 0.00 s
Selected k: 1 | True k: 3
***** Time-series data using MSM with TimeSeriesKMeans *****
Clusterings generated in: 130.75s
====== Hartigan_monotonous ======
0 44.82395258134479
1 271.13833176062394
2 64.65676360724547
3 64.70935819258743
4 21.923837461931303
5 25.197866217014564
6 19.60202558940761
7 7.499097888910482
8 30.578827195256416
9 None
Code executed in 28.81 s
Selected k: 2 | True k: 4
====== CalinskiHarabasz_original ======
0 None
1 0.0
2 559.4086836804266
3 489.88699135236993
4 480.66915746794183
5 442.23686964653393
6 453.5106657558348
7 432.7520533284743
8 404.81059071795636
9 457.77315649368256
Code executed in 15.94 s
Selected k: 2 | True k: 4
====== GapStatistic_original ======
0 None
1 0.3805844469596007
2 1.7005657384178612
3 2.207908431700133
4 2.7142950513163946
5 2.912449902603896
6 3.1418518136702236
7 3.3207666335186286
8 3.389262659357927
9 3.671637986844013
Code executed in 130.45 s
Selected k: None | True k: 4
====== Silhouette ======
0 None
1 None
2 0.6485114553580815
3 0.5986822875271275
4 0.5162205993003215
5 0.4792789578354061
6 0.4660260179335385
7 0.4619040798337993
8 0.42791144140328896
9 0.4791441927395954
Code executed in 18.74 s
Selected k: 2 | True k: 4
====== ScoreFunction ======
0 None
1 0.0
2 1.0
3 1.0
4 0.0
5 0.0
6 0.0
7 0.0
8 0.0
9 0.0
Code executed in 19.75 s
Selected k: 2 | True k: 4
====== MaulikBandyopadhyay_absolute ======
0 None
1 0.0
2 54381.090895915346
3 50553.90311005585
4 46470.22610230166
5 40262.28566638221
6 39387.4448944914
7 36595.61263376264
8 30799.569837682655
9 29917.290540400587
Code executed in 16.22 s
Selected k: 2 | True k: 4
====== SD ======
0 None
1 None
2 0.05356167024291173
3 0.04309266821745296
4 0.040982526671671
5 0.04290262820935717
6 0.04134623197952923
7 0.04992521867797746
8 0.0713423723442485
9 0.047709254149544106
Code executed in 46.05 s
Selected k: 4 | True k: 4
====== SDbw ======
0 None
1 None
2 0.17442086058270134
3 0.11470220138335113
4 inf
5 inf
6 0.039394196040414484
7 0.030826566035482172
8 inf
9 inf
Code executed in 24.25 s
Selected k: 7 | True k: 4
====== Dunn ======
0 None
1 None
2 0.8235232934630395
3 0.07276372021262471
4 0.11371123757135405
5 0.1025398694350732
6 0.155387968569223
7 0.11144568738232707
8 0.11144568738232707
9 0.18392624209570363
Code executed in 9.12 s
Selected k: 2 | True k: 4
====== XB ======
0 None
1 None
2 0.07729899978682377
3 0.2138826717451771
4 0.19868103064490739
5 0.24156386322283893
6 0.19936715817136083
7 0.28856423774066864
8 0.6207322433159643
9 0.21624362504754469
Code executed in 6.61 s
Selected k: 2 | True k: 4
====== XB_star ======
0 None
1 None
2 0.07895670501519059
3 0.346750593722074
4 0.2579471012509385
5 0.38370082027258046
6 0.3617977055243903
7 0.6227178868262979
8 1.4522173224632717
9 0.39377535468909464
Code executed in 6.42 s
Selected k: 2 | True k: 4
====== DB ======
0 None
1 None
2 0.5555629952382906
3 0.6275447998741295
4 0.9929945087783661
5 0.9929945087783661
6 0.8738830100910718
7 0.8345488343417881
8 1.4287289718871055
9 0.9830092648703032
Code executed in 6.75 s
Selected k: 2 | True k: 4
====== Inertia_sum ======
0 16372.716526290325
1 11756.551067446275
2 5309.999080718087
3 4002.651305572027
4 3221.1681301208646
5 2817.9880794032542
6 2510.31491904984
7 2232.2653130309036
8 2129.099948020224
9 1924.4528813339473
Code executed in 21.73 s
Selected k: 2 | True k: 4
====== Diameter_max ======
0 209.23063247403064
1 281.0189505183936
2 177.08071849410624
3 176.56648114304892
4 112.98473490589328
5 112.98473490589328
6 95.15682062499096
7 95.15682062499096
8 95.15682062499096
9 69.85209878933638
Code executed in 15.75 s
Selected k: 4 | True k: 4
***** Time-series data without MSM with KMeans *****
Clusterings generated in: 0.09s
====== Hartigan_monotonous ======
0 16.44418491910634
1 180.2820962759362
2 53.846852033119156
3 22.394820456074363
4 25.202760282907153
5 21.309513200043543
6 15.277152546441965
7 9.858826622121061
8 12.145653055790293
9 None
Code executed in 0.01 s
Selected k: 2 | True k: 4
====== CalinskiHarabasz_original ======
0 None
1 0.0
2 180.28209627593617
3 166.17448068089334
4 142.93732434587818
5 140.81535014558364
6 141.25368243775628
7 138.3283859855347
8 131.3926152848329
9 130.56805754521872
Code executed in 0.01 s
Selected k: 2 | True k: 4
====== GapStatistic_original ======
0 None
1 0.14959122676002323
2 1.1825464601532047
3 1.6100901607890412
4 1.8029296440498754
5 2.0280252692342273
6 2.21832369843703
7 2.3590765271254925
8 2.4430735311078635
9 2.553055497426036
Code executed in 0.11 s
Selected k: None | True k: 4
====== Silhouette ======
0 None
1 None
2 0.5851724720291331
3 0.5053323519853271
4 0.4602712659960852
5 0.4570190106763704
6 0.41519039685198805
7 0.42845540182332315
8 0.4186536913468557
9 0.42491853239904803
Code executed in 0.05 s
Selected k: 2 | True k: 4
====== ScoreFunction ======
0 None
1 0.0
2 0.0
3 0.0
4 0.0
5 0.0
6 0.0
7 0.0
8 0.0
9 0.0
Code executed in 0.01 s
Selected k: 1 | True k: 4
====== MaulikBandyopadhyay_absolute ======
0 None
1 0.0
2 465.6343632128651
3 378.23916578603587
4 323.65402363440177
5 266.4697539400853
6 227.57932618095361
7 190.3514597162322
8 181.94750398389024
9 158.92918517875125
Code executed in 0.01 s
Selected k: 2 | True k: 4
====== SD ======
0 None
1 None
2 1.529704442763962
3 1.6322356854720357
4 1.3340022170871628
5 1.2712656221929055
6 1.3534362780542557
7 1.4051561538550463
8 1.348660264489562
9 1.3021659181396892
Code executed in 0.08 s
Selected k: 5 | True k: 4
====== SDbw ======
0 None
1 None
2 inf
3 inf
4 inf
5 inf
6 inf
7 inf
8 inf
9 inf
Code executed in 0.12 s
Selected k: None | True k: 4
====== Dunn ======
0 None
1 None
2 0.6502295327816004
3 0.4183330532684955
4 0.05453741885973551
5 0.05453741885973551
6 0.06321374469697073
7 0.07400800378311924
8 0.0938339793992864
9 0.11394106723529379
Code executed in 0.01 s
Selected k: 2 | True k: 4
====== XB ======
0 None
1 None
2 0.133838927267939
3 0.2070968818131891
4 0.5675473082510522
5 0.44755211078152235
6 0.36411970567875485
7 0.31226605225137
8 0.625012238523652
9 0.4658818484527943
Code executed in 0.01 s
Selected k: 2 | True k: 4
====== XB_star ======
0 None
1 None
2 0.23315333559033175
3 0.3264007671262031
4 1.1053632201735628
5 1.1053632201735628
6 0.9130044140189886
7 0.715292887528786
8 1.5867926286758676
9 1.342408899772256
Code executed in 0.01 s
Selected k: 2 | True k: 4
====== DB ======
0 None
1 None
2 0.7011289065432457
3 1.1189101040092817
4 1.1189101040092817
5 1.0398228359696284
6 1.4226602670081683
7 1.069681854739743
8 1.2262026392098047
9 1.069681854739743
Code executed in 0.01 s
Selected k: 2 | True k: 4
====== Inertia_sum ======
0 1550.7100623367241
1 1411.2211210804048
2 766.9830051666322
3 633.3155315412099
4 525.9256968224321
5 463.6934090080416
6 429.2586106174678
7 406.2820152412132
8 367.96526075087877
9 348.3200302183911
Code executed in 0.00 s
Selected k: 2 | True k: 4
====== Diameter_max ======
0 26.52376778327575
1 29.63943217185524
2 26.085661705315456
3 21.104625863172615
4 21.104625863172615
5 21.104625863172615
6 18.207936044532552
7 15.55226140068361
8 15.55226140068361
9 14.509602898389424
Code executed in 0.01 s
Selected k: 3 | True k: 4