首页 > 其他分享 >k-means聚类模型的原理和应用

k-means聚类模型的原理和应用

时间:2024-06-09 10:30:02浏览次数:13  
标签:std means int 模型 vector 聚类 clusters

        k-means聚类算法是一种迭代求解的聚类分析算法,其步骤是,预将数据分为K组,然后随机选取K个对象作为初始的聚类中心;计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心;聚类中心以及分配给它们的对象就代表一个聚类;每分配一个样本,聚类的聚类中心会根据聚类中现有的对象被重新计算。这个过程将不断重复直到满足某个终止条件。终止条件可以是没有(或最小数目)对象被重新分配给不同的聚类,没有(或最小数目)聚类中心再发生变化,误差平方和局部最小。

        k-means聚类算法在市场分析、图像处理、模式识别、数据挖掘等多个领域中都有广泛应用。通过对数据进行聚类,可以发现数据集中的隐藏结构和规律,进而为决策提供有力支持。以下是一个简单的C++实现,展示了如何使用k-means算法对二维数据进行聚类。请注意,为了简单起见,此实现省略了一些优化和错误处理,但足以说明k-means算法的基本思想。代码如下。

#include <iostream>
#include <vector>
#include <cmath>
#include <random>
#include <limits>
#include <algorithm>

struct Point {
    double x, y;
};

double euclideanDistance(const Point& a, const Point& b) {
    return std::sqrt(std::pow(a.x - b.x, 2) + std::pow(a.y - b.y, 2));
}

Point calculateCentroid(const std::vector<Point>& cluster) {
    double sumX = 0, sumY = 0;
    for (const auto& point : cluster) {
        sumX += point.x;
        sumY += point.y;
    }
    return {sumX / cluster.size(), sumY / cluster.size()};
}

std::vector<Point> initializeCentroids(const std::vector<Point>& data, int k) {
    std::vector<Point> centroids(k);
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(0, data.size() - 1);
    
    for (int i = 0; i < k; ++i) {
        centroids[i] = data[dis(gen)];
    }
    return centroids;
}

std::vector<std::vector<Point>> kMeans(const std::vector<Point>& data, int k, int maxIterations) {
    std::vector<Point> centroids = initializeCentroids(data, k);
    std::vector<std::vector<Point>> clusters(k);
    
    for (int iter = 0; iter < maxIterations; ++iter) {
        // Assign points to clusters
        std::fill(clusters.begin(), clusters.end(), std::vector<Point>());
        for (const auto& point : data) {
            int minIndex = -1;
            double minDist = std::numeric_limits<double>::max();
            for (int i = 0; i < k; ++i) {
                double dist = euclideanDistance(point, centroids[i]);
                if (dist < minDist) {
                    minDist = dist;
                    minIndex = i;
                }
            }
            clusters[minIndex].push_back(point);
        }

        // Calculate new centroids
        bool hasConverged = true;
        for (int i = 0; i < k; ++i) {
            Point oldCentroid = centroids[i];
            centroids[i] = calculateCentroid(clusters[i]);
            if (euclideanDistance(oldCentroid, centroids[i]) > std::numeric_limits<double>::epsilon()) {
                hasConverged = false;
            }
        }
        if (hasConverged) {
            break;
        }
    }

    return clusters;
}

int main() {
    // Sample data points
    std::vector<Point> data = {{1, 2}, {5, 8}, {1.5, 1.8}, {8, 8}, {1, 0.6}, {9, 11}};
    
    // Number of clusters and maximum iterations
    int k = 2;
    int maxIterations = 100;

    // Perform k-means clustering
    std::vector<std::vector<Point>> clusters = kMeans(data, k, maxIterations);

    // Print results
    std::cout << "Clusters:" << std::endl;
    for (int i = 0; i < clusters.size(); ++i) {
        std::cout << "Cluster " << i + 1 << ":" << std::endl;
        for (const auto& point : clusters[i]) {
            std::cout << "(" << point.x << ", " << point.y << ")" << std::endl;
        }
        std::cout << std::endl;
    }

    // Optionally, print centroids
    std::cout << "Centroids:" << std::endl;
    for (const auto& centroid : kMeans(data, k, maxIterations)[0]) {
        std::cout << "(" << centroid.x << ", " << centroid.y << ")" << std::endl;
    }

    return 0;
}

        以上代码首先定义了一个`Point`结构体用于表示二维空间中的点,然后定义了几个辅助函数,包括计算欧几里得距离、计算聚类中心、初始化聚类中心等。`kMeans`函数实现了k-means算法的主要逻辑,包括分配点到聚类中以及重新计算聚类中心。`main`函数中创建了一些样本数据点,然后调用`kMeans`函数进行聚类,并打印出每个聚类中的点以及聚类中心。

        注意:在实际应用中,k-means算法可能需要更多的优化,例如使用更高效的初始化方法(如k-means++),处理空聚类,以及利用并行计算加速算法等。此外,对于大规模数据集或高维数据,可能需要使用更高级的聚类算法。此示例仅用于展示k-means算法的基本实现。

