MCPcopy Index your code
hub / github.com/clips/pattern / k_means

Function k_means

pattern/vector/__init__.py:1462–1510  ·  view source on GitHub ↗

Returns a list of k clusters, where each cluster is a list of vectors (Lloyd's algorithm). Vectors are assigned to k random centers using a distance metric (EUCLIDEAN, COSINE, ...). Since the initial centers are chosen randomly (by default, seed=RANDOM), there is no guarante

(vectors, k=None, iterations=10, distance=COSINE, seed=RANDOM, **kwargs)

Source from the content-addressed store, hash-verified

1460RANDOM, KMPP = "random", "kmeans++"
1461
1462def k_means(vectors, k=None, iterations=10, distance=COSINE, seed=RANDOM, **kwargs):
1463 """ Returns a list of k clusters, where each cluster is a list of vectors (Lloyd's algorithm).
1464 Vectors are assigned to k random centers using a distance metric (EUCLIDEAN, COSINE, ...).
1465 Since the initial centers are chosen randomly (by default, seed=RANDOM),
1466 there is no guarantee of convergence or of finding an optimal solution.
1467 A more efficient way is to use seed=KMPP (k-means++ initialization algorithm).
1468 """
1469 features = kwargs.get("features") or _features(vectors)
1470 if k is None:
1471 k = sqrt(len(vectors) / 2)
1472 if k < 2:
1473 return [[v for v in vectors]]
1474 if seed == KMPP:
1475 clusters = kmpp(vectors, k, distance)
1476 else:
1477 clusters = [[] for i in xrange(int(k))]
1478 for i, v in enumerate(sorted(vectors, key=lambda x: random())):
1479 # Randomly partition the vectors across k clusters.
1480 clusters[i % int(k)].append(v)
1481 # Cache the distance calculations between vectors (up to 4x faster).
1482 map = DistanceMap(method=distance); distance = map.distance
1483 converged = False
1484 while not converged and iterations > 0 and k > 0:
1485 # Calculate the center of each cluster.
1486 centroids = [centroid(cluster, features) for cluster in clusters]
1487 # Triangle inequality: one side is shorter than the sum of the two other sides.
1488 # We can exploit this to avoid costly distance() calls (up to 3x faster).
1489 p = 0.5 * kwargs.get("p", 0.8) # "Relaxed" triangle inequality (cosine distance is a semimetric) 0.25-0.5.
1490 D = {}
1491 for i in range(len(centroids)):
1492 for j in range(i, len(centroids)): # center1–center2 < center1–vector + vector–center2 ?
1493 D[(i,j)] = D[(j,i)] = p * distance(centroids[i], centroids[j])
1494 # For every vector in every cluster,
1495 # check if it is nearer to the center of another cluster.
1496 # If so, assign it. When visualized, this produces a Voronoi diagram.
1497 converged = True
1498 for i in xrange(len(clusters)):
1499 for v in clusters[i]:
1500 nearest, d1 = i, distance(v, centroids[i])
1501 for j in xrange(len(clusters)):
1502 if D[(i,j)] < d1: # Triangle inequality (Elkan, 2003).
1503 d2 = distance(v, centroids[j])
1504 if d2 < d1:
1505 nearest = j
1506 if nearest != i: # Other cluster is nearer.
1507 clusters[nearest].append(clusters[i].pop(clusters[i].index(v)))
1508 converged = False
1509 iterations -= 1; #print iterations
1510 return clusters
1511
1512kmeans = k_means
1513

Callers 2

clusterMethod · 0.85
clusterFunction · 0.85

Calls 10

lenFunction · 0.85
kmppFunction · 0.85
randomFunction · 0.85
DistanceMapClass · 0.85
centroidFunction · 0.85
distanceFunction · 0.85
getMethod · 0.45
appendMethod · 0.45
popMethod · 0.45
indexMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…