FastPrepCosine k-Means Clustering

Cosine k-Means Clustering

TikTok logoTikTok● MediumINTERNOA
Learn

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

  1. Using the centers from the beginning of the round, assign every point to its nearest center by cosine distance.
  2. If the complete label array equals the previous round's label array, stop.
  3. For each nonempty cluster, replace its center by the coordinate-wise arithmetic mean of its assigned original points. All center updates take effect together.
  4. Repeat until the assignment is stable or iterations rounds have been performed.

Deterministic practice rules

  • Cluster labels are the initial centroid indices 0 through k - 1; never reorder the centers.
  • For nonzero vectors x and c, cosine similarity is sum(x[j] * c[j]) / (sqrt(sum(x[j]^2)) * sqrt(sum(c[j]^2))), and cosine distance is 1 - similarity.
  • Two zero vectors have similarity 1. If exactly one vector is zero, their similarity is 0.
  • Let s be the maximum similarity to any current center. Choose the smallest cluster index whose similarity is at least s - 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, with 1 <= d <= 20.
  • 1 <= k <= min(20, data.length) and centroids.length == k.
  • 1 <= iterations <= 100.
  • Coordinates are finite floating-point values between -10000 and 10000, with at most six digits after the decimal point.
  • Duplicate points, duplicate centers, zero vectors, and empty clusters are allowed.

More TikTok problems

See TikTok hiring insights
public int[] kMeans(double[][] data, int k, double[][] centroids, int iterations) {
    // Implement this method.
}
data[[2.0,0.0],[3.0,0.0],[0.0,2.0],[0.0,4.0]]
k2
centroids[[1.0,0.0],[0.0,1.0]]
iterations5
expected[0,0,1,1]
Checking account…