基于K-prototype算法聚类

k-prototype聚类是一种用于混合数据类型聚类的算法,由Jain和Dubes在1988年提出。它主要用于同时包含连续属性和离散属性的数据集。k-prototype算法可以看作是k-means算法的扩展,它将k-means算法的思想应用于混合数据类型,通过为连续属性和离散属性分别定义距离函数来处理这两种不同类型的数据。

k-prototype算法的基本步骤如下:

  1. 初始化:选择k个原型(prototype),每个原型是一个包含连续属性和离散属性的向量。
  2. 分配:对于数据集中的每个对象,计算其与每个原型的相似度,并将其分配给相似度最高的原型。相似度计算包括连续属性的距离和离散属性的不匹配度。
  3. 更新:根据分配到每个原型的对象,更新原型的值。对于连续属性,取分配给该原型的对象的连续属性的平均值;对于离散属性,取分配给该原型的对象中出现频率最高的离散值。
  4. 迭代:重复步骤2和3,直到原型不再发生变化或达到预设的迭代次数。
  5. 输出:最终得到k个聚类,每个聚类对应一个原型。
    代码实现步骤如下:
from numba import jit
import pandas as pd
import numpy as np
import random
from collections import Counter

## 定义数值型变量的距离(欧式距离)
def dist(x, y):
    return np.sqrt(sum((x-y)**2))
## 计算分类变量的距离(海明威距离)
def sigma(x, y):
    return len(x) - sum(x == y)

## 区分数值变量和分类变量,并随机生成聚类中心
def findprotos(data, k):
    #data = df
    m, n = data.shape
    # 生成聚类中心的行号
    num = random.sample(range(m), k)
    O = []
    C = []
    for i in range(n):
        try:
            if isinstance(data.iloc[0, i], int) or isinstance(data.iloc[0, i], float) or isinstance(data.iloc[0, i], np.int64):
                O.append(i)
            elif isinstance(data.iloc[0, i], str):
                C.append(i)
            else:
                raise ValueError("the %d column of data is not a number or a string column" % i)
        except TypeError as e:
            print(e)
    # 数值型变量
    O_data = data.iloc[:, O]
    # 分类型变量
    C_data = data.iloc[:, C]
    # 随机数值型数据(聚类中心)
    O_protos = O_data.iloc[num, :]
    # 随机分类型数据(聚类中心)
    C_protos = C_data.iloc[num, :]
    return O, C, O_data, C_data, O_protos, C_protos
## data: 待聚类的数据
## k: 类别数
## max_iters: 最大迭代次数
## 
#gamma = 1
#k = 3
#data = pd.DataFrame(df)

def KPrototypes(data, k, max_iters  ,  gamma ):
    # m: 数据的行数,n:数据的列数
    m, n = data.shape
    # O: 数值型变量的列号;   C:分类型变量的列号
    # O_data: 数值型数据;  C_data:分类型数据
    # O_protos:初始聚类中心的数值型数据; C_protos:聚类中心的 
    O, C, O_data, C_data, O_protos, C_protos = findprotos(data, k)
    cluster = None
    # clusterShip: 按行号存储每个样本的聚类类别
    clusterShip = []
    # 每个聚类类别的样本个数
    clusterCount = {}
    
    sumInCluster = {}
    freqInCluster = {}
    for i in range(m):
        mindistance = float('inf')
        # 此处循环每个点和各个聚类中心的关系
        for j in range(k):
            # 对数值型变量计算欧式距离,对分类型变量计算海明威距离
            # 计算每个点到各个聚类中心的距离,把他聚到距离他最近的类中去
            distance = dist(O_data.iloc[i,:], O_protos.iloc[j,:]) + gamma * sigma(C_data.iloc[i,:], C_protos.iloc[j,:])
            if distance < mindistance:
                mindistance = distance
                cluster = j
        clusterShip.append(cluster)
        if  clusterCount.get(cluster) == None:
            clusterCount[cluster] = 1
        else:
            clusterCount[cluster] += 1
        # 此处循环各个列的和,用来更新各个类的中心
        for j in range(len(O)):
            if sumInCluster.get(cluster) == None:
                sumInCluster[cluster] = [O_data.iloc[i,j]] + [0] * (len(O) - 1)
            else:
                sumInCluster[cluster][j] += O_data.iloc[i,j]
            O_protos.iloc[cluster,j] = sumInCluster[cluster][j] / clusterCount[cluster]
        for j in range(len(C)):
            if freqInCluster.get(cluster) == None:
                freqInCluster[cluster] = [Counter(C_data.iloc[i,j])] + [Counter()] * (len(C) - 1)
            else:
                freqInCluster[cluster][j] += Counter(C_data.iloc[i,j])
            # 出现次数最多的那个值,作为聚类中心
            C_protos.iloc[cluster,j] = freqInCluster[cluster][j].most_common()[0][0]
    max_iters = 10
    for t in range(max_iters):
        for i in range(m):
            mindistance = float('inf')
            for j in range(k):
                distance = dist(O_data.iloc[i,:], O_protos.iloc[j,:]) + gamma * sigma(C_data.iloc[i,:], C_protos.iloc[j,:])
                if distance < mindistance:
                    mindistance = distance
                    cluster = j
            # 重新判断某个点属于哪个类,如果不再属于以前的类,则把这个点的类别更新,且更新类的个数的dict
            if clusterShip[i] != cluster:
                oldCluster = clusterShip[i]
                clusterShip[i] = cluster
                clusterCount[cluster] += 1
                clusterCount[oldCluster] -= 1
                # 把这个点的坐标加到新的类别中,把它的值从之前的类中减掉
                for j in range(len(O)):
                    sumInCluster[cluster][j] += O_data.iloc[i,j]
                    sumInCluster[oldCluster][j] -= O_data.iloc[i,j]
                    O_protos.iloc[cluster,j] = sumInCluster[cluster][j] / clusterCount[cluster]
                    O_protos.iloc[oldCluster, j] = sumInCluster[oldCluster][j] / clusterCount[oldCluster]
                # 查找分类变量的聚类中心
                for j in range(len(C)):
                    freqInCluster[cluster][j] += Counter(C_data.iloc[i,j])
                    freqInCluster[oldCluster][j] -= Counter(C_data.iloc[i,j])
                    C_protos.iloc[cluster,j] = freqInCluster[cluster][j].most_common()[0][0]
                    C_protos.iloc[oldCluster,j] = freqInCluster[oldCluster][j].most_common()[0][0]
    return clusterShip , O_protos , C_protos

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

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

