From: Francois Fleuret Date: Wed, 27 Mar 2013 11:36:16 +0000 (+0100) Subject: Cosmetics. X-Git-Url: https://fleuret.org/cgi-bin/gitweb/gitweb.cgi?a=commitdiff_plain;h=792d1a58d91f607d47ea5316ec680fb5e3454e5e;p=clueless-kmeans.git Cosmetics. --- diff --git a/clueless-kmean.cc b/clueless-kmean.cc index 1eea96f..16f7691 100644 --- a/clueless-kmean.cc +++ b/clueless-kmean.cc @@ -76,7 +76,9 @@ int main(int argc, char **argv) { glp_term_out(0); - clusterer.train(nb_clusters, sample_set.dim, + clusterer.train(Clusterer::UNINFORMATIVE_LP_ASSOCIATION, + nb_clusters, + sample_set.dim, sample_set.nb_points, sample_set.points, sample_set.nb_classes, sample_set.labels, associated_clusters); diff --git a/clusterer.cc b/clusterer.cc index 42af81b..47d9ac3 100644 --- a/clusterer.cc +++ b/clusterer.cc @@ -177,7 +177,6 @@ scalar_t Clusterer::uninformative_lp_cluster_association(int nb_points, scalar_t for(int c = 1; c <= nb_classes; c++) { int row = nb_points + (k - 1) * nb_classes + c; scalar_t tau = nb_samples_per_class[c-1] / scalar_t(_nb_clusters); - // cout << "tau " << k << " " << c << " " << tau << endl; glp_set_row_bnds(lp, row, GLP_FX, tau, tau); } } @@ -241,35 +240,6 @@ scalar_t Clusterer::uninformative_lp_cluster_association(int nb_points, scalar_t } } - // { // ******************************* START *************************** -// #warning Test code added on 2013 Feb 07 20:32:05 - // // for(int n = 0; n < nb_points; n++) { - // // scalar_t sum = 0; - // // for(int k = 0; k < _nb_clusters; k++) { - // // ASSERT(gamma[n][k] >= 0 && gamma[n][k] <= 1); - // // sum += gamma[n][k]; - // // } - // // cout << sum << endl; - // // } - - // scalar_t *sum_gamma = new scalar_t[nb_classes]; - - // for(int k = 0; k < _nb_clusters; k++) { - // for(int c = 0; c < nb_classes; c++) { sum_gamma[c] = 0.0; } - // for(int n = 0; n < nb_points; n++) { - // sum_gamma[labels[n]] += gamma[n][k]; - // } - // cout << "CLUSTER" << k; - // for(int c = 0; c < nb_classes; c++) { - // cout << " " << sum_gamma[c]; - // } - // cout << endl; - // } - - // delete sum_gamma; - - // } // ******************************** END **************************** - delete[] nb_samples_per_class; delete[] ia; delete[] ja; @@ -279,7 +249,7 @@ scalar_t Clusterer::uninformative_lp_cluster_association(int nb_points, scalar_t return total_dist; } -void Clusterer::baseline_update_clusters(int nb_points, scalar_t **points, scalar_t **gamma) { +void Clusterer::update_clusters(int nb_points, scalar_t **points, scalar_t **gamma) { for(int k = 0; k < _nb_clusters; k++) { for(int d = 0; d < _dim; d++) { @@ -325,7 +295,8 @@ void Clusterer::initialize_clusters(int nb_points, scalar_t **points) { delete[] used; } -void Clusterer::train(int nb_clusters, int dim, +void Clusterer::train(int mode, + int nb_clusters, int dim, int nb_points, scalar_t **points, int nb_classes, int *labels, int *cluster_associations) { @@ -347,48 +318,41 @@ void Clusterer::train(int nb_clusters, int dim, do { pred_total_distance = total_distance; + + switch(mode) { + + case STANDARD_ASSOCIATION: + total_distance = + baseline_cluster_association(nb_points, points, nb_classes, labels, gammas); + break; + + case STANDARD_LP_ASSOCIATION: + total_distance = + baseline_lp_cluster_association(nb_points, points, nb_classes, labels, gammas); + break; + + case UNINFORMATIVE_LP_ASSOCIATION: total_distance = - // baseline_cluster_association(nb_points, points, nb_classes, labels, gammas); - // baseline_lp_cluster_association(nb_points, points, nb_classes, labels, gammas); uninformative_lp_cluster_association(nb_points, points, nb_classes, labels, gammas); + break; + + default: + cerr << "Unknown sample-cluster association mode." << endl; + abort(); + } + cout << "TRAIN " << nb_rounds << " " << total_distance << endl; - baseline_update_clusters(nb_points, points, gammas); + update_clusters(nb_points, points, gammas); nb_rounds++; } while(total_distance < min_iteration_improvement * pred_total_distance && nb_rounds < max_nb_iterations); - { - cout << "TOTAL_NB_SAMPLES"; - for(int c = 0; c < nb_classes; c++) { - int nb_samples = 0; - for(int n = 0; n < nb_points; n++) { - if(labels[n] == c) { - nb_samples++; - } - } - cout << " " << nb_samples; - } - cout << endl; - - for(int k = 0; k < _nb_clusters; k++) { - cout << "CLUSTER_GAMMA_SUM " << k << " :"; - for(int c = 0; c < nb_classes; c++) { - scalar_t sum = 0.0; - for(int n = 0; n < nb_points; n++) { - if(labels[n] == c) { - sum += gammas[n][k]; - } + if(cluster_associations) { + for(int n = 0; n < nb_points; n++) { + for(int k = 0; k < _nb_clusters; k++) { + if(k == 0 || gammas[n][k] > gammas[n][cluster_associations[n]]) { + cluster_associations[n] = k; } - cout << " " << sum; - } - cout << endl; - } - } - - for(int n = 0; n < nb_points; n++) { - for(int k = 0; k < _nb_clusters; k++) { - if(k == 0 || gammas[n][k] > gammas[n][cluster_associations[n]]) { - cluster_associations[n] = k; } } } diff --git a/clusterer.h b/clusterer.h index 88c168a..b45f8c3 100644 --- a/clusterer.h +++ b/clusterer.h @@ -29,6 +29,9 @@ class Clusterer { public: + + enum { STANDARD_ASSOCIATION, STANDARD_LP_ASSOCIATION, UNINFORMATIVE_LP_ASSOCIATION }; + const static int max_nb_iterations = 10; const static scalar_t min_iteration_improvement = 0.999; @@ -38,26 +41,38 @@ public: void initialize_clusters(int nb_points, scalar_t **points); + // Does the standard hard k-mean association + scalar_t baseline_cluster_association(int nb_points, scalar_t **points, int nb_classes, int *labels, scalar_t **gamma); + // Does the same with an LP formulation, as a sanity check + scalar_t baseline_lp_cluster_association(int nb_points, scalar_t **points, int nb_classes, int *labels, scalar_t **gamma); + // Does the association under constraints that each cluster gets + // associated clusters with the same class proportion as the overall + // training set + scalar_t uninformative_lp_cluster_association(int nb_points, scalar_t **points, int nb_classes, int *labels, scalar_t **gamma); - void baseline_update_clusters(int nb_points, scalar_t **points, scalar_t **gamma); + void update_clusters(int nb_points, scalar_t **points, scalar_t **gamma); public: Clusterer(); ~Clusterer(); - void train(int nb_clusters, int dim, + + void train(int mode, + int nb_clusters, int dim, int nb_points, scalar_t **points, int nb_classes, int *labels, + // This last array returns for each sample to what + // cluster it was associated. It can be null. int *cluster_associations); int cluster(scalar_t *point);