R语言做K均值聚类的一个简单小例子
参考链接
- https://www.guru99.com/r-k-means-clustering.html
- https://datascienceplus.com/k-means-clustering-in-r/
- https://www.datanovia.com/en/lessons/k-means-clustering-in-r-algorith-and-practical-examples/
k均值聚类是一种比较常用的聚类方法,R语言里做k均值聚类比较常用的函数是kmeans()
,需要输入3个参数,第一个是聚类用到的数据,第二个是你想将数据聚成几类k
,第三个参数是nstart
https://www.datanovia.com/en/lessons/k-means-clustering-in-r-algorith-and-practical-examples/
这篇链接里提到
默认的nstart是1,推荐使用较大的值,以获得一个稳定的结果。比如可以使用25或者50。
那如果想使用k均值聚类的话,就可以分成两种情况,
- 第一种是知道我自己想聚成几类,比如鸢尾花的数据集,明确想聚为3类。这时候直接指定k 下面用鸢尾花数据集做k均值聚类
df<-iris[,1:4]
iris.kmeans<-kmeans(df,centers=3,nstart = 25)
names(iris.kmeans)
iris.kmeans
结果里存储9个结果,可能会用到的是iris.kmeans$cluster
存储的是每个样本被归为哪一类iris.kmeans$size
存储的是每一个大类有多少个样本
使用散点图展示结果,借助factoextra
包中的fviz_cluster()
函数
library(factoextra)
fviz_cluster(object=iris.kmeans,data=iris[,1:4],
ellipse.type = "euclid",star.plot=T,repel=T,
geom = ("point"),palette='jco',main="",
ggtheme=theme_minimal())+
theme(axis.title = element_blank())
作图代码参考 https://degreesofbelief.roryquinn.com/clustering-analysis-in-r-part-2
- 第二种情况是我不知道想要聚成几类,这个时候就可以将k值设置为一定的范围,然后根据聚类结果里的一些参数来筛选最优的结果 比如这篇文章 https://www.guru99.com/r-k-means-clustering.html 他提到可以使用
cluster$tot.withinss
这个参数,选择出现平滑变化的那个点,他起的名字是 elbow method,英文解释是
This method uses within-group homogeneity or within-group heterogeneity to evaluate the variability. In other words, you are interested in the percentage of the variance explained by each cluster. You can expect the variability to increase with the number of clusters, alternatively, heterogeneity decreases. Our challenge is to find the k that is beyond the diminishing returns. Adding a new cluster does not improve the variability in the data because very few information is left to explain.
这个英文解释我也没有看明白。实际操作的代码是
下面用USArrests
这个数据集是美国50个州1973年每10万人中因某种罪被捕的人数,共4个变量
df<-USArrests
kmean_withinss <- function(k) {
cluster <- kmeans(df, k,nstart = 25)
return (cluster$tot.withinss)
}
wss<-sapply(2:20, kmean_withinss)
wss
elbow<-data.frame(A=2:20,B=wss)
library(ggplot2)
ggplot(elbow,aes(x=A,y=B))+
geom_point()+
geom_line()+
scale_x_continuous(breaks = seq(1, 20, by = 1))+theme_bw()
从上图看,7到8好像是变得比较平滑的,那我们先选7看看
usa.kmeans<-kmeans(df,centers=7,nstart = 25)
fviz_cluster(object=usa.kmeans,df,
ellipse.type = "euclid",star.plot=T,repel=T,
geom = c("point","text"),palette='jco',main="",
ggtheme=theme_minimal())+
theme(axis.title = element_blank())
image.png
从图上看划分成7类有点多了
https://www.datanovia.com/en/lessons/k-means-clustering-in-r-algorith-and-practical-examples/
这个链接里提到factoextra
这个包里有一个函数fviz_nbclust()
直接可以选择最优的k
fviz_nbclust(df, kmeans, method = "wss")
从图上看4到5变得平滑了,选择4试一下
usa.kmeans<-kmeans(df,centers=4,nstart = 25)
fviz_cluster(object=usa.kmeans,df,
ellipse.type = "euclid",star.plot=T,repel=T,
geom = c("point","text"),palette='jco',main="",
ggtheme=theme_minimal())+
theme(axis.title = element_blank())
从图上看有部分重叠的地方,还有一种办法就是把数据标准化一下
df1<-scale(df)
usa.kmeans<-kmeans(df1,centers=4,nstart = 25)
fviz_cluster(object=usa.kmeans,df,
ellipse.type = "euclid",star.plot=T,repel=T,
geom = c("point","text"),palette='jco',main="",
ggtheme=theme_minimal())+
theme(axis.title = element_blank())
标准化以后的效果看起来好了很多
好了,今天就到这里了。
- redis 学习笔记(4)-HA高可用方案Sentinel配置
- oracle: job使用
- velocity模板引擎学习(2)-velocity tools 2.0
- java:如何用代码控制H2 Database启动
- 游戏开发完整学习路线(各个版本都有)
- spring mvc4:异常处理
- TCP/IP, WebSocket 和 MQTT
- struts2: 玩转 rest-plugin
- 设置系统环境变量立即生效的VBS脚本
- velocity模板引擎学习(1)
- mybatis 3.x 缓存Cache的使用
- XStream、JAXB 日期(Date)、数字(Number)格式化输出xml
- mac: vmware fusion中cent os启动假死的解决办法
- java:hibernate + oracle之坑爹的clob
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 品优购(IDEA版)-第二天
- 品优购第四天
- 深度学习框架OneFlow的并行特色(附框架源码和教程)
- 图解Java设计模式
- python 如何解决 No module named ‘pip‘问题
- 用多智能体强化学习算法MADDPG解决"老鹰捉小鸡"问题
- 网站日志实时分析之Flink处理实时热门和PVUV统计
- 大数据量下的集合过滤—Bloom Filter
- 实时数仓链路分享:kafka =>SparkStreaming=>kudu集成kerberos
- rocketmq broker启动报错,找不到或无法加载主类
- 视频监控联网RTSP平台EasyNVR用户管理权限与实际权限不匹配,该如何排查?
- 2020CHINC,来赴一场“共建智慧医院”的约会
- 《闲扯Redis十》Redis 跳跃表的结构实现
- 图数据库HugeGraph源码解读 (1) —— 入门介绍
- String及StringTable(一):String源码解读