27 #include "jubatus/util/math/random.h"
28 #include "../common/exception.hpp"
30 using jubatus::util::lang::shared_ptr;
38 namespace clustering {
46 typedef eigen_wsvec_list_t::const_iterator data_iter;
52 double old_obj = 0, obj = 0;
53 vector<double> weights(k);
55 bool converged =
false;
63 fill(weights.begin(), weights.end(), 0);
67 for (data_iter i = data.begin(); i != data.end(); ++i) {
70 for (
int c = 0; c < k; ++c) {
71 double cp = i->weight * cps.coeff(c);
73 covs_[c] += i->data * (i->data.transpose()) * cp;
75 obj -= std::log(std::max(cp, std::numeric_limits<double>::min()));
78 for (
int c = 0; c < k; ++c) {
80 covs_[c] /= weights[c];
98 "clustering is not performed yet"));
104 for (
int c = 0; c <
k_; ++c) {
105 double cp = cps.coeff(c);
122 for (
int i = 0; i < d; ++i) {
123 eye_.insert(i, i) = 1;
126 jubatus::util::math::random::mtrand r(time(NULL));
127 for (
int c = 0; c < k; ++c) {
128 means_[c] = data[r.next_int(0, data.size()-1)].data;
129 for (
int i = 0; i < d; ++i) {
130 covs_[c].insert(i, i) = 1;
143 for (
int c = 0; c <
k_; ++c) {
144 max_dist = max(max_dist, (means[c] - old_means[c]).norm());
146 return (max_dist < 1e-09 || niter > 1e05);
154 double den = DBL_MIN;
156 for (
int i = 0; i <
k_; ++i) {
158 double det = std::abs(cov_solvers[i]->determinant());
159 double quad = (dif.transpose() * cov_solvers[i]->solve(dif)).
sum();
160 double lp = -1 / 2. * (std::log(det) + quad);
161 ret.coeffRef(i) = lp;
162 den = (den == DBL_MIN) ?
163 lp : std::max(den, lp) +
164 std::log(1 + std::exp(min(den, lp) - std::max(den, lp)));
166 for (
int i = 0; i <
k_; ++i) {
167 ret.coeffRef(i) = std::exp(ret.coeff(i) - den);
void batch(const eigen_wsvec_list_t &data, int d, int k)
Eigen::SimplicialCholesky< eigen_smat_t > eigen_solver_t
int64_t get_nearest_center_index(const eigen_svec_t &p) const
std::vector< jubatus::util::lang::shared_ptr< eigen_solver_t > > eigen_solver_list_t
void initialize(const eigen_wsvec_list_t &data, int d, int k)
Eigen::SparseMatrix< double > eigen_smat_t
bool is_converged(int64_t niter, const eigen_svec_list_t &means, const eigen_svec_list_t &old_means, double obj, double old_obj)
#define JUBATUS_EXCEPTION(e)
eigen_svec_t get_nearest_center(const eigen_svec_t &p) const
eigen_svec_t cluster_probs(const eigen_svec_t &x, const eigen_svec_list_t &mean, const eigen_smat_list_t &cov, const eigen_solver_list_t &solvers) const
std::vector< eigen_svec_t > eigen_svec_list_t
double sum(const common::sfv_t &p)
eigen_solver_list_t cov_solvers_
std::vector< eigen_wsvec_t > eigen_wsvec_list_t
Eigen::SparseVector< double > eigen_svec_t
std::vector< eigen_smat_t > eigen_smat_list_t