人工智能|机器学习——CURE聚类算法(层次聚类)

news2024/11/15 11:18:13

1.CURE聚类概述

绝大多数聚类算法或者擅长处理球形和相似大小的聚类.或者在存在孤立点时变得比较脆弱。CURE采用了一种新颖的层次聚类算法.该算法选择基于质心和基于代表对象方法之间的中间策略。它不同于单个质心或对象来代表一个类,而是选择数据空间中固定数目的具有代表性的点。一个类的代表点通过如下方式产生:首先选择类中分散的对象,然后根据一个特定的分数或收缩因子“收缩”或移动它们。在算法的每一步,有最近距离的代表点对(每个点来自于一个不同的类)的两个类被合并。

每个类有多于一个的代表点使得CURE可以适应非球形的几何形状。类的收缩或凝聚可以有助于控制孤立点的影响。因此,CURE对孤立点的处理更加健壮,而且能够识别非球形和大小变化比较大的类。针对大型数据库,CURE采用随机取样和划分两种方法组合:一个随机样本首先被划分,每个划分被部分聚类。

2 算法步骤

  • 从源数据对象中抽取一个随机样本S;
  • 将样本S分割成一组划分;
  • 对每个划分局部的聚类;
  • 通过随机样本剔除孤立点。如果一个类增长缓慢就去除它;
  • 对局部的类进行聚类,落在每个新形成的类中的代表点根据用户定义的一个收缩因子收缩或向类中心移动。这些点代表和捕捉到了类的形状。
  • 用相应的类标签来标记数据。

3.CURE 聚类特点

CURE,Clustering Using Representative 算法的特点如下:

  • (1)属于凝聚层次聚类

CURE 算法首先把每个数据点看成一个簇,然后将距离最近的簇 结合,一直到簇的个数达到要求的 K 个为止。

  • (2)适应非球形的几何形状

不同于一个质心或者单个点来代表一个类,CURE 算法中每个簇有多个代表点,这使得 CURE算法可以适应非球形的几何形状。

代表点的选取:
首先选择簇中距离质心最远的点做为第一个点,然后依次选择距离已选到的点最远的点,直到选到c 个点为止,这些点尽量得分散,捕获了簇的形状和大小。

  • (3)对孤立点的处理更加健壮

另外,CURE 算法还通过“收缩因子”减少离群点对聚类效果的影响。

代表点的收缩或凝聚:
将上面选取到的代表点根据固定的参数α(0≤α≤1 )向该簇的质心收缩,距离质心越远的点(例如离群点)的收缩程度越大,因此CURE对离群点是不太敏感的,这种方法可以有效的降低离群点带来的不利影响。

收缩系数α的取值不同,聚类结果也相应不同。

当 α 趋于 0 时,所有的“代表点”都汇聚到质心,算法退化为基于“质心”的聚类;
当 α 趋于 1 时,“代表点”完全没有收缩,算法退化为基于“全连接”的聚类,
因此 α 值需要根据数据特征灵活选取,才能得到更好的聚类结果

在得到收缩后的代表点后,两个簇之间的距离就可以定义为这两个簇中距离最近的两个代表点之间的距离

  • (4)识别异常值/离群点

CURE 算法分两个阶段消除异常值的影响。

第一个阶段、是在聚类算法执行到某一阶段(或称当前的簇总数减小到某个值)时,根据簇的增长速度和簇的大小对离群点进行一次识别。

第一阶段,将聚类过程中类成员增长非常缓慢的类作为异常值剔除;

CURE算法由于异常值同其他对象的距离更大,所以其所在类中对象数目的增大就会非常缓慢,甚至不增长。

需要注意的是:
如果这个阶段选择的较早(簇总数过大)的话,会将一部分本应被合并的簇识别为离群点;
如果这个阶段选择的较晚(簇总数过少)的话,离群点很可能在被识别之前就已经合并到某些簇中;
因此原文推荐当前簇的总数为数据集大小的1/3时,进行离群点的识别。

第一阶段有一个很明显的问题,就是当随机采样到的离群点分布的比较近时(即使可能性比较小),这些点会被合并为一个簇,而导致无法将他们识别出来,这时就需要第二阶段的来进行处理。

第二阶段,是指在聚类的最后阶段,将非常小的簇删除;

由于离群点占的比重很小,而在层次聚类的最后几步中,每个正常簇的粒度都是非常高的,因此很容易将他们识别出来,一般当簇的总数缩减到大约为 k 时,进行第二阶段的识别。

  • (5)适应大规模数据

