数据聚类:Mean-Shift和EM算法


目录

  • 1. 高斯混合分布
  • 2. Mean-Shift算法
  • 3. EM算法
  • 4. 数据聚类
  • 5. 源码地址


1. 高斯混合分布

在高斯混合分布中,我们假设数据是由多个高斯分布组合而成的。每个高斯分布被称为一个“成分”(component),这些成分通过加权和的方式来构成整个混合分布。

高斯混合分布的公式可以表示为:

p ( x ) = ∑ i = 1 K π i N ( x ∣ μ i , Σ i ) p(x) = \sum^K_{i=1} \pi_i N(x|\mu_i, \Sigma_i) p(x)=i=1KπiN(xμi,Σi)

其中:

  • p ( x ) p(x) p(x)是观测数据点 x x x的概率密度函数,
  • K K K是高斯分布的数量,
  • π i \pi_i πi是第 i i i个高斯分布的混合系数,满足 ∑ i = 1 K π i = 1 \sum^K_{i=1} \pi_i = 1 i=1Kπi=1,
  • μ i \mu_i μi是第 i i i个高斯分布的均值向量,
  • Σ i \Sigma_i Σi是第 i i i个高斯分布的协方差矩阵。

为了简单呈现结果,我们选取 K = 2 K=2 K=2个高斯分布。下图为一个高斯混合分布的采样散点图,其中两个高斯分布的 μ i \mu_i μi分别为 [ 0 , 0 ] , [ 5 , 5 ] [0,0], [5,5] [0,0],[5,5],协方差矩阵均为:
[ 1 0 0 1 ] \begin{bmatrix} 1 & 0 \\ 0 & 1 \end{bmatrix} [1001]

在这里插入图片描述

Fig. 1. 高斯混合分布的采样散点图

2. Mean-Shift算法

Mean-Shift是一种非参数化的密度估计和聚类算法,用于将数据点组织成具有相似特征的群集。它是一种迭代算法,通过计算数据点的梯度信息来寻找数据点在特征空间中的密度极值点,从而确定聚类中心。

算法的核心思想是通过不断地更新数据点的位置,将它们移向密度估计函数梯度的最大方向,直到达到收敛条件。具体来说,Mean-Shift算法包括以下步骤:

  • 初始化:选择一个数据点作为初始聚类中心,或者随机选择一个点作为初始中心。
  • 确定梯度向量:对于每个数据点,计算其与其他数据点之间的距离,并根据一定的核函数(如高斯核)计算梯度向量。梯度向量的方向指向密度估计函数增加最快的方向。
  • 移动数据点:将每个数据点移动到梯度向量的方向上,即向密度估计函数增加最快的方向移动一定的步长。
  • 更新聚类中心:对于移动后的每个数据点,重新计算它们周围数据点的梯度向量,并更新它们的位置。重复这个过程直到达到收敛条件,比如聚类中心的移动距离小于某个阈值。
  • 形成聚类:最终,根据收敛后的聚类中心,将数据点分配到最近的聚类中心,形成最终的聚类结果。

Mean-Shift算法的优点是不需要事先指定聚类的个数,且能够自适应地调整聚类中心的数量和形状。它在处理非线性和非凸形状的数据集时表现出良好的聚类效果。然而,该算法对于大规模数据集的计算复杂度较高,且对初始聚类中心的选择敏感。Mean-Shift算法的具体实现见代码片:

