我一直在使用 k-means 在 R 中对我的数据进行聚类,但我希望能够使用贝西信息准则 (BIC) 和 AIC 评估我的聚类的拟合与模型复杂性。目前我在 R 中使用的代码是:
KClData <- kmeans(Data, centers=2, nstart= 100)
但我希望能够提取 BIC 和对数似然。任何帮助将不胜感激!
我一直在使用 k-means 在 R 中对我的数据进行聚类,但我希望能够使用贝西信息准则 (BIC) 和 AIC 评估我的聚类的拟合与模型复杂性。目前我在 R 中使用的代码是:
KClData <- kmeans(Data, centers=2, nstart= 100)
但我希望能够提取 BIC 和对数似然。任何帮助将不胜感激!
对于其他登陆这里的人,Sherry Towers 在http://sherrytowers.com/2013/10/24/k-means-clustering/提出了一种方法,该方法使用来自stats::kmeans
. 我引用:
可以使用以下函数计算 AIC:
kmeansAIC = function(fit){ m = ncol(fit$centers) n = length(fit$cluster) k = nrow(fit$centers) D = fit$tot.withinss return(D + 2*m*k) }
从 的帮助中stats::AIC
还可以看到,BIC 的计算方法与 AIC 类似。获取 BIC 的一种简单方法是return()
将上述函数中的 替换为:
return(data.frame(AIC = D + 2*m*k,
BIC = D + log(n)*m*k))
因此,您将按如下方式使用它:
fit <- kmeans(x = data,centers = 6)
kmeansAIC(fit)
要计算 BIC,只需将.5*k*d*log(n)
(其中k
是平均值的数量,d
是数据集中向量的长度,以及n
数据点的数量)添加到标准 k-means 误差函数。
标准的 k-means 惩罚是\sum_n (m_k(n)-x_n)^2
,其中m_k(n)
是与第 n 个数据点相关的平均值。这个惩罚可以解释为对数概率,所以 BIC 是完全有效的。
BIC 只是在与 成比例的 k 均值误差上添加了一个额外的惩罚项k
。
只是为了添加 user1149913 所说的内容(我没有足够的声誉来发表评论),因为您在 R 中使用了 kmeans 函数,\sum_n (m_k(n)-x_n)^2
因此已经为您计算了KClData$tot.withinss
.
我们可以为对象定义一个对数似然函数,而不是重新实现AIC
or ;这将被包中的函数使用。BIC
kmeans
BIC
stats
logLik.kmeans <- function(object) structure(
-object$tot.withinss/2,
df = nrow(object$centers)*ncol(object$centers),
nobs = length(object$cluster)
)
然后使用它,BIC
正常调用。例如:
example(kmeans, local=FALSE)
BIC(cl)
# [1] 26.22842084
此方法将在stackoverflow
软件包的下一个版本中提供。
一个函数qualityCriterion::longitudinalData可以计算 k-means 集群的 BIC 和 AIC。它首先计算每个集群中心在每个个体上的可能性,然后再与集群大小的权重合并。正态密度函数的 sd 基于 RSS。
虽然原始代码给出了 -BIC 而不是 BIC,但我采用了 BIC 的代码:
qualityCriterion <- function (traj, clusters)
{
if (nrow(traj) != length(clusters)) {
stop("[qualityCriterion] the cluster and the number of trajectory should be the same.")
}
clusters <- as.integer(clusters)
nbIndiv <- nrow(traj)
nbTime <- ncol(traj)
nbClusters <- length(unique(clusters))
# Cluster frequency
preProba <- as.numeric(table(clusters))
preProba <- preProba / sum(preProba)
# Centers as cluster means
moy <- matrix(, nbClusters, nbTime)
for (i in 1:nbClusters) {
moy[i, ] <- apply(traj[as.numeric(clusters) == i, , drop = FALSE], 2, meanNA)
}
# sd of residuals
ecart <- sqrt(mean(as.numeric(traj - moy[clusters, ])^2, na.rm=TRUE))
# likelihood
vraisIndivXcluster <- matrix(, nbIndiv, nbClusters)
for (i in 1:nbClusters) {
vraisIndivXcluster[, i] <- preProba[i] * apply(dnorm(t(traj), moy[i, ], ecart),
2, prod, na.rm = TRUE
)
}
vraisIndivXcluster <- apply(vraisIndivXcluster, 1, sum)
logVraisemblance <- sum(log(vraisIndivXcluster))
nbParam <- nbClusters * nbTime + 1 # cluster centers and sd
#BIC <- -2 * logVraisemblance + nbParam * log(nbIndiv) # BIC for time series
BIC2 <- -2 * logVraisemblance + nbParam * log(nbIndiv * nbTime) # BIC for independent columns
AIC <- 2 * nbParam - 2 * logVraisemblance
#AICc <- AIC + (2 * nbParam * (nbParam + 1)) / (nbIndiv - nbParam - 1) # AICc for time series
#AICc2 <- AIC + (2 * nbParam * (nbParam + 1)) / (nbIndiv * nbTime - nbParam - 1) # AICc for independent columns
return(list(criters = c(BIC2 = BIC2, AIC = AIC)))
}
100 个个体的示例,每个个体有 2 个数据点,形成 3 个集群:
set.seed(1)
dat <- matrix(rnorm(100 * 2), nrow = 100, ncol = 2) # data of 100 individuals
dat[34:66,] <- dat[34:66,] + 4
dat[67:100,] <- dat[67:100,] + 8
plot(dat[,1], dat[,2]) # 3 cluster centers at (0,0), (4,4), (8,8)
正如预期的那样,k = 3 个集群时的最小 BIC:
# k-means with k = 2:5
clusters_2 <- kmeans(dat, centers = 2)
clusters_3 <- kmeans(dat, centers = 3)
clusters_4 <- kmeans(dat, centers = 4)
clusters_5 <- kmeans(dat, centers = 5)
BIC <- c(qualityCriterion(dat, rep(1, nrow(dat)))$criters["BIC2"],
qualityCriterion(dat, clusters_2$cluster)$criters["BIC2"],
qualityCriterion(dat, clusters_3$cluster)$criters["BIC2"],
qualityCriterion(dat, clusters_4$cluster)$criters["BIC2"],
qualityCriterion(dat, clusters_5$cluster)$criters["BIC2"]
)
plot(1:5, BIC, xlab = "k", ylab = "BIC")
lines(1:5, BIC)