相关文章

Web安全知识

第二章 虚拟机运行架构&#xff1a; 1.寄居结构 2.原生架构 软件 注&#xff1a;Hyper-V是在Windows 2008操作系统上 附录 连接FTP服务器过程&#xff1a; 1.下载了软件&#xff1a; 2.连接到ftp://10.0.105.223/服务器&#xff08;访问老师课堂资源地址&#xff09; 关闭…

Node.JS后端开发笔记整理(简洁版)

前端 1. 开发环境和技术栈 开发工具&#xff1a;Visual Studio CodeNode.js版本&#xff1a;18.19.0&#xff08;建议保持在18&#xff09;包管理器&#xff1a;npm前端框架&#xff1a;Vue3.4脚本语言&#xff1a;TypeScript构建工具&#xff1a;Vite后端框架&#xff1a;Ex…

Django项目使用uwsgi+nginx部署上线

Django项目使用uwsginginx部署上线 前言settings 配置安装uwsgi 和配置uwsgi推荐配置文件启用wsgi不使用nginx的配置&#xff08;不推荐&#xff09;使用nginx的配置 安装 nginx和配置niginx 配置 运行参考资料 前言 代码已经开发完成&#xff0c;正式部署上线 settings 配置…

视频教程下载:用ChatGPT玩转海外抖音TikTok

CHATGPT for TikTok是一门前沿课程&#xff0c;旨在帮助您充分发挥TikTok广告活动的全部潜力。随着数字营销的爆炸性增长&#xff0c;企业需要使用先进的工具来保持竞争优势。在这门课程中&#xff0c;您将学习如何利用CHATGPT——一种先进的人工智能工具——来创建与目标受众产…

潜藏10年的恶意软件被发现;利用漏洞在K8S上挖矿;AWS、Google和Azure 出现信息泄露危机 | 安全周报0419

关键词&#xff1a;OfflRouter、恶意软件、VBA宏病毒、机密文件、可执行文件、iOS间谍软件、LightSpy、F_Warehouse、Azure CLI、AWS CLI、Google Cloud CLI 1. 近十年来&#xff0c;OfflRouter恶意软件在乌克兰一直未被发现 自2015年以来&#xff0c;部分乌克兰政府网络一直…

【软考】软件设计师中级

视频课 计算机组成原理 进制转换 定点数vs浮点数 校验码 计算机体系结构 指令系统 I/O 存储系统 直接映射&#xff1a;简单粗暴的死板派 全相联映射&#xff1a;跳脱的自由发挥派 组相联映射&#xff1a;折中派&#xff0c;组间直接映射&组内全相联映射 命中率&#xf…

你的mongodb客户端是哪个呢?

MongoDB 是一种流行的文档数据库&#xff0c;它可以支持多种场景和应用。有很多客户端工具可以用来管理和操作 MongoDB&#xff0c;以下是一些常用的工具&#xff0c;以及它们的介绍&#xff1a; 一、MongoDB Shell MongoDB Shell 是连接&#xff08;和使用&#xff09;MongoD…