class MeanShift:
    def __init__(self, bandwidth=1.0, max_iterations=100):
        self.min_shift = 1
        self.n_clusters_ = None
        self.cluster_centers_ = None
        self.labels_ = None
        self.bandwidth = bandwidth
        self.max_iterations = max_iterations

    def euclidean_distance(self, x1, x2):
        return np.sqrt(np.sum((x1 - x2) ** 2))

    def gaussian_kernel(self, distance, bandwidth):
        return (1 / (bandwidth * np.sqrt(2 * np.pi))) * np.exp(-0.5 * ((distance / bandwidth) ** 2))

    def shift_point(self, point, data, bandwidth):
        shift_x = 0.0
        shift_y = 0.0
        total_weight = 0.0

        for i in range(len(data)):
            distance = self.euclidean_distance(point, data[i])
            weight = self.gaussian_kernel(distance, bandwidth)
            shift_x += data[i][0] * weight
            shift_y += data[i][1] * weight
            total_weight += weight

        shift_x /= total_weight
        shift_y /= total_weight

        return np.array([shift_x, shift_y])

    def fit(self, data):
        centroids = np.copy(data)

        for _ in range(self.max_iterations):
            shifts = np.zeros_like(centroids)

            for i, centroid in enumerate(centroids):
                distances = cdist([centroid], data)[0]
                weights = self.gaussian_kernel(distances, self.bandwidth)
                shift = np.sum(weights[:, np.newaxis] * data, axis=0) / np.sum(weights)
                shifts[i] = shift

            shift_distances = cdist(shifts, centroids)
            centroids = shifts

            if np.max(shift_distances) < self.min_shift:
                break

        unique_centroids = np.unique(np.around(centroids, 3), axis=0)

        self.cluster_centers_ = unique_centroids
        self.labels_ = np.argmin(cdist(data, unique_centroids), axis=1)
        self.n_clusters_ = len(unique_centroids)

3. EM算法

EM算法是一种迭代的数值优化算法,用于求解包含隐变量的概率模型参数的最大似然估计。它在统计学和机器学习领域被广泛应用,尤其在聚类问题中有着重要的应用。其基于观测数据和隐变量之间的概率模型,通过交替进行两个步骤:E步骤(Expectation Step)和M步骤(Maximization Step)来迭代地优化模型参数。下面是EM算法的基本步骤:

  • 初始化:选择一组初始参数来开始迭代过程。
  • E步骤:根据当前的参数估计,计算隐变量的后验概率,即给定观测数据下隐变量的条件概率分布。
  • M步骤:使用在E步骤中计算得到的后验概率,对参数进行更新,以最大化对数似然函数。
  • 重复步骤2-3至收敛:重复执行E步骤和M步骤,直到参数的变化很小或满足收敛条件。

在聚类问题中,EM算法可以用于估计混合高斯模型的参数,从而实现数据的聚类。EM算法在聚类中的应用优点是能够处理具有隐变量的概率模型,适用于灵活的聚类问题。然而,EM算法对于初始参数的选择敏感,可能会陷入局部最优解,并且在处理大规模数据集时可能会面临计算复杂度的挑战。EM算法(包含正则化步骤)的具体实现见代码片:

class RegularizedEMClustering:
    def __init__(self, n_clusters, max_iterations=100, epsilon=1e-4, regularization=1e-6):
        self.labels_ = None
        self.X = None
        self.n_features = None
        self.n_samples = None
        self.cluster_probs_ = None
        self.cluster_centers_ = None
        self.n_clusters = n_clusters
        self.max_iterations = max_iterations
        self.epsilon = epsilon
        self.regularization = regularization

    def fit(self, X):
        self.X = X
        self.n_samples, self.n_features = X.shape

        self.cluster_centers_ = X[np.random.choice(self.n_samples, self.n_clusters, replace=False)]

        self.cluster_probs_ = np.ones((self.n_samples, self.n_clusters)) / self.n_clusters

        # EM
        for iteration in range(self.max_iterations):
            # E-step
            prev_cluster_probs = self.cluster_probs_
            self._update_cluster_probs()

            # M-step
            self._update_cluster_centers()

            delta = np.linalg.norm(self.cluster_probs_ - prev_cluster_probs)

            if delta < self.epsilon:
                break

        self.labels_ = np.argmax(self.cluster_probs_, axis=1)

    def _update_cluster_probs(self):
        distances = np.linalg.norm(self.X[:, np.newaxis, :] - self.cluster_centers_, axis=2)

        # Calculate the cluster probabilities with regularization
        numerator = np.exp(-distances) + self.regularization
        denominator = np.sum(numerator, axis=1, keepdims=True)
        self.cluster_probs_ = numerator / denominator

    def _update_cluster_centers(self):
        self.cluster_centers_ = np.zeros((self.n_clusters, self.n_features))
        for k in range(self.n_clusters):
            self.cluster_centers_[k] = np.average(self.X, axis=0, weights=self.cluster_probs_[:, k])

    def predict(self, X):
        distances = np.linalg.norm(X[:, np.newaxis, :] - self.cluster_centers_, axis=2)
        return np.argmin(distances, axis=1)

