k均值聚类算法优缺点_Grasshopper实现K均值聚类算法

本文很长很长,有很多很多图,包含以下部分:

1.算法简介

2.如何分类平面点

3.如何分类空间点

4.如何分类多维数据

5.后记

提醒:以下内容包括:智障操作,无中生友,重复造轮子 等

1.算法简介

k均值聚类算法(k-means),这东西是什么意思?

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

我用人话解释一下:

假如你有一些平面上的点,大概如下图。你想把它们分组,离得近的点分到同一组去,离得远的分到不同的组。

9bf1dc43fcffdcf2cd72a97aa306e53c.png

你估摸了一下,大概知道要分9组,别的限制条件一概不知,这时候就非常适合用这种简单粗暴的方法。

方法是这样的:

1.在这些点的范围内,随机取9个点,取名为“聚类中心”。注意,是随机的,想怎么取就怎么取。

850900340e733df1997191405a6686dd.png

2.对每一个点,计算它到9个聚类中心的位置,找到最近的聚类中心,并将其划分到那一组中

3db0c3d310d17da8ea6041579f7c976c.png

9c7d2bf3292bc562dd5f4ae38c8f91f2.png

很明显,分组的情况相当糟糕,毕竟聚类中心是随机的嘛。

3.对每一个组内的点,求出平均点,并将其作为新的聚类中心,在下图中,绿色点是新的聚类中心。

539c90b73796a497558e28d6fc475e6c.png

4.重复2、3的步骤,直到分组情况不再变化

437dc1d8d560b57f02c2b709699a6b7f.gif

这就是k均值聚类算法的平面应用方式,接下来介绍在grasshopper里如何实现它。

2.如何分类平面点

首先画一些点,拾取进grasshopper中;求出这些点的bounding box,以此为边界,使用populate 3d/2d生成9个点作为聚类中心。

fc1dabb9dff93e9762ec00b939e14ee7.png

以聚类中心为起始点,生成泰森多边形,泰森多边形内的点就是被分到该组的点。使用Point In Curve搭配 Cull Pattern实现这一步

(当然,可以计算距离然后排序,这两种方法是等效的。只不过在平面的情况下,这里选择了更直观的方法)

1c9cf16e2b4bdcdda75f520e055871a7.png

使用average,求出各组平均点。

564dbc781114f06b900f008576089f82.png

使用插件anemone,根据上文所述,在Populate 3D后设立循环起点,在average后设立循环终点,并让控制循环的两个电池对应,设立最大循环次数。

d8e7c8d43853d5333df707f0109cb87e.png

OK,完美!我们的“平面kmeans.gh”正式完成!

望着简单优雅的电池图和灵巧变动的迭代动画,电脑前的你获得了前所未有的满足感。

7481f8029a1a982d2643787555425eeb.png

然而,你很快发现这个电池并不完美。

首先它没有显示结果。虽然分组完毕,但是并不直观。

你拖出了Convex Hull,解决了这一问题。

fedb781102520a6af99e388c28b198fa.png

显示分组结果之后你马上发现,即便是迭代了十余次,分组结果已经稳定,这个结果还是不能让你满意。

1317a159102492f9f76d4042b9ad8c21.png

首先,本来是要分9组的,现在它只有8组,;而且右边有两组紧挨着的点,凭什么他们不能分到一组去?

原因在于初始聚类中心上。因为它是随机的,所以可能有一个聚类中心和所有点都距离很远,没有点在它那一组,导致它成了光杆司令。

因为第一次分组它就没有组员,所以以后也不再会有,最终导致结果少了一组。

851ef7d52125050b43cec8db08754297.png

同理,两个聚类中心之间存在一大批点,最终会导致两个中心势均力敌,平分这些点。

2edf3505cd2d9a4cca07f982d8439e91.png

要解决这些问题,只能调整随机的种子,直到结果令人满意。

15429b238d48efd7ccfaa13235263e01.png

解决了分组问题,你隐隐约约觉得还有哪里不对劲,没错,就是循环的部分。

现在,运算结果会不停迭代直至最大次数,这就面临着“最大迭代次数设置为多少是合适的”的问题。太大,浪费资源;太小,分组情况不稳定。一般来说,人们习惯性地设为100,当然这只是权宜之计,略有强迫症的你决定做出可以终止迭代的部分。

