Skip to content

Commit 3198c10

Browse files
committed
Fix NCO clustering bounds for small asset universes
1 parent d622421 commit 3198c10

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

helper_monkey.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,14 +498,24 @@ def clusterKMeansBase(corr0, maxNumClusters=10, n_init=10):
498498
corr0 = DataFrame(corr0)
499499
x, silh = ((1-corr0.fillna(0))/2.)**.5, Series()
500500
x_values = x.to_numpy()
501+
max_k = min(maxNumClusters, x_values.shape[0] - 1)
502+
if max_k < 2:
503+
raise ValueError('Need at least 3 assets to form clusters.')
504+
505+
kmeans = None
501506
for init in range(n_init):
502-
for i in range(2, maxNumClusters+1):
507+
for i in range(2, max_k + 1):
503508
kmeans_ = KMeans(n_clusters=i, n_init=10, random_state=init)
504509
kmeans_labels = kmeans_.fit_predict(x_values)
505510
silh_ = silhouette_samples(x_values, kmeans_labels)
506511
stat = (silh_.mean()/silh_.std(), silh.mean()/silh.std())
507512
if np.isnan(stat[1]) or stat[0]>stat[1]:
508513
silh, kmeans = silh_, kmeans_
514+
515+
if kmeans is None:
516+
kmeans = KMeans(n_clusters=2, n_init=10, random_state=0).fit(x_values)
517+
silh = silhouette_samples(x_values, kmeans.labels_)
518+
509519
newIdx = np.argsort(kmeans.labels_)
510520
corr1 = corr0.iloc[newIdx]
511521
corr1 = corr1.iloc[:, newIdx]

0 commit comments

Comments
 (0)