Commit 516a8024 authored by Joe Grimes's avatar Joe Grimes
Browse files

Masking merge request updates

parent 34405ecc
Loading
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ double LossFunctionCalinskiHarabasz::compute_w() {
        std::vector<double> centroid = get_centroid(cluster_label);
        for (size_t sample_idx = 0; sample_idx < _n_samp; sample_idx++) {
            int mask_idx = cluster_label * _n_samp + sample_idx;
            if (!label_mask[mask_idx]) continue;
            if (!_label_mask[mask_idx]) continue;
            const double* sample = &_a[sample_idx * _n_feat];
            double dist2 = 0.0;
            for (int f = 0; f < _n_feat; ++f) {
@@ -74,7 +74,7 @@ double LossFunctionCalinskiHarabasz::compute_b() {
        int n_k = 0;
        for (size_t sample_idx = 0; sample_idx < _n_samp; sample_idx++) {
            int mask_idx = cluster_label * _n_samp + sample_idx;
            if (label_mask[mask_idx]) {
            if (_label_mask[mask_idx]) {
                n_k++;
            }
        }
+20 −28
Original line number Diff line number Diff line
@@ -13,7 +13,8 @@ LossFunctionClustering::LossFunctionClustering(std::vector<double> prop_train,
                                                         int n_feat)
    : LossFunction(prop_train, prop_test, task_sizes_train, std::move(task_sizes_test), false, n_feat),
      _n_class_per_task(task_sizes_train.size(), 0),
      _n_class(0)
      _n_class(0),
      _curr_centroid(_n_feat,0.0)
{
    for (auto& pt : _prop_test)
    {
@@ -91,18 +92,18 @@ LossFunctionClustering::LossFunctionClustering(const std::shared_ptr<LossFunctio


void LossFunctionClustering::init_mask(){
    int length = _n_samp * _n_class;
    label_mask.resize(length);
    std::fill_n(label_mask.begin(), length, 0);
    _label_mask.resize(_n_samp * _n_class, 0.0);

    for (int i = 0; i < _n_class; i++) {            // each cluster
        for (int j = 0; j < _n_samp; j++) {         // each sample
            label_mask[i * _n_samp + j] = static_cast<int>(_prop_train[j]) == i;
        }
        //use daxpy now in lapack to do calculations
    for (int i = 0; i < _n_class; i++)
    {
        std::transform(_prop_train.begin(),
                       _prop_train.end(),
                       &_label_mask[i * _n_samp], [i](double prop){return static_cast<double>(static_cast<int>(prop) == i);}
        );
    }
    }


void LossFunctionClustering::set_nfeat(int n_feat)
{
    _n_feat = n_feat;
@@ -113,6 +114,7 @@ void LossFunctionClustering::set_nfeat(int n_feat)
            return tot + nc * (nc - 1) / 2;
        });
    _coefs.resize(n_class_combos * _n_dim, 0.0);
    
}
double LossFunctionClustering::operator()(const std::vector<int>& inds) {
    return 0.0;
@@ -141,27 +143,17 @@ void LossFunctionClustering::populate_from_feats(const std::vector<model_node_pt


std::vector<double> LossFunctionClustering::get_centroid(int cluster_label) {
    std::vector<double> centroid(_n_feat, 0.0);
    int n_samples_in_cluster = 0;

    int n = _n_feat;
    double alpha = 1.0;
    int inc = 1;

    for (size_t sample_idx = 0; sample_idx < _n_samp; sample_idx++) {
        if (!label_mask[cluster_label * _n_samp + sample_idx]) {
            continue;
    const double* mask = &_label_mask[cluster_label * _n_samp];
    int n_samples_in_cluster = std::accumulate(mask, mask + _n_samp, 0.0);
    if (n_samples_in_cluster == 0){
        return _curr_centroid;
    }
        daxpy_(&n, &alpha, &_a[sample_idx * _n_feat], &inc, centroid.data(), &inc);
        n_samples_in_cluster++;
    int inc_mask = 1;
    for (int ff = 0; ff < _n_feat; ++ff) {
        _curr_centroid[ff] = ddot_(&_n_samp, &_a[ff], &_n_feat, mask, &inc_mask);
        _curr_centroid[ff] /= n_samples_in_cluster;
    }

    if (n_samples_in_cluster > 0) {
        double scale = 1.0 / n_samples_in_cluster;
        dscal_(&n, &scale, centroid.data(), &inc);
    }

    return centroid;
    return _curr_centroid;
}

double LossFunctionClustering::test_loss(const std::vector<model_node_ptr>& feats) {
+2 −1
Original line number Diff line number Diff line
@@ -19,7 +19,8 @@ protected:
    std::vector<int> _n_class_per_task; //!< Number of classes in the property
    int _n_class; //!< Number of classes in the property
    std::vector<double> _a; //!< matrix to copy values from the D_Matrix
    std::vector<double> label_mask; //!< Label mask for prop train
    std::vector<double> _label_mask; //!< Label mask for prop train
    std::vector<double> _curr_centroid; //!< Stores the current calculated centroid;

public:
    /**
+33 −41
Original line number Diff line number Diff line
@@ -41,41 +41,33 @@ double LossFunctionDaviesBouldin::get_dbi() {
    double worst_spread_avg = 0.0;

    for (int key = 0; key < _n_class; key++) {
        int cluster_size = 0;
        for (int s = 0; s < _n_samp; s++) {
            int mask_idx = key * _n_samp  + s;
            if (label_mask[mask_idx])
            {
                cluster_size++;
            }
        }
        int cluster_size = std::accumulate(_label_mask.begin() + key * _n_samp,
                                           _label_mask.begin() + (key + 1) * _n_samp,
                                           0);
        if (cluster_size == 0) {
            continue;
        }
        double curr_spread = cent_avg_dist(key);
        std::vector<double> c1 = get_centroid(key);
        double curr_spread = cent_avg_dist(key, c1);
        double highest_ratio = 0.0;
        for (int other_key = 0; other_key < _n_class; other_key++) {
            if (other_key == key) {
                continue;
            }
            int n_other = 0;
            for (int s = 0; s < _n_samp; s++) {
                int mask_idx = other_key * _n_samp  +s;
                if (label_mask[mask_idx]) n_other++;
            }
            if (n_other == 0) {
            int n_other = std::accumulate(&_label_mask[other_key * _n_samp], &_label_mask[(other_key + 1) * _n_samp], 0);
            if (n_other == 0)
            {
                continue;
            }
            std::vector<double> c1 = get_centroid(key);
            std::vector<double> c2 = get_centroid(other_key);

            double dist = 0.0;
            for (int f = 0; f < _n_feat; f++) {
                double d = c1[f] - c2[f];
                dist += d * d;
            }
            dist = std::sqrt(dist);
            double other_spread = cent_avg_dist(other_key);
            double dist = std::sqrt(std::inner_product(
                c1.begin(), c1.end(), c2.begin(), 0.0,
                std::plus<>(),
                [](double a, double b){ return (a - b) * (a - b); }
                ));

            double other_spread = cent_avg_dist(other_key, c2);
            if (dist > 0.0) {
                double ratio = (curr_spread + other_spread) / dist;
                highest_ratio = std::max(highest_ratio, ratio);
@@ -86,26 +78,26 @@ double LossFunctionDaviesBouldin::get_dbi() {
    return worst_spread_avg / static_cast<double>(_n_class);
}

double LossFunctionDaviesBouldin::cent_avg_dist(size_t cluster_label) {
    std::vector<double> centroid = get_centroid(cluster_label);
    std::vector<int> cluster_samples;
    for (int s = 0; s < _n_samp; s++) {
        int mask_idx = cluster_label * _n_samp + s;
        if (label_mask[mask_idx]) {
            cluster_samples.push_back(s);
        }
    }
    int n_samples = static_cast<int>(cluster_samples.size());
    if (n_samples <= 1) return 0.0;
double LossFunctionDaviesBouldin::cent_avg_dist(size_t cluster_label, std::vector<double> centroid) {
    int n_samples = std::accumulate(
        &_label_mask[cluster_label * _n_samp],
        &_label_mask[(cluster_label + 1) * _n_samp],
        0
    );

    double avg = 0.0;
    for (int samp : cluster_samples) {
        const double* p = &_a[samp * _n_feat];
        double dist_sq = 0.0;
        for (int f = 0; f < _n_feat; f++) {
            double d = p[f] - centroid[f];
            dist_sq += d * d;
    for (int ii = 0; ii < _n_samp; ++ii)
    {
        if (_label_mask[cluster_label * _n_samp + ii] == 0)
        {
            continue;
        }
        avg += std::sqrt(dist_sq);
        avg += std::sqrt(std::inner_product(
            centroid.begin(), centroid.end(), &_a[ii * _n_feat], 0.0,
            std::plus<>(),
            [](double a, double b){ return (a - b) * (a - b); }
            ));
    }

    return avg / static_cast<double>(n_samples);
}
 No newline at end of file
+1 −1
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ public:
    /**
     * @brief Average distance of how spread out a cluster is
     */
    virtual double cent_avg_dist(size_t cluster_label);
    virtual double cent_avg_dist(size_t cluster_label, std::vector<double> centroid);

    
};
Loading