根据算法定义,当分组情况不变时,停止迭代。

Loop End电池的exit端等于TRUE时,停止迭代。

也就是说,比较一下本次运算和上次运算时的分组情况,如果相同,则输出true到exit端。

“分组情况”是什么?

89768c8334ed0a67e59f36fd2564bd35.png

是每一组内点的数量(列表长度)。把这些数据转换成一个数据,而且还能避免误判的一个最简便的方式,就是Construct Path。

4e936c7bdaef2fb5d1730fcc6bb92c91.png

这样,“分组情况”就能被一行唯一的文字代表,只要用match text把它和上一次迭代时的文字比较就行了。

但是可惜,anemone没有查看迭代过程中的上次数据的功能,(如果有,请教教我)只能自己做了。如下图:

5621fab27e47b85b0b22f0ed9e9adcca.png

这一部分是什么意思呢?

Data Recorder记录所有通过的数据。

List Item列出本次和上次迭代的文字。

Replace Nulls是为了用随便什么别的文字替换掉null。因为如果Data Recorder记录的数据不足两个,list item的-1端会和i端一致,使得循环结束,所以必须将wrap设为false;这样就导致-1端会变成null,所以必须将它替换掉。

最后就是match text,当两输入端一致时输出true,搞定。

最终成果如下

f9094cdf1cf0a98ddf08e68b3311cdbb.png

OK,完美!我们的“平面kmeans改.gh”正式完成!

望着简单粗暴的电池图和完全自动的迭代过程,电脑前的你获得了前所未有的满足感。

7481f8029a1a982d2643787555425eeb.png

随着鼠标的一阵抖动,整个电池图索然无味。

处于贤者时间的你不禁想到,这个方法可以拓展到3维空间里吗?


3.如何分类空间点

灵巧的双手穿针引线,类比的思维高速运转——顷刻,能够处理空间点的电池组横空出世,它在算法上完全继承了“平面kmeans改.gh”的衣钵:

127024f5c7171afd58f3164806b68f94.png

b0657cbe7815f15fa8a9637ecd16d575.gif

2f3d818a223de4059e0f85a3fab0f161.gif

但是,麻烦也如期而至——会建立曲面的Voronoi 3D 和求交集的Point In Brep两个电池大大拖慢了运算速度。在平面情况下,这种方法的劣势还不明显,现在则已经成为必须要解决的问题了。

b268e06cc9a7936dbdb8b26f8cf93557.png

所以只能根据定义中的计算方式来分组了。

首先调整数据结构,计算点到聚类中心的距离,依照距离将聚类中心排序

a3537516d1babdb82a9f42d86cc0f20e.png

可见,现在有1295个点,23个聚类中心,每一条路径都代表着一个点,路径内的23个点依照距离从小到大排列。

重点来了。现在提取每一条路径中的第一个数据——那是距离某一个特定点最近的聚类中心。

现在有1295条路径,也就是每一个点都从23个聚类中心里面,找到了一个距离它最近的。

之后将它flatten,使用Create Set、Member Index和List Item素质三连,就得到了分好组的点。

d46c3a0532e35dd854d7f5611e5dedc1.png

这套连招究竟做了什么?是什么原理?

看一下flatten后的数据。有1295个点物件,他们是1295个点各自对应的最近的聚类中心。

目标是:将要处理的点分组,对应同一个聚类中心的点处在相同路径下。

97dd563f77972cb0c8832569f0057653.png

很明显,图中有很多的重复点,使用Create Set得到一个没有重复点的集合,该集合有23个点物件,正是那23个聚类中心。

c5592bedcd707786fed588dca9193c34.png

Member Index的功能是:对于某个列表中的数据,返回它在这个列表中的索引。输入23个独特的聚类中心,输出这23个聚类中心在原列表中的索引。在原列表中,每个聚类中心都重复了很多次,所以,索引的数目一共1295个。

68eec71773161eb5a0001f45ce6df9c3.png

既然有了索引,只需要用List Item将数据取出来就好了,只不过这次输入的列表要是待处理的点