为了适应大型数据,CURE算法采用了随机抽样和分割相结合的手段。

随机抽样将原始数据集中的部分点提取出来,然后试图在这些点上实施CURE层次聚类算法,采样形成的数据子集要适应内存的需要并且与原始数据集相比要足够小。因此,这种随机采样的方法会大大提升CURE的执行速度,并且由于采样过程会对离群点进行过滤因而可以提高聚类质量。

另外,CURE算法还引入了分割的手段,即样本分割成几个部门,然后针对各个部分中的对象进行局部聚类,形成子类,再针对子类进行聚类,新出新的类。

4.优缺点

优点

1)可以发现复杂空间的簇

2)受噪点影响小

缺点

1)参数较多,包括采样的大小、聚类的个数、收缩的比例等;

2) 抽样有误差;

3)难以发现形状非常复杂的空间簇(如中空形状),对空间数据密度差异敏感

4)虽然 CURE 聚类是针对大规模数据库设计的算法,但是当数据量剧增时,效率仍然不能满足需求

5.Python实现

# -*- coding: utf-8 -*-

###########################################################################################
# Implementation of CURE (Clustering Using Representatives) Clustering Algorithm
# Author for codes: Chu Kun(kun_chu@outlook.com)
# Paper: https://www.sciencedirect.com/science/article/pii/S0306437901000084
# Reference: https://github.com/Kchu/CURE-cluster-python
###########################################################################################

import numpy as np
import scipy.spatial.distance as distance
import sys

# Returns the distance between two vectors
def dist(vecA, vecB):
    return np.sqrt(np.power(vecA - vecB, 2).sum())

# This class describes the data structure and method of operation for CURE clustering.
class CureCluster:
    def __init__(self, id__, center__):
        self.points = center__
        self.repPoints = center__
        self.center = center__
        self.index = [id__]
        
    def __repr__(self):
        return "Cluster " + " Size: " + str(len(self.points))
    
    # Computes and stores the centroid of this cluster, based on its points
    def computeCentroid(self, clust):
        totalPoints_1 = len(self.index)
        totalPoints_2 = len(clust.index)
        self.center = (self.center*totalPoints_1 + clust.center*totalPoints_2) / (totalPoints_1 + totalPoints_2)
    
    # Computes and stores representative points for this cluster
    def generateRepPoints(self, numRepPoints, alpha):
        tempSet = None
        for i in range(1, numRepPoints+1):
            maxDist = 0
            maxPoint = None
            for p in range(0, len(self.index)):
                if i == 1:
                    minDist = dist(self.points[p,:], self.center)
                else:
                    X = np.vstack([tempSet, self.points[p, :]])
                    tmpDist = distance.pdist(X)
                    minDist = tmpDist.min()
                if minDist >= maxDist:
                    maxDist = minDist
                    maxPoint = self.points[p,:]
            if tempSet is None:
                tempSet = maxPoint
            else:
                tempSet = np.vstack((tempSet, maxPoint))
        for j in range(len(tempSet)):
            if self.repPoints is None:
                self.repPoints = tempSet[j,:] + alpha * (self.center - tempSet[j,:])
            else:
                self.repPoints = np.vstack((self.repPoints, tempSet[j,:] + alpha * (self.center - tempSet[j,:])))

    # Computes and stores distance between this cluster and the other one.
    def distRep(self, clust):
        distRep = float('inf')
        for repA in self.repPoints:
            if type(clust.repPoints[0]) != list:
                repB = clust.repPoints
                distTemp = dist(repA, repB)
                if distTemp < distRep:
                    distRep = distTemp
            else:
                for repB in clust.repPoints:
                    distTemp = dist(repA, repB)
                    if distTemp < distRep:
                        distRep = distTemp
        return distRep

    # Merges this cluster with the given cluster, recomputing the centroid and the representative points.
    def mergeWithCluster(self, clust, numRepPoints, alpha):
        self.computeCentroid(clust)
        self.points = np.vstack((self.points, clust.points))
        self.index = np.append(self.index, clust.index)
        self.repPoints = None
        self.generateRepPoints(numRepPoints, alpha)