【银角大王——Django课程Day1】

Django框架第一课 安装Django框架方式一&#xff08;命令行的形式创建Django项目&#xff09;方式二&#xff08;适合企业版的pycharm&#xff09;默认文件介绍app文件介绍快速上手我的导包一直爆红是因为我没使用解释器&#xff0c;没导入包&#xff0c;去设置里面导入包即可—…

(保姆级教学)跨站请求伪造漏洞

1. CSRF漏洞 CSRF&#xff08;Cross-site request forgery&#xff09;跨站请求伪造&#xff0c;也被称为One Click Attack 或者Session Riding&#xff0c;通常缩写为CSRF或者XSRF&#xff0c;是一种对网站的恶意利用。尽管听起来像跨站脚本&#xff08;XSS&#xff09;&…

【银角大王———Django学习DAY0——基础准备】

银角大王——Django学习前情提要 &#xff08;1&#xff09;在pycharm中下载Flask&#xff08;2&#xff09;使用Flask&#xff08;3&#xff09;下载BootStrap框架&#xff08;4&#xff09; 使用BootStrap框架 &#xff08;1&#xff09;在pycharm中下载Flask 在设置——项目…

搭建sql-lab出现的php不兼容

下载不了的时候&#xff0c;直接打开该网址下载5.xphp版本&#xff0c;解压到C:\php_studyv8\phpstudy\phpstudy_pro\Extensions\php&#xff08;可能路径都不一样&#xff0c;找到Extensions\php放到该目录下&#xff09;

element table加减列

// 有个特别注意的地方,下面这行代码,key一定绑的是item,千万不要绑定index,不然就会出现异常 //<el-table-column v-for"(item,index) in titleList" :key"item" min-width"150" align"center"><el-table fit :data"d…

微信小程序酒店选择日期和入住人数(有效果图)

效果图 app.vue onLaunch:function(options){this.defaultcache()}defaultcache(){// 入住信息缓存var arr this.getDateTime();var ReserVation {reservType:0,//1 人数 2日期InCheckin:{},//入离日期peopleArr:[{title:成人,num:2},{title:儿童,num:0},{title:宝子,num:1…

【C语言__动态内存管理__复习篇6】

目录 前言 一、动态内存管理 二、动态内存函数 2.1 malloc 2.2 free 2.3 calloc 2.4 realloc 三、动态内存常见的6个使用错误 3.1 接收malloc/calloc返回的参数后未及时检查是否为NULL 3.2 越界访问动态内存空间 3.3 对非动态开辟的内存使用free释放 3.4 使用free只释放了…

【GoWeb框架初探——GRPC】

1. GRPC介绍 1.1 什么是RPC RPC全程是Remote Procedure Call&#xff0c;远程过程调用。这是一种协议&#xff0c;是用来屏蔽分布式计算中的各种调用细节&#xff0c;使得你可以像是本地调用一样直接调用一个远程的函数。 调用流程 1&#xff09;客户端发送数据&#xff08;…

flutter 谷歌的苹果系统消息推送

flutter firebase 云消息通知教程 (android-安卓、ios-苹果) Android、ReactNative、Flutter集成Firebase推送注意事项 Android&#xff1a;Firebase 凭据 iOS&#xff1a;基于 p8 令牌的 APN 连接 iOS&#xff1a;p12 生成证书 Flutter之对接国外推送onesignal踩坑笔记&a…

基于SSM的平面设计课程在线学习平台系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的平面设计课程在线学习平台系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;…

C++:STL-list模拟实现:迭代器的封装

STL-list模拟实现细节 一. 模拟实现的思想细节1.迭代器实现&#xff1a;用类进行封装2.和--的重载3.奇怪的->重载4.const迭代器 二.实现源码 一. 模拟实现的思想细节 1.迭代器实现&#xff1a;用类进行封装 为什么不使用原生指针&#xff1a; ​ 相比于vector和string&am…

9.Godot数组|遍历|静态变量|对象|调试

数组和字典的遍历 数组的概念 数组是一组数据的集合。在程序中负责批量处理数据。数组中的元素可以包括各个类型的数据&#xff0c;也可以对数组内数据类型进行限定。可以通过 数组名【数字】 的形式来访问数组元素&#xff0c;数字 0 代表数组的第一个元素。数组可以通过调用…

《中学科技》是什么级别的刊物?如何投稿?

《中学科技》是什么级别的刊物&#xff1f;如何投稿&#xff1f; 《中学科技》创刊于1976年&#xff0c;由上海世纪出版&#xff08;集团&#xff09;有限公司主管&#xff0c;上海科技教育出版社有限公司主办的省级学术期刊&#xff0c;《中学科技》以传播科技知识、启迪智慧…
最新文章