7bccc11fe354c69e422f3481f9a07b2d.png

费了老鼻子劲,终于得到了分好组的点,接下来只要照搬原先写好的电池就行了。

最终结果如下:

3d2ee1b7a0004ceb97c1bf516f8e3403.png

6ecb6497232ef216b7c5cad17968b90a.gif

OK,完美!我们的“空间kmeans.gh”正式完成!

望着精准高效的电池图和高端酷炫的迭代过程,电脑前的你获得了前所未有的满足感。

7481f8029a1a982d2643787555425eeb.png

随着鼠标的一阵抖动,整个电池图索然无味。

处于贤者时间的你不禁想到,平面点由xy坐标确定,凡是有两个属性的数据(比如某人的身高和体重)就可以用唯一的平面点来代表;同理,有三个属性的数据(比如某人的三围)就可以用唯一的空间点来代表。

而你刚刚做出了可以给这些点自动分类的算法,虽然不知道有什么用——

但是电脑前的你还是获得了前所未有的满足感。

不过你很快就意识到,现实中的数据基本上都有三个及以上的属性,如果不将算法拓展到n维空间,也就无法处理这些数据,算法的能力将大大减弱——而且这个算法本来就不局限于三维空间坐标。

但是由于grasshopper自身的限制,它不支持多维空间中的点和向量。

即便如此,你还是在想:到底能不能拓展到n维空间中呢?

4.如何分类多维数据

幸运的是,grasshopper在关闭一扇门的同时,也打开了一扇窗——

矩阵

32a6f41ae541841214dbeb0b115207c9.png

虽然grasshopper不支持n维向量,但是可以用1行n列的矩阵来代替。通过把多维空间中的点转化成矩阵,你看到了希望。

很快,麻烦来了:

由于人不能理解多维空间,数据的可视化就成了一个大难题。不过可以通过在空间点上附加额外的属性来表示多维点——比如在空间点上画球,用球的半径代表第四维数据

54f3530f2bb0dda3875b8125b95462f0.png

空间点上画立方体,用立方体的长宽高代表第四、五、六维数据

e4272ea98dffb3dc4b4077b2a6a7efc8.png

此外,生成随机点的部分也不再多维点中适用,只能手动求出各维度数据区间,生成随机数再合成一个多维点。下图是 生成随机矩阵和将多维点转化为矩阵的部分。

7428e95dfe5abb2427103b95bb8c5d40.png

由于矩阵不是几何物件,不能用Distance计算距离,若要求矩阵所代表的多维点的欧氏距离,则需要手动计算。而且矩阵本身又自带一层数据结构,处理起来相当麻烦。下图是计算距离的部分。

f92ae433f8dc8721be590d62403caae5.png

其他部分都和三维kmeans相似。

不知过了多长时间,重启了多少次grasshopper,数据结构出错多少次,终于,电池运行成功了。

在最终结果如下:

fe54cf29e4ee88e4bc48a56934edd2d1.png

20a4ae19252a3586121995cc660ea4e2.png

稍加改动,就可以直接从Excel中导入数据并计算了。

caf72d52b69a7c29702430bbf337f83c.png

OK,完美!我们的“多维kmeans.gh”正式完成!

5.后记

望着并不复杂的电池图和前途无量的算法,电脑前的你获得了前所未有的满足感。

7481f8029a1a982d2643787555425eeb.png

随着鼠标的一阵抖动,整个电池图索然无味。

处于贤者时间的你不禁想到,整个过程可以写成文章发到知乎上,或许能帮到别人。

在码字之前,你觉得,也许应该问问之前是否有人做过类似的事情,通过对比学习,一定大有收获。

a545468b2631d0db1428176239f9662c.png

受群友的指引,你下载了owl和最新版的Lunchbox

https://www.food4rhino.com/app/owl

https://provingground.io/tools/lunchbox/download-lunchbox-for-grasshopper/

打开插件的一瞬间,空气凝固了

c04828c2e6a73255a312478b53c01a1c.png

30c6e0e8b668a51fd0feb0647dd33414.png

你倚在阳台上,晚风试图把你从无奈中解救出来。

效果并不怎样。用grasshopper久了,就连月亮都看起来有两个输入端。

