15
15
16
16
import numpy as np
17
17
import scipy .sparse as sp
18
+ from threadpoolctl import threadpool_limits
18
19
19
20
from ..base import BaseEstimator , ClusterMixin , TransformerMixin
20
21
from ..metrics .pairwise import euclidean_distances
@@ -431,15 +432,16 @@ def _kmeans_single_elkan(X, sample_weight, n_clusters, max_iter=300,
431
432
labels , upper_bounds , lower_bounds )
432
433
433
434
for i in range (max_iter ):
434
- elkan_iter (X , sample_weight , centers , centers_new , weight_in_clusters ,
435
- center_half_distances , distance_next_center , upper_bounds ,
436
- lower_bounds , labels , center_shift , n_threads )
435
+ elkan_iter (X , sample_weight , centers , centers_new ,
436
+ weight_in_clusters , center_half_distances ,
437
+ distance_next_center , upper_bounds , lower_bounds ,
438
+ labels , center_shift , n_threads )
437
439
438
440
# compute new pairwise distances between centers and closest other
439
441
# center of each center for next iterations
440
442
center_half_distances = euclidean_distances (centers_new ) / 2
441
- distance_next_center = np .partition (np . asarray ( center_half_distances ),
442
- kth = 1 , axis = 0 )[1 ]
443
+ distance_next_center = np .partition (
444
+ np . asarray ( center_half_distances ), kth = 1 , axis = 0 )[1 ]
443
445
444
446
if verbose :
445
447
inertia = _inertia (X , sample_weight , centers , labels )
@@ -458,9 +460,9 @@ def _kmeans_single_elkan(X, sample_weight, n_clusters, max_iter=300,
458
460
if center_shift_tot > 0 :
459
461
# rerun E-step so that predicted labels match cluster centers
460
462
elkan_iter (X , sample_weight , centers , centers , weight_in_clusters ,
461
- center_half_distances , distance_next_center , upper_bounds ,
462
- lower_bounds , labels , center_shift , n_threads ,
463
- update_centers = False )
463
+ center_half_distances , distance_next_center ,
464
+ upper_bounds , lower_bounds , labels , center_shift ,
465
+ n_threads , update_centers = False )
464
466
465
467
inertia = _inertia (X , sample_weight , centers , labels )
466
468
@@ -564,29 +566,32 @@ def _kmeans_single_lloyd(X, sample_weight, n_clusters, max_iter=300,
564
566
lloyd_iter = lloyd_iter_chunked_dense
565
567
_inertia = _inertia_dense
566
568
567
- for i in range (max_iter ):
568
- lloyd_iter (X , sample_weight , x_squared_norms , centers , centers_new ,
569
- weight_in_clusters , labels , center_shift , n_threads )
570
-
571
- if verbose :
572
- inertia = _inertia (X , sample_weight , centers , labels )
573
- print ("Iteration {0}, inertia {1}" .format (i , inertia ))
569
+ # Threadpoolctl context to limit the number of threads in second level of
570
+ # nested parallelism (i.e. BLAS) to avoid oversubsciption.
571
+ with threadpool_limits (limits = 1 , user_api = "blas" ):
572
+ for i in range (max_iter ):
573
+ lloyd_iter (X , sample_weight , x_squared_norms , centers , centers_new ,
574
+ weight_in_clusters , labels , center_shift , n_threads )
574
575
575
- center_shift_tot = (center_shift ** 2 ).sum ()
576
- if center_shift_tot <= tol :
577
576
if verbose :
578
- print ("Converged at iteration {0}: "
579
- "center shift {1} within tolerance {2}"
580
- .format (i , center_shift_tot , tol ))
581
- break
577
+ inertia = _inertia (X , sample_weight , centers , labels )
578
+ print ("Iteration {0}, inertia {1}" .format (i , inertia ))
579
+
580
+ center_shift_tot = (center_shift ** 2 ).sum ()
581
+ if center_shift_tot <= tol :
582
+ if verbose :
583
+ print ("Converged at iteration {0}: "
584
+ "center shift {1} within tolerance {2}"
585
+ .format (i , center_shift_tot , tol ))
586
+ break
582
587
583
- centers , centers_new = centers_new , centers
588
+ centers , centers_new = centers_new , centers
584
589
585
- if center_shift_tot > 0 :
586
- # rerun E-step so that predicted labels match cluster centers
587
- lloyd_iter (X , sample_weight , x_squared_norms , centers , centers ,
588
- weight_in_clusters , labels , center_shift , n_threads ,
589
- update_centers = False )
590
+ if center_shift_tot > 0 :
591
+ # rerun E-step so that predicted labels match cluster centers
592
+ lloyd_iter (X , sample_weight , x_squared_norms , centers , centers ,
593
+ weight_in_clusters , labels , center_shift , n_threads ,
594
+ update_centers = False )
590
595
591
596
inertia = _inertia (X , sample_weight , centers , labels )
592
597
0 commit comments