k-means center initialization using the following algorithm: Arthur & Vassilvitskii (2007) k-means++: The Advantages of Careful Seeding */
| 2579 | Arthur & Vassilvitskii (2007) k-means++: The Advantages of Careful Seeding |
| 2580 | */ |
| 2581 | static void generateCentersPP(const Mat& _data, Mat& _out_centers, |
| 2582 | int K, RNG& rng, int trials) |
| 2583 | { |
| 2584 | int i, j, k, dims = _data.cols, N = _data.rows; |
| 2585 | const float* data = _data.ptr<float>(0); |
| 2586 | size_t step = _data.step/sizeof(data[0]); |
| 2587 | vector<int> _centers(K); |
| 2588 | int* centers = &_centers[0]; |
| 2589 | vector<float> _dist(N*3); |
| 2590 | float* dist = &_dist[0], *tdist = dist + N, *tdist2 = tdist + N; |
| 2591 | double sum0 = 0; |
| 2592 | |
| 2593 | centers[0] = (unsigned)rng % N; |
| 2594 | |
| 2595 | for( i = 0; i < N; i++ ) |
| 2596 | { |
| 2597 | dist[i] = normL2Sqr_(data + step*i, data + step*centers[0], dims); |
| 2598 | sum0 += dist[i]; |
| 2599 | } |
| 2600 | |
| 2601 | for( k = 1; k < K; k++ ) |
| 2602 | { |
| 2603 | double bestSum = DBL_MAX; |
| 2604 | int bestCenter = -1; |
| 2605 | |
| 2606 | for( j = 0; j < trials; j++ ) |
| 2607 | { |
| 2608 | double p = (double)rng*sum0, s = 0; |
| 2609 | for( i = 0; i < N-1; i++ ) |
| 2610 | if( (p -= dist[i]) <= 0 ) |
| 2611 | break; |
| 2612 | int ci = i; |
| 2613 | |
| 2614 | parallel_for_(Range(0, N), |
| 2615 | KMeansPPDistanceComputer(tdist2, data, dist, dims, step, step*ci)); |
| 2616 | for( i = 0; i < N; i++ ) |
| 2617 | { |
| 2618 | s += tdist2[i]; |
| 2619 | } |
| 2620 | |
| 2621 | if( s < bestSum ) |
| 2622 | { |
| 2623 | bestSum = s; |
| 2624 | bestCenter = ci; |
| 2625 | std::swap(tdist, tdist2); |
| 2626 | } |
| 2627 | } |
| 2628 | centers[k] = bestCenter; |
| 2629 | sum0 = bestSum; |
| 2630 | std::swap(dist, tdist); |
| 2631 | } |
| 2632 | |
| 2633 | for( k = 0; k < K; k++ ) |
| 2634 | { |
| 2635 | const float* src = data + step*centers[k]; |
| 2636 | float* dst = _out_centers.ptr<float>(k); |
| 2637 | for( j = 0; j < dims; j++ ) |
| 2638 | dst[j] = src[j]; |
no test coverage detected