def reseed_point(X, C, index):
""" Re-initialise the centre of a class if it loses all its members
This should almost never happen. If it does, find the point furthest
from all the other cluster centres and use that. Maybe a bad idea but
a decent first pass
Parameters
----------
X : ndarray
(n, d) array of points
C : ndarray
(k, d) array of cluster centres
index : int >= 0
index between 0..k-1 of the cluster that has lost it's points
Returns
-------
new_point : ndarray
d-dimensional point for replacing the empty cluster centre.
"""
log.info("Reseeding class with no members")
nsplits = max(1, int(X.shape[0]/distance_partition_size))
splits = np.array_split(X, nsplits)
empty_index = np.ones(C.shape[0], dtype=bool)
empty_index[index] = False
local_candidate = None
local_cost = 1e23
for x_i in splits:
D2_x = scipy.spatial.distance.cdist(x_i, C, metric='sqeuclidean')
costs = np.sum(D2_x[:, empty_index], axis=1)
potential_idx = np.argmax(costs)
potential_cost = costs[potential_idx]
if potential_cost < local_cost:
local_candidate = x_i[potential_idx]
local_cost = potential_cost
best_pernode = mpiops.comm.allgather(local_cost)
best_node = np.argmax(best_pernode)
new_point = mpiops.comm.bcast(local_candidate, root=best_node)
return new_point
评论列表
文章目录