目录
聚类相关理论
动态聚类vs系统聚类
基本思想
基本操作步骤_系统聚类
基本操作步骤_动态聚类
重要距离
R语言代码实现_层次聚类
R语言代码实现_kmeans聚类
R语言代码实现_KNN聚类
聚类相关理论
聚类分析是研究分类问题的多元统计方法。主要分为层次聚类(即系统聚类)和动态聚类。
合理的聚类的关键:使得同一类别内的观测尽可能地“相似”,但不同类别之间有明显区分。
动态聚类vs系统聚类
系统聚类法是一种比较成功的聚类方法。然而当样本点数量十分庞大时,则是一件非常繁重的工作,且聚类的计算速度也比较慢。比如在市场抽样调查中,有4万人就其对衣着的偏好作了回答,希望能迅速将他们分为几类。这时,采用系统聚类法就很困难,而动态聚类法就会显得方便,适用。动态聚类使用于大型数据。
基本思想
系统聚类:先将n个样品各自看成一类,然后规定样品之间的“距离”和类与类之间的距离。选择距离最近的两类合并成一个新类,计算新类和其它类(各当前类)的距离,再将距离最近的两类合并。这样,每次合并减少一类,直至所有的样品都归成一类为止。
动态聚类:选取若干个样品作为凝聚点,计算每个样品和凝聚点的距离,进行初始分类,然后根据初始分类计算其重心,将重心作为新的凝聚点再进行第二次分类,一直到所有样品不再调整为止。
基本操作步骤_系统聚类
1. 计算n个样品两两间的距离
2.构造n个类,每个类只包含一个样品。
3. 合并距离最近的两类为一新类。
4. 计算新类与各当前类的距离。
5. 重复步骤3、4,合并距离最近的两类为新类,直到所有的类并为一类为止。
6. 画聚类谱系图。
7. 决定类的个数和类。
基本操作步骤_动态聚类
1.选择凝聚点
2.初始分类:以每个凝聚点为类别中心,将其他观测按照距离最近原则归入凝聚点类别。
3.调整分类:得到初始分类,计算各类的重心,以这些重心作为新的凝聚点,重新进行分类,重复步骤2、3,直到分类的结果与上一步的分类结果相同,表明分类已经合理为止。
重要距离
相似度的度量:明氏距离(街区距离、欧氏距离、切比雪夫距离)、标准化欧式距离、马氏距离。
类的合并方法(类与类之间的距离):最短距离法(也叫简单连接法)、最长距离(也叫完全连接法)、中间距离(也叫平均连接法)、重心法(重心连接法) 、类平均法、离差平方和(Ward法)。
R语言代码实现_层次聚类
dist几种距离:"euclidean"欧氏距离, "maximum", "manhattan", "canberra"坎贝拉距离, "binary"二进制距离 or "minkowski"闵可夫斯基距离。
#距离矩阵的生成
data(iris)
head(iris)
rownames(iris)=paste0("x_",1:150)
#生成距离矩阵
d = dist(iris[,1:4],method = "euclidean")
class(d)
#d
md = as.matrix(d)
#md
系统聚类的核心函数 hclust(d, method = "complete", members = NULL)
其中 d:为距离矩阵 ;method: 表示类的合并方法
- single最短距离法: 一个类中的点和另一个类中的点的最小距离
- complete最长距离法: 一个类中的点和另一个类中的点的最大距离
- median中间距离法: 一个类中的点和另一个类中的点的平均距离
- mcquitty相似分析法
- average平均距离法:测量两类每对观测间的平均距离
- centroid重心法:两类间的距离定义为两类重心之间的距离
- ward离差平方和法:基于方差分析思想,如果分类合理,则同类样品间离差平方和应当较小,类与类间离差平方和应当较大
#系统聚类
iris.hc1 <- hclust(d,"single")
print(iris.hc1)
plot(iris.hc1,hang = -1)
#plot(iris.hc1,hang = -1,cex=0.9)
iris.hc2 <- hclust(d,"complete")
print(iris.hc2)
plot(iris.hc2,hang = -1)
iris.hc3 <- hclust(d,"ward.D")
print(iris.hc3)
plot(iris.hc3,hang = -1)
par(mfrow=c(1,3))
plot(iris.hc1,hang = -1)
plot(iris.hc2,hang = -1)
plot(iris.hc3,hang = -1)
#将聚类结果划分
par(mfrow=c(1,1))
plot(iris.hc1,hang = -1)
#rect.hclust为聚类分析结果画框
rect.hclust(iris.hc1,k=3, border = "red")
re1 <- rect.hclust(iris.hc1,k=3)
re1
plot(iris.hc1,hang = -1)
rect.hclust(iris.hc1, h=0.75,which=c(1,3))
rect.hclust(iris.hc1, h=0.75,which=c(1,3), border =c("green","red"))
re2 <- rect.hclust(iris.hc1, h=0.75,which=c(1,3), border = 2:3)
re2
# 返回值的标签,根据分类数
iris.id1 <- cutree(iris.hc1,k=3);iris.id1
#iris.id1 <- cutree(iris.hc1,h=0.31);iris.id1
#iris.id1 <- cutree(iris.hc1,k=2:5);iris.id1
table(iris.id1)
#返回值的标签,根据分类数
iris.id2 <- cutree(iris.hc2,k=3);iris.id2
table(iris.id2)
#查看与已有标签对比,参考聚类效果
table(iris$Species)
table(iris.id1,iris$Species)
table(iris.id2,iris$Species)
#查看原始数据分布情况
plot(iris$Sepal.Length,iris$Sepal.Width)
plot(iris$Sepal.Length,iris$Sepal.Width,col=iris$Species)
plot(iris[,1:4],col=iris$Species)
#如果觉得横坐标标签太多了,可以去掉
plot(iris.hc1,labels = FALSE,hang = -1)
R语言代码实现_kmeans聚类
核心函数 kmeans(x, centers, iter.max = 10, nstart = 1,algorithm = c("Hartigan-Wong", "Lloyd", "Forgy", "MacQueen"), trace=FALSE)
其中 x:数据矩阵 ;centers: 类别数或各类初始中心;iter.max 最大迭代次数,nstart:随机起点数。
#kmeans 聚类
km1 = kmeans(iris[,1:4],3)
km1
km1$cluster
km1$centers
km2 = kmeans(scale(iris[,1:4]),3,nstart = 25)
km2
table(km2$cluster,iris$Species)
table(km1$cluster,iris$Species)
R语言代码实现_KNN聚类
核心函数KNN(x, k, sort = TRUE, search = "kdtree", bucketSize = 10, splitRule = "suggest", approx = 0);
install.packages("dbscan");
library(dbscan);
#去掉种属列
iris2 <- iris[, -5];
head(iris2);
#查询最近邻的5个点
nn <- kNN(iris2, k=5);
nn;
#查询nn的属性列表
attributes(nn);
head(nn$id); ##索引值
head(nn$dist); ##距离值
#设置索引
idx<-33;
#打印与33,最近邻的5个点的索引
nn$id[idx,];
#画图
cols = ifelse(1:nrow(iris2) %in% nn$id[idx,],"red", "black")
cols[idx]<-'blue'
plot(iris2,pch = 19, col = cols)
plot(nn, iris2)
plot(kNN(nn, k = 2), iris2)