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 comprises a set of cluster centroids of a corresponding set of clusters, wherein each cluster of the set of clusters includes a corresponding subset of the set of data points, each cluster of the set of clusters being defined by a respective cluster boundary, the constructing comprising: identifying neighboring data points located within a threshold distance from at least one of a cluster boundary or a data point included in a subset of the set of data points included in a cluster of the set of clusters; constructing a cluster closure for each cluster of the set of clusters to create a corresponding set of cluster closures, each cluster closure of the set of cluster closures including a cluster of the set of clusters and an area exterior a respective cluster boundary of the cluster, the area included in each cluster closure and exterior the respective cluster boundary of the respective cluster being within the threshold distance; and iteratively assigning at least one neighboring data point of the neighboring data points to one cluster of the set of clusters, the assigning comprising: identifying a subset of cluster closures from the set of cluster closures whose areas exterior their respective cluster boundaries include the at least one neighboring data point, wherein the subset of cluster closures includes one cluster closure corresponding to the one cluster, and wherein the subset of cluster closures includes at least two cluster closures and less than all of the set of cluster closures; based at least in part on identifying the subset of cluster closures, calculating distances between the at least one neighboring data point and cluster centroids of each cluster corresponding to the subset of cluster closures; based at least in part on a comparison of the distances between the at least one neighboring data point and the cluster centroids of each of the subset of cluster closures, assigning the at least one neighboring data point included in the subset of cluster closures to the one cluster; and updating a corresponding subset of data points of the one cluster to include the at least one neighboring data point and calculating an updated cluster centroid for the one cluster based at least in part on the updated corresponding subset of data points.