“如果我的脑袋是一个电池的话,输出端一定是水。”你抱着这样的想法坐回电脑前。

你没有放弃写知乎,只不过,在羞耻和自嘲的怂恿下,文章用的是第二人称的视角。

文件下载:https://pan.baidu.com/s/1PYaVuVw7dIViXYVeLk0kTQ

提取码:75u1

需要lunchbox(读取Excel)

需要meshedit(建立三维点分组预览)

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

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

相关文章

fullgc频繁的原因_系统运行缓慢,CPU 100%,Full GC次数过多,这一招帮你全搞定

处理过线上问题的同学基本上都会遇到系统突然运行缓慢,CPU 100%,以及Full GC次数过多的问题。当然,这些问题的最终导致的直观现象就是系统运行缓慢,并且有大量的报警。本文主要针对系统运行缓慢这一问题,提供该问题的排…

WEKA “Detailed Accuracy By Class”和“Confusion Matrix”含义

原文 Summary (总结)Correctly Classified Instances(正确分类的实例) 45 90 %Incorrectly Classified Instances (错误分类的实例) 5 10 %Kappa …

es删除数据_面试官是怎么来考察你对ES搜索引擎的理解?

来源:http://1t.click/ZdY一. 面试官心理分析问这个,其实面试官就是要看看你了解不了解 es 的一些基本原理,因为用 es 无非就是写入数据,搜索数据。你要是不明白你发起一个写入和搜索请求的时候,es 在干什么,那你真的是…

一个分布式服务器集群架构方案

