在k模式聚类后为新数据分配聚类的简单方法

问题描述

我正在使用由数据帧mymodel创建的k模式模型(mydf1)。我正在为新数据帧mymodel的每一行分配最近的mydf2簇。 Similar to this question - just with k-modes instead of k-meanspredict软件包的flexclust函数仅适用于数字数据,不适用于分类数据。

一个简短的例子:

require(klaR)
set.seed(100)
mydf1 <- data.frame(var1 = as.character(sample(1:20,50,replace = T)),var2 = as.character(sample(1:20,var3 = as.character(sample(1:20,replace = T)))
mydf2 <- data.frame(var1 = as.character(sample(1:20,replace = T)))
mymodel <- klaR::kmodes(mydf1,modes = 5)
# Get mode centers
mycenters <- mymodel$modes
# Now I would want to predict which of the 5 clusters each row 
# of mydf2 would be closest to,e.g.:
# cluster2 <- predict(mycenters,mydf2)

是否已经存在可以使用k模式模型进行预测的函数,或者最简单的方法是什么?谢谢!

解决方法

我们可以使用kmodes算法中使用的距离度量来将每个新行分配给最近的簇。

## From klaR::kmodes

distance <- function(mode,obj,weights) {
  if (is.null(weights)) 
    return(sum(mode != obj))
  obj <- as.character(obj)
  mode <- as.character(mode)
  different <- which(mode != obj)
  n_mode <- n_obj <- numeric(length(different))
  for (i in seq(along = different)) {
    weight <- weights[[different[i]]]
    names <- names(weight)
    n_mode[i] <- weight[which(names == mode[different[i]])]
    n_obj[i] <- weight[which(names == obj[different[i]])]
  }
  dist <- sum((n_mode + n_obj)/(n_mode * n_obj))
  return(dist)
}

AssignCluster <- function(df,kmeansObj)
{
  apply(
    apply(df,1,function(obj)
  {
    apply(kmeansObj$modes,distance,NULL)
  }),2,which.min)
}

AssignCluster(mydf2,mymodel)

[1] 4 3 4 1 1 1 2 2 1 1 5 1 1 3 2 2 1 3 3 1 1 1 1 1 3 1 1 1 3 1 1 1 1 2 1 5 1 3 5 1 1 4 1 1 2 1 1 1 1 1

请注意,这可能会产生许多条目,它们与多个群集的距离相等,然后which.min将选择编号最小的群集。