# Describe the process of the CURE algorithm
def runCURE(data, numRepPoints, alpha, numDesCluster):

    # Initialization
    Clusters = []
    numCluster = len(data)
    numPts = len(data)
    distCluster = np.ones([len(data), len(data)])
    distCluster = distCluster * float('inf')
    for idPoint in range(len(data)):
        newClust = CureCluster(idPoint, data[idPoint,:])
        Clusters.append(newClust)
    for row in range(0, numPts):
    	for col in range(0, row):
    		distCluster[row][col] = dist(Clusters[row].center, Clusters[col].center)
    while numCluster > numDesCluster:
        if np.mod(numCluster, 50) == 0:
            print('Cluster count:', numCluster)

        # Find a pair of closet clusters
        minIndex = np.where(distCluster == np.min(distCluster))
        minIndex1 = minIndex[0][0]
        minIndex2 = minIndex[1][0]

        # Merge
        Clusters[minIndex1].mergeWithCluster(Clusters[minIndex2], numRepPoints, alpha)
        # Update the distCluster matrix
        for i in range(0, minIndex1):
            distCluster[minIndex1, i] = Clusters[minIndex1].distRep(Clusters[i])
        for i in range(minIndex1+1, numCluster):
            distCluster[i, minIndex1] = Clusters[minIndex1].distRep(Clusters[i])
        # Delete the merged cluster and its disCluster vector.
        distCluster = np.delete(distCluster, minIndex2, axis=0)
        distCluster = np.delete(distCluster, minIndex2, axis=1)
        del Clusters[minIndex2]
        numCluster = numCluster - 1

    print('Cluster count:', numCluster)
    # Generate sample labels
    Label = [0] * numPts
    for i in range(0, len(Clusters)):
        for j in range(0, len(Clusters[i].index)):
            Label[Clusters[i].index[j]] = i + 1

    return Label

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mac使用自动操作(Automator)发送文件到Android设备

需求场景 在Android开发调试的过程中&#xff0c;当需要把电脑上的文件传输到连接的Android设备时&#xff0c;通常的做法是通过adb push命令。那既然是通过命令操作&#xff0c;是否可以通过可视化的工具来操作呢&#xff1f;例如在Finder中&#xff0c;右击某一个文件或者目…

BigGait: Learning Gait Representation You Want by Large Vision Models阅读笔记

于老师团队又有新作&#xff01;&#xff01; 0 Abstract 现有的步态识别任务严重依赖上游任务所使用的多种显示步态表征&#xff08;剪影图、姿态图、点云…&#xff09;&#xff0c;会导致严高额标注成本以及累计错误&#xff1b;文章提出了BigGait框架&#xff1a; 挖掘基…

如果利用AOP/Aspect来修改方法的入参

问题描述&#xff1a; 最近项目代码过三方测试&#xff08;国企项目&#xff09;&#xff0c;在一系列代码扫描审计检查下&#xff0c;代码发现一部分修改&#xff0c;例如请求参数发生了编码/加密&#xff0c;导致后台需要对请求的参数进行解码/解密&#xff0c;后端那么接口&…

【Git版本控制系统】:起步

目录 前言 版本控制 集中式与分布式的区别 Windows安装Git 核心 文件状态 工作区域 基本工作流程 配置用户信息 获取帮助 在线资源 前言 本篇文件的环境是Windows环境下实现。 在日常工作中git少不了&#xff0c;所以编写本篇文章介绍Git基础&#xff0c;专栏会不…

武汉星起航:创新驱动,共赢未来,引领跨境电商新潮流

在跨境电商这个充满挑战与机遇的领域&#xff0c;武汉星起航凭借其创新思维和共赢理念&#xff0c;正引领着行业发展的新潮流。 武汉星起航深知创新是企业在激烈竞争中立于不败之地的关键。公司始终关注市场动态&#xff0c;紧跟行业趋势&#xff0c;不断探索新的商业模式和运…

玩转 Spring 状态机:更优雅的实现订单状态流转

说起 Spring 状态机&#xff0c;大家很容易联想到这个状态机和设计模式中状态模式的区别是啥呢&#xff1f;没错&#xff0c;Spring 状态机就是状态模式的一种实现&#xff0c;在介绍 Spring 状态机之前&#xff0c;让我们来看看设计模式中的状态模式。 1. 状态模式 状态模式…

leetcode刷题(javaScript)——堆相关场景题总结

堆是什么&#xff1f;堆都能用树表示&#xff0c;并且一般树的实现都是利用链表。平时使用的最多的是二叉堆&#xff0c;它可以用完全二叉树表示&#xff0c;二叉堆易于存储&#xff0c;并且便于索引。在堆的实现时注意&#xff1a;因为是数组&#xff0c;所以父子节点的关系就…

学习SSM的记录(六)-- Spring MVC

目录 Spring MVC 简介和体验 Spring MVC原理简单解析 Spring MVC涉及的组件 Spring MVC 快速体验 Spring MVC 接收数据 访问路径设置 接收参数&#xff08;重点&#xff09; param和json参数比较 param参数接收 路径参数接收 json参数接收 EnableWebMvc注解 接收C…

