Skip to content

Commit 3b5057f

Browse files
committed
[Issue #30] Allow using a custom post_eigen_cluster_function in the API
1 parent 2a29ffc commit 3b5057f

File tree

3 files changed

+58
-29
lines changed

3 files changed

+58
-29
lines changed

docs/spectral_clusterer.html

Lines changed: 47 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ <h1 class="title">Module <code>spectralcluster.spectral_clusterer</code></h1>
5757
max_iter=300,
5858
constraint_options=None,
5959
eigengap_type=EigenGapType.Ratio,
60-
affinity_function=utils.compute_affinity_matrix):
60+
affinity_function=utils.compute_affinity_matrix,
61+
post_eigen_cluster_function=custom_distance_kmeans.run_kmeans):
6162
&#34;&#34;&#34;Constructor of the clusterer.
6263

6364
Args:
@@ -83,6 +84,9 @@ <h1 class="title">Module <code>spectralcluster.spectral_clusterer</code></h1>
8384
eigengap_type: the type of the eigengap computation
8485
affinity_function: a function to compute the affinity matrix from the
8586
embeddings. This defaults to (cos(x,y)+1)/2
87+
post_eigen_cluster_function: a function to cluster the spectral embeddings
88+
after the eigenvalue computations. This function must have the same
89+
signature as custom_distance_kmeans.run_kmeans
8690
&#34;&#34;&#34;
8791
self.min_clusters = min_clusters
8892
self.max_clusters = max_clusters
@@ -99,6 +103,7 @@ <h1 class="title">Module <code>spectralcluster.spectral_clusterer</code></h1>
99103
self.constraint_options = constraint_options
100104
self.eigengap_type = eigengap_type
101105
self.affinity_function = affinity_function
106+
self.post_eigen_cluster_function = post_eigen_cluster_function
102107

