Returns a Cluster containing k items (vectors or clusters with nested items). With k=1, the top-level cluster contains a single cluster.
(vectors, k=1, iterations=1000, distance=COSINE, **kwargs)
| 1608 | yield i; i=f(i) |
| 1609 | |
| 1610 | def hierarchical(vectors, k=1, iterations=1000, distance=COSINE, **kwargs): |
| 1611 | """ Returns a Cluster containing k items (vectors or clusters with nested items). |
| 1612 | With k=1, the top-level cluster contains a single cluster. |
| 1613 | """ |
| 1614 | id = sequence() |
| 1615 | features = kwargs.get("features", _features(vectors)) |
| 1616 | clusters = Cluster((v for v in shuffled(vectors))) |
| 1617 | centroids = [(id.next(), v) for v in clusters] |
| 1618 | map = {} |
| 1619 | for _ in range(iterations): |
| 1620 | if len(clusters) <= max(k, 1): |
| 1621 | break |
| 1622 | nearest, d0 = None, None |
| 1623 | for i, (id1, v1) in enumerate(centroids): |
| 1624 | for j, (id2, v2) in enumerate(centroids[i+1:]): |
| 1625 | # Cache the distance calculations between vectors. |
| 1626 | # This is identical to DistanceMap.distance(), |
| 1627 | # but it is faster in the inner loop to use it directly. |
| 1628 | try: |
| 1629 | d = map[(id1, id2)] |
| 1630 | except KeyError: |
| 1631 | d = map[(id1, id2)] = _distance(v1, v2, method=distance) |
| 1632 | if d0 is None or d < d0: |
| 1633 | nearest, d0 = (i, j+i+1), d |
| 1634 | # Pairs of nearest clusters are merged as we move up the hierarchy: |
| 1635 | i, j = nearest |
| 1636 | merged = Cluster((clusters[i], clusters[j])) |
| 1637 | clusters.pop(j) |
| 1638 | clusters.pop(i) |
| 1639 | clusters.append(merged) |
| 1640 | # Cache the center of the new cluster. |
| 1641 | v = centroid(merged.flatten(), features) |
| 1642 | centroids.pop(j) |
| 1643 | centroids.pop(i) |
| 1644 | centroids.append((id.next(), v)) |
| 1645 | return clusters |
| 1646 | |
| 1647 | #v1 = Vector(wings=0, beak=0, claws=1, paws=1, fur=1) # cat |
| 1648 | #v2 = Vector(wings=0, beak=0, claws=0, paws=1, fur=1) # dog |
no test coverage detected
searching dependent graphs…