基于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 = dfm, 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 = distancecluster = jclusterShip.append(cluster)if  clusterCount.get(cluster) == None:clusterCount[cluster] = 1else: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 = 10for 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 = distancecluster = j# 重新判断某个点属于哪个类,如果不再属于以前的类,则把这个点的类别更新,且更新类的个数的dictif clusterShip[i] != cluster:oldCluster = clusterShip[i]clusterShip[i] = clusterclusterCount[cluster] += 1clusterCount[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.mzph.cn/web/1088.shtml

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

相关文章

ubuntu在xshell中使用快捷方式操作命令,减少命令行的数入量

第一步 第二步 然后无脑确定 第三步 在xshell的显示方式 方式一 这样就会在每个窗格中进行显示 方式二 效果显示–> 这种窗格的显示是全局的 然后你双击这个process就会自动把命令打在命令行上&#xff0c;减少你的输入量

Oracle数据库Bug:相关子查询多层嵌套报错:标识符无效

Oracle Bug? 一、案例描述二、解决方案<一>、升级版本<二>、改写语句 一、案例描述 在Mysql中常常有如下写法用相关子查询 order by desc limit 1来完成需求 select code,date,(select value from test t1 where t.code t1.code and t1.date between date_su…

【Gradle如何安装配置及使用的教程】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

新型大数据架构之湖仓一体(Lakehouse)架构特性说明——Lakehouse 架构(一)

文章目录 为什么需要新的数据架构&#xff1f;湖仓一体&#xff08;Lakehouse&#xff09;——新的大数据架构模式同时具备数仓与数据湖的优点湖仓一体架构存储层计算层 湖仓一体特性单一存储拥有数据仓库的查询性能存算分离开放式架构支持各种数据源类型支持各种使用方式架构简…

递归求阶乘和(不熟悉)

本题要求实现一个计算非负整数阶乘的简单函数&#xff0c;并利用该函数求 1!2!3!...n! 的值。 函数接口定义&#xff1a; double fact( int n ); double factsum( int n ); 函数fact应返回n的阶乘&#xff0c;建议用递归实现。函数factsum应返回 1!2!...n! 的值。题目保证输…

快速访问github

修改本地hosts文件 GitHub访问慢的原因在于域名解析&#xff0c;通过修改本地的hosts文件&#xff0c;将远程DNS解析改为本地DNS解析。 fang 步骤1&#xff1a;打开hosts文件&#xff08;没有就创建&#xff09; host所在位置&#xff1a; C:\Windows\System32\drivers\etc…

1031:反向输出一个三位数

#include<bits/stdc.h> using namespace std; int main() {int a;cin>>a;cout<<a%10;cout<<a/10%10;cout<<a/100%10;return 0; } 时间限制: 1000 ms 内存限制: 65536 KB 提交数:146171 通过数: 89399 【题目描述】 将一个三位数反向…

linux@内核@内核版本发展@镜像文件查看内核

文章目录 linux内核介绍简介小结 linux发行版和内核各个linux发行版和内核的关系内核更新追踪GAHWE版的内核 内核版本查看&#x1f60a;linux当前系统内核查看未安装时查看网络搜索内核版本号挂载镜像查看虚拟机启动镜像体验版查看内核版本 linux(内核)版本演进&#x1f60a;相…

python_列表和元组

介绍 列表&#xff08;List&#xff09;和元组&#xff08;Tuple&#xff09;是Python中两种不同的数据结构&#xff0c;它们都可以用来存储一系列的元素。下面是它们的主要特点和区别&#xff1a; 列表&#xff08;List&#xff09; 可变性&#xff1a;列表是可变的&…

【c基础】文件操作

1.fopen和fclose函数 函数原型 FILE *fopen(const char *path, const char *mode); 参数解释&#xff1a; 返回值&#xff1a;fopen打开成功&#xff0c;则返回有效file的有效地址&#xff0c;失败返回NULL。path是文件路径&#xff0c;可以相对路径&#xff0c;可以绝对路径…

C# 将 TextBox 绑定为 KindEditor 富文本

目录 关于 KindEditor 绑定设计 部署 KindEditor 实现代码 小结 关于 KindEditor KindEditor 基于JavaScript 编写&#xff0c;可以与众多WEB应用程序结合。KindEditor 依靠出色的用户体验和领先的技术提供富文本编辑功能&#xff0c;是一款非常受欢迎的HTML在线编辑器。…

400电话如何对接配置SIP

400电话对接配置SIP的基本步骤 要配置400电话对接SIP&#xff0c;通常需要遵循以下基本步骤&#xff1a; 注册和认证&#xff1a;首先需要在相应的云通信平台上注册账号&#xff0c;并进行企业实名认证。 开通语音服务&#xff1a;在通过认证后&#xff0c;需要开通语音服务&…

(007)Blender 根据顶点组分离模型

1.选中模型&#xff0c;并且进入【3D视图】【编辑模式】&#xff1a; 2.选择顶点组&#xff1a; 3.分离选中项&#xff1a;

【经验总结】Jupyter 配置内核

1. 背景描述 使用 国家超算互联网中心 的服务器&#xff0c;创建 jupyterlab 容器&#xff0c;想在之前 conda 创建的环境中运行&#xff0c;可是不行&#xff0c;进入容器就直接进入 jupyterlab 2. 解决方法 配置内核 2.1 激活环境 conda activate peft2.2 安装内核 pip…

易保全网络赋强公证系统,前置预防、快速化解债权纠纷

网络赋强公证是一种创新的法律服务模式&#xff0c;为金融机构和债权人提供了一种便捷、高效的债权保障方式。既可以加大对违约方的司法震慑力&#xff0c;又能降低维权方实现债权的风险&#xff0c;且执行时间更快&#xff0c;债权周期更短&#xff0c;诉讼费用更低&#xff0…

Oracle函数

Oracle 函数 一、SQL函数分类 二、单行函数字符函数数字函数日期函数转换函数to_charto_numberto_date 其它函数单行函数嵌套 三、组函数数据分组创建分组过滤分组&#xff08;having子句&#xff09;分组和排序 Selecct子句顺序 一、SQL函数 函数一般是在数据上执行的&#x…

AttributeError: can‘t set attribute ‘lines‘

目录 报错代码&#xff1a; 解决方法&#xff1a; 示例完整代码&#xff1a; 报错代码&#xff1a; ax.lines [] 解决方法&#xff1a; 当你尝试使用 ax.lines [] 来清除一个图表的线条&#xff0c;并遇到 AttributeError: cant set attribute 错误时&#xff0c;这表明…

Spring AI ETL 流水线

先纠正 Spring AI 使用本地 Ollama Embeddings 中的一个错误&#xff0c;当启动 Ollama 之后&#xff0c;Windows会有托盘图标&#xff0c;此时已经启动了 Ollama 的服务&#xff0c;访问 Embedding 时不需要运行 ollama run gemma &#xff0c;只有访问 chat 时才需要启动一个…

React脚手架的搭建与使用

React脚手架是开发现代Web应用的必备&#xff0c;其充分利用Webpack、Babel、ESlint等工具辅助项目的开发&#xff0c;当然这些工具也无需手动配置即可使用&#xff0c;脚手架的意义更多的是关注的是业务而不是工具的配置&#xff1b;项目的整体技术架构为&#xff1a;react w…

ZYNQ NVME高速存储之EXT4文件系统

前面文章分析了高速存储的各种方案&#xff0c;目前主流的三种存储方案是&#xff0c;pcie switch高速存储方案&#xff0c;zynq高速存储方案&#xff0c;fpga高速存储方案。虽然三种高速存储方案都可以实现高速存储&#xff0c;但是fpga高速存储方案是最烂的&#xff0c;fpga…