103108
def _compute_eigenvectors_ncluster(self, affinity, constraint_matrix=None):
104109
&#34;&#34;&#34;Perform eigen decomposition and estiamte the number of clusters.
@@ -118,12 +123,6 @@ <h1 class="title">Module <code>spectralcluster.spectral_clusterer</code></h1>
118123
n_clusters: number of clusters as an integer
119124
max_delta_norm: normalized maximum eigen gap
120125
&#34;&#34;&#34;
121-
if (self.constraint_options and
122-
self.constraint_options.apply_before_refinement):
123-
# Perform the constraint operation before refinement
124-
affinity = self.constraint_options.constraint_operator.adjust_affinity(
125-
affinity, constraint_matrix)
126-
127126
# Perform refinement operations on the affinity matrix.
128127
for refinement_name in self.refinement_options.refinement_sequence:
129128
refinement_operator = self.refinement_options.get_refinement_operator(
@@ -185,6 +184,12 @@ <h1 class="title">Module <code>spectralcluster.spectral_clusterer</code></h1>
185184
# Compute affinity matrix.
186185
affinity = self.affinity_function(embeddings)
187186

187+
if (self.constraint_options and
188+
self.constraint_options.apply_before_refinement):
189+
# Perform the constraint operation before refinement
190+
affinity = self.constraint_options.constraint_operator.adjust_affinity(
191+
affinity, constraint_matrix)
192+
188193
if self.autotune:
189194
# Use Auto-tuning method to find a good p_percentile.
190195
if (RefinementName.RowWiseThreshold
@@ -220,9 +225,10 @@ <h1 class="title">Module <code>spectralcluster.spectral_clusterer</code></h1>
220225
spectral_embeddings = spectral_embeddings / np.reshape(
221226
rows_norm, (spectral_embeddings.shape[0], 1))
222227

223-
# Run K-means on spectral embeddings.
224-
labels = custom_distance_kmeans.run_kmeans(
225-
spectral_embeddings,
228+
# Run clustering algorithm on spectral embeddings. This defaults
229+
# to customized K-means.
230+
labels = self.post_eigen_cluster_function(
231+
spectral_embeddings=spectral_embeddings,
226232
n_clusters=n_clusters,
227233
custom_dist=self.custom_dist,
228234
max_iter=self.max_iter)
@@ -240,7 +246,7 @@ <h2 class="section-title" id="header-classes">Classes</h2>
240246
<dl>
241247
<dt id="spectralcluster.spectral_clusterer.SpectralClusterer"><code class="flex name class">
242248
<span>class <span class="ident">SpectralClusterer</span></span>
243-
<span>(</span><span>min_clusters=None, max_clusters=None, refinement_options=None, autotune=None, laplacian_type=None, stop_eigenvalue=0.01, row_wise_renorm=False, custom_dist='cosine', max_iter=300, constraint_options=None, eigengap_type=EigenGapType.Ratio, affinity_function=&lt;function compute_affinity_matrix&gt;)</span>
249+
<span>(</span><span>min_clusters=None, max_clusters=None, refinement_options=None, autotune=None, laplacian_type=None, stop_eigenvalue=0.01, row_wise_renorm=False, custom_dist='cosine', max_iter=300, constraint_options=None, eigengap_type=EigenGapType.Ratio, affinity_function=&lt;function compute_affinity_matrix&gt;, post_eigen_cluster_function=&lt;function run_kmeans&gt;)</span>
244250
</code></dt>
245251
<dd>
246252
<div class="desc"><p>Spectral clustering class.</p>
@@ -281,6 +287,10 @@ <h2 id="args">Args</h2>
281287
<dt><strong><code>affinity_function</code></strong></dt>
282288
<dd>a function to compute the affinity matrix from the
283289
embeddings. This defaults to (cos(x,y)+1)/2</dd>
290+
<dt><strong><code>post_eigen_cluster_function</code></strong></dt>
291+
<dd>a function to cluster the spectral embeddings
292+
after the eigenvalue computations. This function must have the same
293+
signature as custom_distance_kmeans.run_kmeans</dd>
284294
</dl></div>
285295
<details class="source">
286296
<summary>
@@ -301,7 +311,8 @@ <h2 id="args">Args</h2>
301311
max_iter=300,
302312
constraint_options=None,
303313
eigengap_type=EigenGapType.Ratio,
304-
affinity_function=utils.compute_affinity_matrix):
314+
affinity_function=utils.compute_affinity_matrix,
315+
post_eigen_cluster_function=custom_distance_kmeans.run_kmeans):
305316
&#34;&#34;&#34;Constructor of the clusterer.
306317

307318
Args:
@@ -327,6 +338,9 @@ <h2 id="args">Args</h2>
327338
eigengap_type: the type of the eigengap computation
328339
affinity_function: a function to compute the affinity matrix from the
329340
embeddings. This defaults to (cos(x,y)+1)/2
341+
post_eigen_cluster_function: a function to cluster the spectral embeddings
342+
after the eigenvalue computations. This function must have the same
343+
signature as custom_distance_kmeans.run_kmeans
330344
&#34;&#34;&#34;
331345
self.min_clusters = min_clusters
332346
self.max_clusters = max_clusters
@@ -343,6 +357,7 @@ <h2 id="args">Args</h2>
343357
self.constraint_options = constraint_options
344358
self.eigengap_type = eigengap_type
345359
self.affinity_function = affinity_function
360+
self.post_eigen_cluster_function = post_eigen_cluster_function
346361

347362
def _compute_eigenvectors_ncluster(self, affinity, constraint_matrix=None):
348363
&#34;&#34;&#34;Perform eigen decomposition and estiamte the number of clusters.
@@ -362,12 +377,6 @@ <h2 id="args">Args</h2>
362377
n_clusters: number of clusters as an integer
363378
max_delta_norm: normalized maximum eigen gap
364379
&#34;&#34;&#34;
365-
if (self.constraint_options and
366-
self.constraint_options.apply_before_refinement):
367-
# Perform the constraint operation before refinement
368-
affinity = self.constraint_options.constraint_operator.adjust_affinity(
369-
affinity, constraint_matrix)
370-
371380
# Perform refinement operations on the affinity matrix.
372381
for refinement_name in self.refinement_options.refinement_sequence:
373382
refinement_operator = self.refinement_options.get_refinement_operator(
@@ -429,6 +438,12 @@ <h2 id="args">Args</h2>
429438
# Compute affinity matrix.
430439
affinity = self.affinity_function(embeddings)
431440

441+
if (self.constraint_options and
442+
self.constraint_options.apply_before_refinement):
443+
# Perform the constraint operation before refinement
444+
affinity = self.constraint_options.constraint_operator.adjust_affinity(
445+
affinity, constraint_matrix)
446+
432447
if self.autotune:
433448
# Use Auto-tuning method to find a good p_percentile.
434449
if (RefinementName.RowWiseThreshold
@@ -464,9 +479,10 @@ <h2 id="args">Args</h2>
464479
spectral_embeddings = spectral_embeddings / np.reshape(
465480
rows_norm, (spectral_embeddings.shape[0], 1))
466481

467-
# Run K-means on spectral embeddings.
468-
labels = custom_distance_kmeans.run_kmeans(
469-
spectral_embeddings,
482+
# Run clustering algorithm on spectral embeddings. This defaults
483+
# to customized K-means.
484+
labels = self.post_eigen_cluster_function(
485+
spectral_embeddings=spectral_embeddings,
470486
n_clusters=n_clusters,
471487
custom_dist=self.custom_dist,
472488
max_iter=self.max_iter)
@@ -530,6 +546,12 @@ <h2 id="raises">Raises</h2>
530546
# Compute affinity matrix.
531547
affinity = self.affinity_function(embeddings)
532548

549+
if (self.constraint_options and
550+
self.constraint_options.apply_before_refinement):
551+
# Perform the constraint operation before refinement
552+
affinity = self.constraint_options.constraint_operator.adjust_affinity(
553+
affinity, constraint_matrix)
554+
533555
if self.autotune:
534556
# Use Auto-tuning method to find a good p_percentile.
535557
if (RefinementName.RowWiseThreshold
@@ -565,9 +587,10 @@ <h2 id="raises">Raises</h2>
565587
spectral_embeddings = spectral_embeddings / np.reshape(
566588
rows_norm, (spectral_embeddings.shape[0], 1))
567589

568-
# Run K-means on spectral embeddings.
569-
labels = custom_distance_kmeans.run_kmeans(
570-
spectral_embeddings,
590+
# Run clustering algorithm on spectral embeddings. This defaults
591+
# to customized K-means.
592+
labels = self.post_eigen_cluster_function(
593+
spectral_embeddings=spectral_embeddings,
571594
n_clusters=n_clusters,
572595
custom_dist=self.custom_dist,
573596
max_iter=self.max_iter)

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import setuptools
44

5-
VERSION = "0.2.3"
5+
VERSION = "0.2.4"
66

77
with open("README.md", "r") as file_object:
88
LONG_DESCRIPTION = file_object.read()

spectralcluster/spectral_clusterer.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ def __init__(self,
2828
max_iter=300,
2929
constraint_options=None,
3030
eigengap_type=EigenGapType.Ratio,
31-
affinity_function=utils.compute_affinity_matrix):
31+
affinity_function=utils.compute_affinity_matrix,
32+
post_eigen_cluster_function=custom_distance_kmeans.run_kmeans):
3233
"""Constructor of the clusterer.
3334
3435
Args:
@@ -54,6 +55,9 @@ def __init__(self,
5455
eigengap_type: the type of the eigengap computation
5556
affinity_function: a function to compute the affinity matrix from the
5657
embeddings. This defaults to (cos(x,y)+1)/2
58+
post_eigen_cluster_function: a function to cluster the spectral embeddings
59+
after the eigenvalue computations. This function must have the same
60+
signature as custom_distance_kmeans.run_kmeans
5761
"""
5862
self.min_clusters = min_clusters
5963
self.max_clusters = max_clusters
@@ -70,6 +74,7 @@ def __init__(self,
7074
self.constraint_options = constraint_options
7175
self.eigengap_type = eigengap_type
7276
self.affinity_function = affinity_function
77+
self.post_eigen_cluster_function = post_eigen_cluster_function
7378

7479
def _compute_eigenvectors_ncluster(self, affinity, constraint_matrix=None):
7580
"""Perform eigen decomposition and estiamte the number of clusters.
@@ -191,9 +196,10 @@ def p_percentile_to_ratio(p_percentile):
191196
spectral_embeddings = spectral_embeddings / np.reshape(
192197
rows_norm, (spectral_embeddings.shape[0], 1))
193198

194-
# Run K-means on spectral embeddings.
195-
labels = custom_distance_kmeans.run_kmeans(
196-
spectral_embeddings,
199+
# Run clustering algorithm on spectral embeddings. This defaults
200+
# to customized K-means.
201+
labels = self.post_eigen_cluster_function(
202+
spectral_embeddings=spectral_embeddings,
197203
n_clusters=n_clusters,
198204
custom_dist=self.custom_dist,
199205
max_iter=self.max_iter)

0 commit comments

Comments
 (0)