标签:std,means,int,模型,vector,聚类,clusters
From: https://blog.csdn.net/winterling/article/details/139521789

相关文章

  • k-means聚类模型的优缺点
    一、k-means聚类模型的优点        1.简单高效:k-means算法思想简单直观,易于实现。它通过迭代计算样本点与聚类中心之间的距离,并不断调整聚类中心的位置,直至满足终止条件。由于其计算过程相对直接,所以具有较高的执行效率。        2.空间划分明确:k-means算......
  • 【下篇】从 YOLOv1 到 YOLOv8 的 YOLO 物体检测模型历史
    YOLO型号之所以闻名遐迩,主要有两个原因:其速度和准确性令人印象深刻,而且能够快速、可靠地检测图像中的物体。上回我解释了YoloX,今天从Yolov6开始。YOLOv6:面向工业应用的单级物体检测框架美团视觉人工智能事业部(MeituanVisionAIDepartment)于2022年9月在ArXiv上......
  • Ai qwen大模型本地部署
    Aiqwen大模型本地部署官网地址ollama官网:https://ollama.comGithub:https://github.com/ollama/ollama环境配置Windows操作系统一台【小新2019】 windows下载安装工具https://ollama.com/download下载对应操作系统的安装包,下载需要开启魔法,不需要注册登录就能下载,......
  • 算法金 | LSTM 原作者带队,一个强大的算法模型杀回来了
    大侠幸会,在下全网同名「算法金」0基础转AI上岸,多个算法赛Top「日更万日,让更多人享受智能乐趣」时间拉回2019年,有「计算机界诺贝尔奖」之称图灵奖获得者公布,深度学习三巨头:YoshuaBengio、GeoffreyHinton、YannLeCun众望所归。图灵奖为何不颁给LSTM之父Jürgen......
  • Git底层原理与分析模型
    https://www.cnblogs.com/liqinglucky/p/git.html一、git版本管理1.1背景--从写毕业论文讲文档备份让我们从写毕业论文的经历讲起。通常开始写论文之前,先在一个开阔的空间创建了一个文件夹用于保存将来的论文稿。然后就开始了我们的“毕业论文版本管理”。这样管理存在的问......
  • 应用广义线性模型二|二响应广义线性模型
    系列文章目录文章目录系列文章目录一、二响应模型的不同表达方式和响应函数二、二响应模型的性质(一)二响应变量的条件数学期望与方差(二)二响应模型参数的极大似然估计(三)二响应模型的优势三、二响应模型参数的假设检验(一)对数似然比检验方法(二)Wald统计量(三)得分统计量(四)模型......
  • 【报错解决】深度学习模型训练时cuda内存足够但测试时反而报错cuda out of memory
    报错描述报错的代码如下:model=reader(config=args,encoder=encoder)#初始化模型model.to('cuda')#把模型放到gpu上model.load_state_dict(torch.load(join(args.checkpoint_path,'best_ckpt_model1.pkl')))#加载模型参数model=torch.nn.DataParallel(model)#并行化......
  • C++ OpenCV 图像分类魔法:探索神奇的模型与代码
    ⭐️我叫忆_恒心,一名喜欢书写博客的研究生......
  • 想转行做大模型?AI产品经理们,先看看这份指南
    前言作为一个产品经理,你可能已经熟悉了一些常见的AI技术和应用,比如机器学习、深度学习、自然语言处理、计算机视觉等。但是,你是否了解什么是大模型?大模型又有什么特点和优势?为什么大模型会成为AI领域的一个重要趋势?如果你想转行做大模型,你需要具备哪些基本素质和技能?你又该......
  • 关于继承djangon内置模型AbstractUser用户认证authenticate一直返回None
    为了想要使用django内置的auth_user表字段,但是有些字段没有,想要定制于是我们可以:首先导入:fromdjango.contrib.auth.modelsimportUser,AbstractUserfromdjango.dbimportmodels然后这么写:classUserInfo(AbstractUser):"""用户信息"""nid=m......