0x01.大型网站演化 简单说,分布式是以缩短单个任务的执行时间来提升效率的,而集群则是通过提高单位时间内执行的任务数来提升效率。 集群主要分为:高可用集群(High Availability Cluster),负载均衡集群(Load Balance Cluster&…

python数据预处理_Python数据预处理——缺失值、重复值

一、缺失值处理 isnull( ) 、fillna( ) 、dropna( )(1)查看缺失查看数据集缺失,返回每列的缺失个数 df.isnull().sum() 查看某字段有缺失的行 df[df.a.isnull()] 查看某字段每行的缺失情况:返回T/F:df.score.isnull() …

vb如何测试连接mysql_VB怎么连接访问Access数据库?

VB是我们常常会见到的一款可视化程序设计语言,它的功能十分强大,因此有很多人会使用它,但是有时候我们需要用到VB来连接Access数据库,但是却无从下手,那么VB怎么连接访问Access数据库呢?不懂的朋友请看以下…

textarea如何在文字后面_FLASH如何制作风吹文字的效果

使用动作补间动画可以制作各种各样的动态效果,树叶飘落、蝴蝶飞舞等。这里再使用引导层动画结合动作补间动画制作风吹文字飞起的效果。主要知识点:引导层动画、动作补间动画FLASH如何制作树叶飘落​jingyan.baidu.comFlash如何制作飞舞的蝴蝶​jingyan.b…

ef mysql 外键 一对一_EFCore-一对一配置外键小记2

前后两次遇到这样的错误:The property xx on entity type xxxx has a temporary value. Either set a permanent value explicitly or ensure that the database is configured to generate values for this property.多数情况下是表配置关系会出现这样的问题。我实…

矩阵快速幂 HDU3483

1 #include <iostream>2 #include <cstring>3 4 using namespace std;5 6 //矩阵大小上限7 const int SIZ100;8 int MOD;9 10 //矩阵大小为n*m&#xff0c;初始化全部为011 struct mat12 {13 int n,m;14 long long ar[SIZ][SIZ];15 mat()16 {17 …

哲学家就餐问题python_Python实现哲学家就餐问题实例代码

哲学家就餐问题&#xff1a; 哲学家就餐问题是典型的同步问题&#xff0c;该问题描述的是五个哲学家共用一张圆桌&#xff0c;分别坐在五张椅子上&#xff0c;在圆桌上有五个盘子和五个叉子&#xff08;如下图&#xff09;&#xff0c;他们的生活方式是交替的进行思考和进餐&am…

fpga摄像头模块_FPGA开源项目:双目测距(一)之双目图像采集显示以及图片保存...

1.简述这个项目是大三下学期暑假(也就是2019年8份)完成的&#xff0c;当时的视频效果已发布在bilibili上&#xff0c;这是我们的省级的科研立项&#xff0c;其实就我一个人负责完成。发布bilibili后很多人比较感兴趣&#xff0c;打算年初回学校完成毕设期间开源的&#xff0c;一…

github ssh 配置_Github远程仓库克隆更新本机,SSH协议免密操作配置和注意事项

Github远程仓库-克隆远程仓库到本机 【重点】目标如何克隆远程仓库到本机呢&#xff1f;小结下载项目的命令&#xff1a;git clone https://gitee.com/kekesam/sassweb777.git注意&#xff1a;1&#xff1a;它会自动创建本地仓库&#xff1b;2&#xff1a;它也会自动和远程仓库…

golang中文文档_【译】Go 语言源码贡献官方指导文档

以前给 Go 语言项目源码提交过一些 commits&#xff0c;期间阅读他们的官方指导文档的时候觉得这篇指导文档可以作为绝佳的关于大型软件项目的规范管理的参考&#xff0c;因为最近又提交了几个 commits&#xff0c;就又把这篇文档再看了一遍&#xff0c;有感于 Go 团队在项目管…

mysql增加最大连接数_mysql最大连接数怎么设置

设置mysql最大连接数的方法&#xff1a;首先打开mysql的控制台&#xff1b;然后输入语句【set GLOBAL max_connections1000;】即可直接设置最大连接数。通常&#xff0c;mysql的最大连接数默认是100, 最大可以达到16384&#xff1b;如果我们想修改mysql的最大连接数&#xff0c…

让一个动画一直执行的属性是_iOS 动画 一

View AnimationsAnimatable properties• bounds: 改变 bounds 属性可以在当前 view 内改变子视图等的相对位置。• frame: 改变 frame 可以移动或者缩放 view 。• center: 当你想移动 view 到屏幕的新位置时&#xff0c;可以改变此属性。• backgroundColor: 背景颜色。• al…

阿里云java mysql环境_阿里云搭建centos java mysql nginx环境

1.上传下载yum install lrzszsz下载rz上传2.安装压缩命令yum install -y unzip zip;3.安装javarpm -ivh jdk-8u161-linux-x64.rpm4.安装mysqlyum install libaioyum -y remove mariadb-libs-5.5*rpm -ivh mysql-community-common-5.7.21-1.el7.x86_64.rpmrpm -ivh mysql-commun…

ide快捷键_一款好用的IDE怎么可以没有代码提示?

我在使用过IntelliJ IDEA(一款Java开发工具)之后&#xff0c;感觉Delphi的IDE在编写代码方面尤其是代码提示方面和IntelliJ IDEA相比真的天差地别&#xff0c;所以决定认真的研究一下Delphi的代码提示功能一般情况下我们使用Delphi的开发工具都会安装cnpack专家包&#xff0c;但…

IOS开发学习记录第4天之C语言学习

&#xff08;一&#xff09;、今天我们要学习的主要包括一下内容&#xff1a; 1、标示符概念及其命名原则 在C语言中&#xff0c;符号常量&#xff0c;变量&#xff0c;数组&#xff0c;函数等都需要一定的名称&#xff0c;我们把这种名称称之为标识符。 标识符划分&#xff1a…

mysql pmm 布署_给 mysql 安装 pmm 监控

PMM 说明PMM(Percona Monitoring and Management) 是一款监控和分析 MySQL 服务的一套工具&#xff0c;可以从图形化的方式看到 MySQL 服务的各种性能指标&#xff0c;慢查询分析、连接数、线程状态、查询信息、缓存信息等等&#xff0c;对分析 MySQL 运行时问题很有帮助。PMM …

java 自定义注解_Java注解

前言近日在阅读开源项目&#xff0c;发现项目里好多奇奇怪怪的注解(DataScope、Log...)看得我一脸懵&#xff0c;不知道大家是否也有过这样的经历&#xff0c;回想了一下&#xff0c;发现自己对于注解的知识&#xff0c;好像只停留在Override。。。异常尴尬&#xff0c;所以今天…