Loading src/loss_function/LossFunctionCalinskiHarabasz.cpp +70 −3 Original line number Diff line number Diff line Loading @@ -23,12 +23,79 @@ LossFunctionCalinskiHarabasz::LossFunctionCalinskiHarabasz(const std::shared_ptr } double LossFunctionCalinskiHarabasz::test_loss(const std::vector<model_node_ptr>& feats) { //get the centroids first if (_label_mask.size() == 0){ if (_label_mask.empty()) { init_mask("train"); } populate_from_feats(feats); //now get the goods std::vector<std::vector<double>> train_centroids(_n_class, std::vector<double>(_n_feat, 0.0)); for (int cc = 0; cc < _n_class; ++cc) { const double* mask = &_label_mask[cc * _n_samp]; int n_points = std::accumulate(mask, mask + _n_samp, 0); if (n_points == 0) continue; int inc_mask = 1; for (int f = 0; f < _n_feat; ++f) { train_centroids[cc][f] = ddot_(&_n_samp, &_a[f], &_n_feat, mask, &inc_mask); train_centroids[cc][f] /= static_cast<double>(n_points); } } init_mask("test"); std::vector<double> global_centroid(_n_feat, 0.0); for (int f = 0; f < _n_feat; f++) { global_centroid[f] = cblas_ddot( static_cast<int>(_n_samp), &_a[f], _n_feat, _ones.data(), 1 ) / static_cast<double>(_n_samp); } double W = 0.0; double B = 0.0; int total_test_points = 0; for (int cc = 0; cc < _n_class; ++cc) { const double* mask = &_label_mask[cc * _n_samp]; int n_points = std::accumulate(mask, mask + _n_samp, 0); if (n_points == 0) continue; total_test_points += n_points; for (int s = 0; s < _n_samp; ++s) { if (mask[s] == 0) continue; W += std::inner_product( &_a[s * _n_feat], &_a[s * _n_feat] + _n_feat, train_centroids[cc].begin(), 0.0, std::plus<>(), [](double a, double b) { return (a - b) * (a - b); } ); } double dist2 = std::inner_product( train_centroids[cc].begin(), train_centroids[cc].end(), global_centroid.begin(), 0.0, std::plus<>(), [](double a, double b) { return (a - b) * (a - b); } ); B += n_points * dist2; } if (_n_class <= 1 || total_test_points <= _n_class) { return 0.0; } double CH = (B / static_cast<double>(_n_class - 1)) / (W / static_cast<double>(total_test_points - _n_class)); return CH; } Loading tests/googletest/loss_function/test_calinksi_harabasz.cc +3 −1 Original line number Diff line number Diff line Loading @@ -178,12 +178,14 @@ TEST_F(LossFunctionCalinskiHarabaszTests, MultiClassTest) // 4 classes _prop_train = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3}; _prop_test = _prop_train; _prop_test = {0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3}; LossFunctionCalinskiHarabasz loss( _prop_train, _prop_test, _task_sizes_train, _task_sizes_test, false, 2); double CH_score = loss(_model_phi); EXPECT_NEAR(CH_score, 1556.2937293418609, 1e-10); std::cout << "value from regular pipeline " << CH_score << std::endl; std::cout << "Value from test loss " << loss.test_loss(_model_phi) << std::endl; } } Loading
src/loss_function/LossFunctionCalinskiHarabasz.cpp +70 −3 Original line number Diff line number Diff line Loading @@ -23,12 +23,79 @@ LossFunctionCalinskiHarabasz::LossFunctionCalinskiHarabasz(const std::shared_ptr } double LossFunctionCalinskiHarabasz::test_loss(const std::vector<model_node_ptr>& feats) { //get the centroids first if (_label_mask.size() == 0){ if (_label_mask.empty()) { init_mask("train"); } populate_from_feats(feats); //now get the goods std::vector<std::vector<double>> train_centroids(_n_class, std::vector<double>(_n_feat, 0.0)); for (int cc = 0; cc < _n_class; ++cc) { const double* mask = &_label_mask[cc * _n_samp]; int n_points = std::accumulate(mask, mask + _n_samp, 0); if (n_points == 0) continue; int inc_mask = 1; for (int f = 0; f < _n_feat; ++f) { train_centroids[cc][f] = ddot_(&_n_samp, &_a[f], &_n_feat, mask, &inc_mask); train_centroids[cc][f] /= static_cast<double>(n_points); } } init_mask("test"); std::vector<double> global_centroid(_n_feat, 0.0); for (int f = 0; f < _n_feat; f++) { global_centroid[f] = cblas_ddot( static_cast<int>(_n_samp), &_a[f], _n_feat, _ones.data(), 1 ) / static_cast<double>(_n_samp); } double W = 0.0; double B = 0.0; int total_test_points = 0; for (int cc = 0; cc < _n_class; ++cc) { const double* mask = &_label_mask[cc * _n_samp]; int n_points = std::accumulate(mask, mask + _n_samp, 0); if (n_points == 0) continue; total_test_points += n_points; for (int s = 0; s < _n_samp; ++s) { if (mask[s] == 0) continue; W += std::inner_product( &_a[s * _n_feat], &_a[s * _n_feat] + _n_feat, train_centroids[cc].begin(), 0.0, std::plus<>(), [](double a, double b) { return (a - b) * (a - b); } ); } double dist2 = std::inner_product( train_centroids[cc].begin(), train_centroids[cc].end(), global_centroid.begin(), 0.0, std::plus<>(), [](double a, double b) { return (a - b) * (a - b); } ); B += n_points * dist2; } if (_n_class <= 1 || total_test_points <= _n_class) { return 0.0; } double CH = (B / static_cast<double>(_n_class - 1)) / (W / static_cast<double>(total_test_points - _n_class)); return CH; } Loading
tests/googletest/loss_function/test_calinksi_harabasz.cc +3 −1 Original line number Diff line number Diff line Loading @@ -178,12 +178,14 @@ TEST_F(LossFunctionCalinskiHarabaszTests, MultiClassTest) // 4 classes _prop_train = {0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3}; _prop_test = _prop_train; _prop_test = {0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3}; LossFunctionCalinskiHarabasz loss( _prop_train, _prop_test, _task_sizes_train, _task_sizes_test, false, 2); double CH_score = loss(_model_phi); EXPECT_NEAR(CH_score, 1556.2937293418609, 1e-10); std::cout << "value from regular pipeline " << CH_score << std::endl; std::cout << "Value from test loss " << loss.test_loss(_model_phi) << std::endl; } }