4. 数据聚类

Mean-Shift和EM算法的聚类结果分别如图2的a-b子图所示,由于MoG比较简单,两种算法均可以合理且完整地实现聚类,聚类中心也没有显著差异。

在这里插入图片描述

Fig. 2. Mean-Shift(a)和EM(b)算法的聚类结果

5. 源码地址

如果对您有用的话可以点点star哦~

https://github.com/Jurio0304/cs-math/blob/main/hw3_clustering.ipynb
https://github.com/Jurio0304/cs-math/blob/main/func.py


创作不易,麻烦点点赞和关注咯!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/579151.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ElasticSearch教程入门到精通——第二部分(基于ELK技术栈elasticsearch 7.x+8.x新特性)

ElasticSearch教程入门到精通——第二部分&#xff08;基于ELK技术栈elasticsearch 7.x8.x新特性&#xff09; 1. JavaAPI-环境准备1.1 新建Maven工程——添加依赖1.2 HelloElasticsearch 2. 索引2.1 索引——创建2.2 索引——查询2.3 索引——删除 3. 文档3.1 文档——重构3.2…

GPU:使用gpu-burn压测GPU

简介&#xff1a;在测试GPU的性能问题时&#xff0c;通常需要考虑电力和散热问题。使用压力测试工具&#xff0c;可以测试GPU满载时的状态参数&#xff08;如温度等&#xff09;。gpu_burn是一个有效的压力测试工具。通过以下步骤可以进行测试。 官网&#xff1a; http://www…

Linux——终端

一、终端 1、终端是什么 终端最初是指终端设备&#xff08;Terminal&#xff09;&#xff0c;它是一种用户与计算机系统进行交互的硬件设备。在早期的计算机系统中&#xff0c;终端通常是一台带有键盘和显示器的电脑&#xff0c;用户通过它输入命令&#xff0c;计算机在执行命…

PMBOK® 第六版 项目是什么

目录 读后感—PMBOK第六版 目录 项目定义 定义&#xff1a;项目是为创造独特的产品、服务或成果而进行的临时性工作。 项目的特征具备以下三点&#xff1a; 独特性&#xff1a;独一无二&#xff0c;无法简单重复过去的做法。 临时性&#xff1a;项目有明确的起点和终点&…

(22408)武汉大学计算机专硕初试备考经验贴

首先谈一下&#xff0c;写这篇文章的初衷。 我相信考武大计算机的同学都是优秀的&#xff0c;应该有自己的备考方法&#xff0c;所以这里并不介绍具体怎么备考某一科目。 计算机考研热度较高&#xff0c;备考不易&#xff0c;这里将自己备考过程中遇到的问题&#xff0c;分享…

人工智能|推荐系统——推荐大模型最新进展

近年来,大语言模型的兴起为推荐系统的发展带来了新的机遇。这些模型以其强大的自然语言处理能力和丰富的知识表示,为理解和生成复杂的用户-物品交互提供了新的视角。本篇文章介绍了当前利用大型语言模型进行推荐系统研究的几个关键方向,包括嵌入空间的解释性、个性化推荐的知…

中国人工智能奠基人张钹院士:走进“无人区” 探索人工智能之路

4月23日&#xff0c;中国人工智能奠基人、清华大学计算机系教授、中国科学院院士张钹在“人文清华”讲坛作专题分享。在2小时的直播中&#xff0c;张钹以《走进“无人区” 探索人工智能之路》为主题&#xff0c;回顾人工智能的发展历程&#xff0c;为大家解读ChatGPT的意义&…

新手Pytorch入门笔记-概念入门

文章目录 1.主干权重和模型权重2.超参数2.1 ReLU(inplaceTrue)2.2 交叉熵损失CrossEntropyLoss 3.反向传播4.优化器4.1 optimizer.zero_grad()5.卷积6.Batch Normalization7.U-Net结构 这章节比较枯燥&#xff0c;都是大段文字 1.主干权重和模型权重 主干权重&#xff08;Back…

GateWay具体的使用之全链路跟踪TraceId日志

