聚类分析是一种数据归约技术,旨在揭漏一个数据集中观测值的子类。子类内部之间相似度最高,子类之间差异性最大。至于这个相似度是一个个性化的定义了,所以有很多聚类方法。
最常用的聚类方法包括层次聚类和划分聚类。
每个聚类方法都有优缺点,甚至聚类的时候出现不存在的类,这些方法最好是对照使用。
有效的聚类分析是一个多步骤的过程,每一步的决策都会影响下一步的分析。所以多探索多尝试最重要。
基本步骤:
df1 <- apply(mydata, 2, function(x){(x-mean(x))/sd(x)})
df2 <- apply(mydata, 2, function(x){x/max(x)})
df3 <- apply(mydata, 2, function(x){(x ̢ mean(x))/mad(x)})
?dist
# install.packages("flexclust")
data(nutrient, package="flexclust")
row.names(nutrient) <- tolower(row.names(nutrient))
head(nutrient)
# 缩放数据
nutrient.scaled <- scale(nutrient,center = T,scale = T)
head(nutrient.scaled)
# 计算欧几里得距离
d <- dist(nutrient.scaled)
head(d)
typeof(d)
str(d)
# 将距离数据传入层次聚类函数
# 距离数据
fit.average <- hclust(d, method="average")
plot(fit.average, hang=-1, cex=.8, main="Average Linkage Clustering")
library(NbClust)
# 需要输入需要聚类的数据框,距离计算公式,聚类方法
nc <- NbClust(nutrient.scaled, distance="euclidean",
min.nc=2, max.nc=15, method="average")
table(nc$Best.n[1,]) # 看看多少个指标支持对应的子类个数
有1个指标支持1个子类
有4个指标支持2个子类
有4个指标支持3个子类
有4个指标支持5个子类
Nbcluster推荐聚成2类
# 那就把K设置成 2或者3或者5试试看
clusters <- cutree(fit.average, k=2) # cutree将层次聚类结果划分为5个部分
# 第一个子类包括了26个观测,第二个子类包括了一个观测
table(clusters)
# 利用聚合函数看看原来的数据框
aggregate(nutrient, by=list(cluster=clusters), median) # 主要是calcium的含量区别
# 可视化看看
plot(fit.average, hang=-1, cex=.8,
main="Average Linkage Clustering\n2 Cluster Solution")
rect.hclust(fit.average, k=2)
library(NbClust)
data(wine, package="rattle")
head(wine)
df <- scale(wine[-1])
set.seed(1234)
nc <- NbClust(df, min.nc=2, max.nc=15, method="kmeans")
table(nc$Best.n[1,]) # 3个子类最好
# 或者使用碎石图的方法找拐点,如下代可以实现
wssplot <- function(data, nc=15, seed=1234){
wss <- (nrow(data)-1)*sum(apply(data,2,var))
for (i in 2:nc){
set.seed(seed)
wss[i] <- sum(kmeans(data, centers=i)$withinss)}
plot(1:nc, wss, type="b", xlab="Number of Clusters",
ylab="Within groups sum of squares")
}
wssplot(df)
set.seed(1234)
fit.km <- kmeans(df, 3, nstart=25)
str(fit.km)
size : 每个子类包含的观测数目
iter : 迭代次数
withinss : 子类内部 距离之和
centers: 子类的中心点,都少个变量就会有对应的多少个数值,组成了一个高维的点。可能不好理解,看看看下面的代码。
fit.km$centers
aggregate(wine[-1], by=list(cluster=fit.km$cluster), mean)
library(cluster)
set.seed(1234)
fit.pam <- pam(wine[-1], k=3, stand=TRUE)
fit.pam$medoids
clusplot(fit.pam, main="Bivariate Cluster Plot")
table(wine$Type,fit.pam$clustering)