Source code for sospcat.spatial

"""
Module to define the spatial based partitioning
"""
from sklearn.cluster import KMeans


[docs]def get_groups( node_locations, nbr_clusters, return_form='membership', random_state=None, **kwargs ): """ Perform k-means clustering on the provided node locations. Parameters ========== node_locations: dict Specify for each node (key) its position (value) in the form of a tuple, `(x, y)`. nbr_clusters: int The number of clusters to find. return_form: str (default='membership') Determines the format of how the social group structure should be returned. Options are: * ``'membership'``: A `dict` returning for each node (key) the group it belongs to (value). * ``'memberlists'``: Dictionary with a list of members (value) for each group (key). random_state : int, RandomState instance, default=None Determines random number generation for centroid initialization. Use an int to make the randomness deterministic. **kwargs All keyword arguments forwarded to :class:`sklearn.cluster.KMeans`. Returns ======= dict Depending on what was chosen for the `return_form` attribute, either the membership dict, i.e.:: { node_id: group_id, ... } or the memberlist dict, i.e.:: { group_id: [node1_id, node2_id, ...], ... } (value) is returned. """ nodes = sorted(node_locations.keys()) positions = [node_locations[n] for n in nodes] membership_predict = KMeans( n_clusters=nbr_clusters, random_state=random_state, **kwargs ).fit_predict(positions) group_membership = { node: membership_predict[i] for i, node in enumerate(nodes) } # note: could use default dict here kmeans_grouping = {i: [] for i in range(nbr_clusters)} for i, memb in enumerate(membership_predict): kmeans_grouping[memb].append(nodes[i]) if return_form == 'membership': membership = [None]*len(nodes) for g, members in kmeans_grouping.items(): for member in members: membership[member] = g return membership return group_membership elif return_form == 'memberlists': return kmeans_grouping else: return None