1.创建全局过滤器&#xff0c;在请求头上带入traceId参数&#xff0c;穿透到下游服务. package com.by.filter;import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.jwt.JWTValidator;…

vue做导入导出excel文档

系统中经常会遇到要实现批量导入/导出数据的功能&#xff0c;导入就需要先下载一个模板&#xff0c;然后在模板文件中填写内容&#xff0c;最后导入模板&#xff0c;导出就可能是下载一个excel文件。 1、导出 新建一个export.js文件如下&#xff1a; import {MessageBox,Mes…

【Git】分支管理的基本操作

文章目录 理解分支分支的本质主分支创建分支切换分支合并分支fast-forward模式删除分支合并冲突问题 理解分支 分支管理是git的一个核心功能。在git中&#xff0c;分支是用来独立开发于某个功能或者修复某个bug的一种方式。就像是《火影忍者》中的鸣人使用分身去妙蛙山修炼&am…

ansible-copy用法

目录 概述实践不带目录拷贝带目录拷贝 概述 ansible copy 常用用法举例 不带目录拷贝&#xff0c;拷贝的地址要写全 带目录拷贝&#xff0c;拷贝路径不要写在 dest 路径中 实践 不带目录拷贝 # with_fileglob 是 Ansible 中的一个循环关键字&#xff0c;用于处理文件通配符匹…

【强训笔记】day4

NO.1 思路&#xff1a;利用滚动数组&#xff0c;迭代一个Fibonacci数列&#xff0c;给出三个值进行循环迭代&#xff0c;当n<c时&#xff0c;说明n在b和c之间&#xff0c;这里只需要返回c-n和n-b的最小值就可以了。 代码实现&#xff1a; #include<iostream>using n…

BLIP-2论文精读

概述 由于大规模模型的端到端训练&#xff0c;视觉和语言预训练的成本越来越高&#xff0c;BLIP-2是一种通用且高效的预训练策略&#xff0c;可以从现成的冻结的预训练图像编码器和冻结的大型语言模型引导视觉语言预训练。 模型主体框架 BLIP-2采用了一个轻量级的查询转换器Q…

【Docker】Docker的网络与资源控制

Docker网络实现原理 Docker使用Linux桥接&#xff0c;在宿主机虚拟一个Docker容器网桥(docker0)&#xff0c;Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址&#xff0c;称为Container-IP&#xff0c;同时Docker网桥是每个容器的默认网关。因为在同一宿主机内…

什么是外汇杠杆交易?

外汇杠杆交易是目前的外汇交易市场中&#xff0c;投资者进行外汇交易的重要方式&#xff0c;通过这样的交易方式&#xff0c;投资者就有机会进行以小搏大的交易&#xff0c;他们的交易就有可能会更成功&#xff0c;因此&#xff0c;投资者应该对这样的交易方式进行了解&#xf…

【车展直播(1)】电机的知识

背景&#xff0c;最近在2024 北京车展&#xff0c;然后需要做一些直播讲解。 首先需要关注的是电动车的电机。其实这个东西吧&#xff0c;我不能算是完全知道&#xff0c;但是自己做做PWM 控制器&#xff0c;MOS管驱动&#xff0c;做两轮电机Motor 的控制这种基础的工作还是有…

Docker数据管理+镜像的创建

Docker容器数据管理方式 数据卷 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中&#xff0c;可将宿主的目录挂载到数据卷上&#xff0c;对数据卷的修改操作立即可见&#xff0c;并且更新数据不会影响镜像&#xff0c;从而实现数据在宿主机与容器之间的迁移。数据卷…

C#反射应用

1.根据类名名称生成类实例 CreateInstance后面的参数部分一定要和所构造的类参数数量对应&#xff0c;即使设置参数默认值&#xff0c;也不可省略。 2.只知道类名&#xff0c;需要将该类作为参数调用泛型接口。 3.只知道类名&#xff0c;需要将该类的数组作为参数调用泛型接口…

CentOS yum make cache/clean all 提示yum lock

错误信息 Another app is currently holding the yum lock; waiting for it to exit 问题描述&#xff1a; 已加载插件&#xff1a;fastestmirror Repository base is listed more than once in the configuration Repository updates is listed more than once in the config…