探秘知乎的排名算法:知乎撰写高质量内容的秘诀

知乎作为一个知识问答社区&#xff0c;用户众多、内容繁杂&#xff0c;那么究竟是什么样的原则决定了知乎上的排名呢&#xff1f;腾轩科技传媒探讨知乎排名的规则&#xff0c;并分享如何撰写高质量的文章。 知乎排名的算法 在知乎这个巨大的社交平台上&#xff0c;任何一个用户…

DDL - 建立数据库,建表代码版(Way 2)

一、DB操作 show databases; create database DBOFRYX; drop database DBOFRYX; use DBOFRYX; 二、表操作&#xff08;表和表结构、字段是A、B两姐妹&#xff09; (1) use DBOFRYX; show tables; (2) create table TABOFRYX( name varchar(50) comment "姓名"…

ChatGPT提问技巧——对话提示

ChatGPT提问技巧——对话提示 对话提示是一种允许模型生成模拟两个或多个实体之间对话的文本的技术。 通过向模型提供上下文和一组角色或实体&#xff0c;以及他们的角色和背景&#xff0c;并要求模型生成他们之间的对话。 因此&#xff0c;应向模型提供一个上下文和一组角色…

大语言模型智能体简介

大语言模型&#xff08;LLM&#xff09;智能体&#xff0c;是一种利用大语言模型进行复杂任务执行的应用。这种智能体通过结合大语言模型与关键模块&#xff0c;如规划和记忆&#xff0c;来执行任务。构建这类智能体时&#xff0c;LLM充当着控制中心或“大脑”的角色&#xff0…

浏览器设置字体1px时,不能正常显示

问题如下&#xff0c;某版本浏览器&#xff0c;字体很小时&#xff0c;无法正常显示&#xff0c;解决方案有三种。 解决方案1 解决方案2 解决方案3

WebServer -- 面试题(下)

&#x1f442; 夏风 - Gifty - 单曲 - 网易云音乐 目录 &#x1f33c;前言 &#x1f382;面试题(下) 4&#xff09;HTTP报文解析 为什么要用状态机 状态转移图画一下 https 协议为什么安全 https 的 ssl 连接过程 GET 和 POST 的区别 5&#xff09;数据库注册登录 登…

十五、软考-系统架构设计师笔记-面向服务架构设计理论与实践

1、SOA相关概念 面向服务的架构(SOA)的定义 SOA 是一个组件模型&#xff0c;它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的&#xff0c;它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构…

[RoarCTF 2019]Easy Java -不会编程的崽

考察一下大家对java-web知识点的掌握 熟悉的登录界面让你想起了某位故人没有&#xff0c;哈哈&#xff0c;但是并非sql注入。一番基础尝试无果后&#xff0c;看看help吧 这个url让你想起某位故人了吗&#xff1f;对文件下载。但是似乎没有响应。改成post请求即可。 我看见pk了&…

unity3d Animal Controller的Animal组件中General基础部分理解

控制器介绍 动物脚本负责控制动物的所有运动逻辑.它管理所有的动画师和刚体参数,以及所有的状态和模式,动物可以做。 动物控制器 是一个动画框架控制器,根动或到位,为任何生物或人形。它利用刚体与物理世界的互动和动画师的玩动画。 States States 是不互相重叠的动画。例如…

canvas绘制圆形进度条

canvas绘制圆形进度条 用canvas绘制了一个圆形进度条&#xff0c;记录一下&#xff1a; 效果如下&#xff1a; 感觉效果还行&#xff0c;不过有待优化 代码如下&#xff1a; 我是用Vue写的 组件的代码&#xff1a; progressCanvas.vue <template><div><can…

Linux VM虚拟环境 设置静态IP

目录 查看自己的网卡配置说明重启网卡实例测试配置情况测试网络 查看自己的网卡 ip a配置文件 vim /etc/sysconfig/network-scripts/ifcfg-ens32配置说明 [rootlinux-server ~]# cd /etc/sysconfig/network-scripts/ #网卡配置文件存放路径 [rootlinux-server network-scri…

C/C++中{}的用法总结(全)

C基础专栏&#xff1a;http://t.csdnimg.cn/UjhPR 目录 1.定义初始化列表&#xff08;Initializer List&#xff09; 2.类成员初始化列表 3.无默认构造函数的类的默认初始化&#xff08;C11 及以后版本&#xff09; 4.初始化器列表构造函数&#xff08;C11 及以后版本&…