-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathspectral-clustering.py
More file actions
26 lines (21 loc) 路 874 Bytes
/
Copy pathspectral-clustering.py
File metadata and controls
26 lines (21 loc) 路 874 Bytes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import numpy as np
def spectral_clustering(X, k=2):
from scipy.spatial.distance import pdist, squareform
from scipy.linalg import eigh
W = np.exp(-squareform(pdist(X)) ** 2 / (2 * np.median(pdist(X)) ** 2))
np.fill_diagonal(W, 0)
D = np.diag(W.sum(axis=1))
L = D - W
eigvals, eigvecs = eigh(L, D)
H = eigvecs[:, :k]
H /= np.linalg.norm(H, axis=1, keepdims=True)
def kmeans(U, k, max_iters=100):
centroids = U[np.random.choice(len(U), k, replace=False)]
for _ in range(max_iters):
labels = np.argmin(np.linalg.norm(U[:, None] - centroids, axis=2), axis=1)
new_centroids = np.array([U[labels == j].mean(axis=0) for j in range(k)])
if np.allclose(centroids, new_centroids):
break
centroids = new_centroids
return labels
return kmeans(H, k)