6
6
7
7
Authors: Shane Grigsby <refuge@rocktalus.com>
8
8
Amy X. Zhang <axz@mit.edu>
9
+ Erich Schubert <erich@debian.org>
9
10
License: BSD 3 clause
10
11
"""
11
12
@@ -319,6 +320,10 @@ class OPTICS(BaseEstimator, ClusterMixin):
319
320
order. Points which will never be core have a distance of inf. Use
320
321
``clust.core_distances_[clust.ordering_]`` to access in cluster order.
3
8000
21
322
323
+ predecessor_ : array, shape (n_samples,)
324
+ Point that a sample was reached from.
325
+ Seed points have a predecessor of -1.
326
+
322
327
See also
323
328
--------
324
329
@@ -331,6 +336,10 @@ class OPTICS(BaseEstimator, ClusterMixin):
331
336
Ankerst, Mihael, Markus M. Breunig, Hans-Peter Kriegel, and Jörg Sander.
332
337
"OPTICS: ordering points to identify the clustering structure." ACM SIGMOD
333
338
Record 28, no. 2 (1999): 49-60.
339
+
340
+ Schubert, Erich, Michael Gertz.
341
+ "Improving the Cluster Structure Extracted from OPTICS Plots." Proc. of
342
+ the Conference "Lernen, Wissen, Daten, Analysen" (LWDA) (2018): 318-329.
334
343
"""
335
344
336
345
def __init__ (self , min_samples = 5 , max_eps = np .inf , metric = 'euclidean' ,
@@ -398,6 +407,8 @@ def fit(self, X, y=None):
398
407
# Start all points as 'unprocessed' ##
399
408
self .reachability_ = np .empty (n_samples )
400
409
self .reachability_ .fill (np .inf )
410
+ self .predecessor_ = np .empty (n_samples , dtype = int )
411
+ self .predecessor_ .fill (- 1 )
401
412
# Start all points as noise ##
402
413
self .labels_ = np .full (n_samples , - 1 , dtype = int )
403
414
@@ -501,8 +512,9 @@ def _set_reach_dist(self, point_index, processed, X, nbrs):
501
512
self .metric , n_jobs = None ).ravel ()
502
513
503
514
rdists = np .maximum (dists , self .core_distances_ [point_index ])
504
- new_reach = np .minimum (np .take (self .reachability_ , unproc ), rdists )
505
- self .reachability_ [unproc ] = new_reach
515
+ improved = np .where (rdists < np .take (self .reachability_ , unproc ))
516
+ self .reachability_ [unproc [improved ]] = rdists [improved ]
517
+ self .predecessor_ [unproc [improved ]] = point_index
506
518
507
519
# Define return order based on reachability distance
508
520
return (unproc [quick_scan (np .take (self .reachability_ , unproc ),
0 commit comments