24 VectorXf weights(data.rows());
25 weights.setConstant(std::numeric_limits<float>::max());
27 for (
unsigned i = 0; i != k; ++i) {
29 std::discrete_distribution<unsigned> dist(weights.data(), weights.data() + weights.size());
30 centroids.row(i) = data.row(dist(g));
32 weights = weights.cwiseMin((data.rowwise() - centroids.row(i)).rowwise().squaredNorm());
40 M_insist(k >= 1,
"kmeans requires at least one cluster");
41 if (data.size() == 0)
return std::make_pair(std::vector<unsigned>(), MatrixXf(0, data.cols()));
46 std::vector<unsigned> labels(data.rows(), 0);
47 std::vector<unsigned> label_counters(k, 0);
51 while (change
and i--) {
55 for (
unsigned row_id = 0; row_id != data.rows(); ++row_id) {
57 auto deltas = (centroids.rowwise() - data.row(row_id)).rowwise().squaredNorm();
58 deltas.minCoeff(&label);
59 change = change or labels[row_id] != label;
60 labels[row_id] = label;
64 label_counters.assign(k, 0);
65 centroids = MatrixRXf::Zero(centroids.rows(), centroids.cols());
66 for (
unsigned row_id = 0; row_id != data.rows(); ++row_id) {
67 const auto l = labels[row_id];
68 centroids.row(l) += (data.row(row_id) - centroids.row(l)) / ++label_counters[l];
72 return std::make_pair(std::move(labels), std::move(centroids));
static constexpr unsigned KMEANS_MAX_ITERATIONS
std::pair< std::vector< unsigned >, MatrixRXf > M_EXPORT kmeans_with_centroids(const Eigen::MatrixXf &data, unsigned k)
Clusters the given data according to the k-means algorithm.
MatrixRXf M_EXPORT kmeans_plus_plus(const Eigen::MatrixXf &data, unsigned k)
Compute initial cluster centroids using k-means++ algorithm.
Eigen::Matrix< float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > MatrixRXf