如何在 R 中实现分类特征向量的聚类?

数据挖掘 r 聚类 k-均值
2022-02-24 14:17:22

我有一个像这样的数据集:

 id color  body  eyes
 1  A  blue  slim green
 2  B black   fat  blue
 3  A black  slim black
 4  C green  slim  blue
 5  D black medim black

而每个 id 代表具有其个人身体特征的个人。

可重现:

 structure(list(id = structure(c(1L, 2L, 1L, 3L, 4L), .Label = c("A", 
"B", "C", "D"), class = "factor"), color = structure(c(2L, 1L, 
1L, 3L, 1L), .Label = c("black", "blue", "green"), class = "factor"), 
body = structure(c(3L, 1L, 3L, 3L, 2L), .Label = c("fat", 
"medim", "slim"), class = "factor"), eyes = structure(c(3L, 
2L, 1L, 2L, 1L), .Label = c("black", "blue", "green"), class = "factor")),
 .Names = c("id", 
"color", "body", "eyes"), class = "data.frame", row.names = c(NA, 
-5L))

然后特征的数量是固定的(颜色:蓝色/黑色/绿色,身体:苗条/脂肪/中等,眼睛:绿色/蓝色/黑色)。

我的目标是将这些人聚集在一起。

我的概念问题与方法有关:

  1. 一个简单的关联可能是第一步。一个问题可能是:这些特征的组合如何可能出现在个体群体中?

    1. 更复杂的方法。也许k-means聚类。鉴于这些是分类变量,如何解决这个问题?我应该把它们变成假人吗?

我是这种分析的新手,对 R 中的实现的任何提示/参考都非常感谢!谢谢

2个回答

你应该使用虚拟变量,然后你可以直接把它扔进K-means。如果您有很多类别,那么执行此操作的有效方法是通过 one-hot-encoding(稀疏编码)。

这是一个使用聚类然后在回归模型中使用聚类的小演示。一般来说,你应该避免这样做,但在这种情况下它很有启发性。

library(glmnet)
library(Matrix)
n <- 1e5
nclusters <- 5
set.seed(420)
ls <- data.frame(sample(letters, n, replace=TRUE))
xs <- sparse.model.matrix(~.,data=ls)
print(head(xs))  
# Now let's run k-means
out <- kmeans(xs, centers=nclusters)
bs <- rep(1, dim(xs)[2])
# Let's run k-means on the different categories
clusterpred <- data.frame(out[[1]])
ys <- xs %*% bs + rnorm(n)
print(table(clusterpred))
# Now let's use a clustered data set to predict some outcome
cxs <- sparse.model.matrix(~.,data=clusterpred)
model <- glmnet(y=ys, x=xs, alpha=0)
cmodel <- glmnet(y=ys, x=cxs, alpha=0)

# Predictions
yhat <- predict(model, xs)
yhatc <- predict(cmodel, cxs)
# Looking at the difference RMSEs 
print(sqrt( sum( (ys-yhat)**2 )))
print(sqrt( sum( (ys-yhatc)**2 )))

首先,最初的蛮力方法是仅执行相似事件的计数,以了解哪些特征组合出现了多少次。这可以很容易地使用包.N提供的运算符data.table

counts <- df[, .N, by = c("first_column", "second_column")]

一旦这样,您可以使用作为初始标准方法的Pearson 卡方独立性检验(可在Ras中获得)计算分类变量之间的相关性。chisq.test(x,y, ...)

为了执行聚类,您必须引入一种距离方法,该方法允许您决定两个点(其坐标是手头的分类变量)的距离。有很多方法可以将距离分配给名义变量,就像您的情况一样,每种方法都适用于一个正在处理的用例(虚拟变量分配、降维或简单的相似性度量,即变量要么相同,要么它们不是,前者对应距离 0,后者对应距离 1)。在另一个答案中有一个很好的工作示例引入合适的距离后,您可以执行均值聚类或最适合您的任何其他类型的聚类。k

此详细答案中提供了非常精确的演练(带有示例和参考)。