예제 #1
0
void kmedians::calculate_median(cluster & current_cluster, point & median) {
    const dataset & data = *m_ptr_data;
    const std::size_t dimension = data[0].size();

    for (size_t index_dimension = 0; index_dimension < dimension; index_dimension++) {
        std::sort(current_cluster.begin(), current_cluster.end(), 
            [this](std::size_t index_object1, std::size_t index_object2) 
        {
            return (*m_ptr_data)[index_object1] > (*m_ptr_data)[index_object2];
        });

        std::size_t relative_index_median = (std::size_t) (current_cluster.size() - 1) / 2;
        std::size_t index_median = current_cluster[relative_index_median];

        if (current_cluster.size() % 2 == 0) {
            std::size_t index_median_second = current_cluster[relative_index_median + 1];
            median[index_dimension] = (data[index_median][index_dimension] + data[index_median_second][index_dimension]) / 2.0;
        }
        else {
            median[index_dimension] = data[index_median][index_dimension];
        }
    }
}
예제 #2
0
void agglomerative::calculate_center(const cluster & cluster, point & center) {
    const std::vector<point> & data = *m_ptr_data;

    const size_t dimension = data[0].size();

    center.resize(dimension, 0.0);

    for (auto index_point : cluster) {
        for (size_t index_dimension = 0; index_dimension < dimension; index_dimension++) {
            center[index_dimension] += data[index_point][index_dimension];
        }
    }

    for (size_t index_dimension = 0; index_dimension < dimension; index_dimension++) {
        center[index_dimension] /= cluster.size();
    }
}
예제 #3
0
double kmeans::update_center(const cluster & p_cluster, point & p_center) {
    point total(p_center.size(), 0.0);

    /* for each object in cluster */
    for (auto object_index : p_cluster) {
        /* for each dimension */
        for (size_t dimension = 0; dimension < total.size(); dimension++) {
            total[dimension] += (*m_ptr_data)[object_index][dimension];
        }
    }

    /* average for each dimension */
    for (size_t dimension = 0; dimension < total.size(); dimension++) {
        total[dimension] = total[dimension] / p_cluster.size();
    }

    const double change = m_metric(p_center, total);

    p_center = std::move(total);
    return change;
}