1. A method implemented at least partially by a processor, the method comprising: constructing a codebook of a set of data points, wherein the codebook is comprised of a set of cluster centroids, C={c 1 , c 2 , c 3 ,. .. c k }, of a corresponding set of clusters, G={G 1 , G 2 , G 3 ,. .. G k }, wherein each cluster is comprised by a subset of data points, by; identifying neighboring data points for each data point of the set of data points; and clustering the data points of the set of data points by iteratively: constructing a cluster closure, G j , for each cluster, G j , of the set of clusters, G={G 1 , G 2 , G 3 ,. .. G k }, based at least on the neighboring data points, wherein a set of cluster closures G ={ G 1 , G 2 , G 3 ,. .. G k } corresponds to the set of clusters, G={G 1 , G 2 , G 3 ,. .. G k }, assigning a given data point to a given cluster based at least in part on a subset of the set of cluster closures, and for each cluster of the set of clusters, updating data points comprising a cluster and calculating an updated cluster centroid for the cluster based at least in part on the updated data points.