Cosine k-Means Clustering
Problem statement
Implement kMeans(data, k, centroids, iterations) from scratch. The floating-point matrix data contains one data point per row. The matrix centroids supplies the initial center of each of the k clusters.
Use cosine distance to assign points, and arithmetic means to update centers. Return an integer array with the cluster label for each data point, in input order.
Clustering rounds
- Using the centers from the beginning of the round, assign every point to its nearest center by cosine distance.
- If the complete label array equals the previous round's label array, stop.
- For each nonempty cluster, replace its center by the coordinate-wise arithmetic mean of its assigned original points. All center updates take effect together.
- Repeat until the assignment is stable or
iterationsrounds have been performed.
Deterministic practice rules
- Cluster labels are the initial centroid indices
0throughk - 1; never reorder the centers. - For nonzero vectors
xandc, cosine similarity issum(x[j] * c[j]) / (sqrt(sum(x[j]^2)) * sqrt(sum(c[j]^2))), and cosine distance is1 - similarity. - Two zero vectors have similarity
1. If exactly one vector is zero, their similarity is0. - Let
sbe the maximum similarity to any current center. Choose the smallest cluster index whose similarity is at leasts - 10^-12. Use double-precision arithmetic. - If a cluster receives no points, retain its previous center.
- Return the labels from the last assignment phase. Reaching the iteration limit does not trigger an extra assignment after the last mean update.
- Average the original vectors, without normalizing them first.
The original assessment uses a partially completed skeleton. In this callable practice version, implement the same assignment and mean-update behavior inside kMeans; do not change the function signature.
Function
kMeans(data: double[][], k: int, centroids: double[][], iterations: int) → int[]Examples
Example 1
data = [[2.0,0.0],[3.0,0.0],[0.0,2.0],[0.0,4.0]]k = 2centroids = [[1.0,0.0],[0.0,1.0]]iterations = 5return = [0,0,1,1]The first two points have cosine similarity 1 to cluster 0, and the last two to cluster 1. Their new centers are [2.5,0.0] and [0.0,3.0]. The next assignment is unchanged.
Example 2
data = [[1.0,0.0],[0.0,1.0],[0.0,0.0]]k = 2centroids = [[100.0,0.0],[0.0,1.0]]iterations = 1return = [0,1,0]The first point chooses cluster 0 despite its center being much farther away in Euclidean distance. The second chooses 1. The zero point has similarity 0 to both nonzero centers, so it chooses the smaller label 0.
Constraints
1 <= data.length <= 100.- Every point and initial center has the same dimension
d, with1 <= d <= 20. 1 <= k <= min(20, data.length)andcentroids.length == k.1 <= iterations <= 100.- Coordinates are finite floating-point values between
-10000and10000, with at most six digits after the decimal point. - Duplicate points, duplicate centers, zero vectors, and empty clusters are allowed.