R:亲和力传播中的特征选择
R: Feature selection in Affinity Propagation
菜鸟求助。
所以我正在对数据集进行一些聚类,使用亲和传播,APcluster。
现在我有几个问题想解决:
1:可视化,显然当有超过 15 个特征时,Plot() 函数不喜欢我的 table。有什么方法可以绕过这个吗?
2:与 1 相关,所以我想我可以通过使用 PCA 减少 table 的特征,或者检查相关性。前者会给我 2-3 个关键组件来处理,而后者应该允许我消除多余的组件。然而,PCA 表现不佳,PCA1 和 2 仅占 22% ...
那么有没有机会建立一个循环,在这个循环中我可以 运行domly select 来自 table 的特性然后删除它,运行 APcluster使用剩余的功能,并对所有功能重复此过程。并比较生成的聚类结果,以查看哪些特征是冗余的,哪些特征是关键角色。
显然,这需要知道什么是好的结果。这个问题 2 部分是我在编码和集群知识方面都不知道如何实现的地方。真的很感激一些指导。
下面是最小的模拟数据和我的 APcluster 代码:
#minimum dataset
Id <- c(1:30)
timestamp <- rep(c("20200512","20180212","20181204" ),10)
f_1 <- runif (30, 0.0, 20)
f_2 <- runif (30, 0.0, 500)
f_3 <- runif (30, 0.0, 15)
f_4 <- runif (30, 0.0, 8.6)
f_5 <- runif (30, 0.0, 200)
f_6 <- runif (30, 0.0, 250)
f_7 <- runif (30, 0.0, 2000)
f_8 <- runif (30, 0.0, 35)
f_9 <- runif (30, 0.0, 20)
f_10 <- runif (30, 0.0, 14)
f_11 <- runif (30, 0.0, 10)
f_12 <- runif (30, 0.0, 89)
df <- data.frame(Id,timestamp,f_1,f_2,f_3,f_4,f_5,f_6,f_7,f_8,f_9,f_10,f_11,f_12)
#drop labels
sampleID <- df$Id
Time <- df$timestamp
sampleID <-NULL
Time <- NULL
#scale numerical data
scaled_df <- scale(df[,3:14])
#APcluster
library(apcluster)
apres <- apcluster(negDistMat(r=2), scaled_df, details=TRUE)
show(apres)
plot(apres, df)
我认为您不应该专注于选择用于聚类的变量,而是继续进行可视化并理解聚类。
如果确实存在信号,这意味着您的数据集中有一些分离迹象,大多数聚类算法将使用更多有用的列。因此,例如在下面的示例中,我使用 iris 集群,但又添加了 10 个无意义的列:
library(apcluster)
set.seed(100)
df = iris[,1:4]
df = cbind(df,matrix(rnbinom(nrow(df)*10,mu=10,size=1),ncol=10))
scaled_df = scale(df)
pca = prcomp(scaled_df)
plot(pca$x[,1:2],col=iris$Species)
在上面你可以看到,如果你投影到第一台电脑上,你仍然可以看到来自原始数据的分离。查看解释的方差,大约是 30%,这是有道理的,因为其他列只是噪声:
head(100*(pca$sdev^2)/sum( (pca$sdev^2)))
[1] 21.624484 9.839297 9.657884 8.239994 7.875396 7.289238
现在我们做聚类的话,也可以把cluster id取出来,不局限于package提供的plot函数:
apres <- apcluster(negDistMat(r=2), scaled_df,q=0.01)
clusters = apres@clusters
clusterid = data.frame(
cluster = rep(1:length(clusters),sapply(clusters,length)),
obs = unlist(clusters)
)
clusterid = clusterid[order(clusterid$obs),]
head(clusterid)
cluster obs
1 2 1
2 2 2
3 2 3
4 2 4
5 2 5
6 2 6
现在我们有一个 data.frame,它告诉我们对于我们作为输入提供的每个观察,分配的集群。让我们将其投影到 pca 上,看看它是如何分离的:
library(RColorBrewer)
COLS = brewer.pal(length(unique(clusterid$cluster)),"Set3")
plot(pca$x[,1:2],col=COLS[clusterid$cluster],pch=20,cex=0.5)
我们可以查看包含信号的变量,
plot(df[,1:2],col=COLS[clusterid$cluster],pch=20,cex=0.5)
那些没有的:
plot(df[,9:10],col=COLS[clusterid$cluster],pch=20,cex=0.5)
因此,如果确实有一种明智的数据聚类方法(您的 pca 建议),那么使用上述方法,您已经可以探索您的数据并找出聚类是否有意义。调整您的聚类参数,您可以轻松地看到最终结果。
菜鸟求助。
所以我正在对数据集进行一些聚类,使用亲和传播,APcluster。 现在我有几个问题想解决:
1:可视化,显然当有超过 15 个特征时,Plot() 函数不喜欢我的 table。有什么方法可以绕过这个吗?
2:与 1 相关,所以我想我可以通过使用 PCA 减少 table 的特征,或者检查相关性。前者会给我 2-3 个关键组件来处理,而后者应该允许我消除多余的组件。然而,PCA 表现不佳,PCA1 和 2 仅占 22% ...
那么有没有机会建立一个循环,在这个循环中我可以 运行domly select 来自 table 的特性然后删除它,运行 APcluster使用剩余的功能,并对所有功能重复此过程。并比较生成的聚类结果,以查看哪些特征是冗余的,哪些特征是关键角色。
显然,这需要知道什么是好的结果。这个问题 2 部分是我在编码和集群知识方面都不知道如何实现的地方。真的很感激一些指导。
下面是最小的模拟数据和我的 APcluster 代码:
#minimum dataset
Id <- c(1:30)
timestamp <- rep(c("20200512","20180212","20181204" ),10)
f_1 <- runif (30, 0.0, 20)
f_2 <- runif (30, 0.0, 500)
f_3 <- runif (30, 0.0, 15)
f_4 <- runif (30, 0.0, 8.6)
f_5 <- runif (30, 0.0, 200)
f_6 <- runif (30, 0.0, 250)
f_7 <- runif (30, 0.0, 2000)
f_8 <- runif (30, 0.0, 35)
f_9 <- runif (30, 0.0, 20)
f_10 <- runif (30, 0.0, 14)
f_11 <- runif (30, 0.0, 10)
f_12 <- runif (30, 0.0, 89)
df <- data.frame(Id,timestamp,f_1,f_2,f_3,f_4,f_5,f_6,f_7,f_8,f_9,f_10,f_11,f_12)
#drop labels
sampleID <- df$Id
Time <- df$timestamp
sampleID <-NULL
Time <- NULL
#scale numerical data
scaled_df <- scale(df[,3:14])
#APcluster
library(apcluster)
apres <- apcluster(negDistMat(r=2), scaled_df, details=TRUE)
show(apres)
plot(apres, df)
我认为您不应该专注于选择用于聚类的变量,而是继续进行可视化并理解聚类。
如果确实存在信号,这意味着您的数据集中有一些分离迹象,大多数聚类算法将使用更多有用的列。因此,例如在下面的示例中,我使用 iris 集群,但又添加了 10 个无意义的列:
library(apcluster)
set.seed(100)
df = iris[,1:4]
df = cbind(df,matrix(rnbinom(nrow(df)*10,mu=10,size=1),ncol=10))
scaled_df = scale(df)
pca = prcomp(scaled_df)
plot(pca$x[,1:2],col=iris$Species)
在上面你可以看到,如果你投影到第一台电脑上,你仍然可以看到来自原始数据的分离。查看解释的方差,大约是 30%,这是有道理的,因为其他列只是噪声:
head(100*(pca$sdev^2)/sum( (pca$sdev^2)))
[1] 21.624484 9.839297 9.657884 8.239994 7.875396 7.289238
现在我们做聚类的话,也可以把cluster id取出来,不局限于package提供的plot函数:
apres <- apcluster(negDistMat(r=2), scaled_df,q=0.01)
clusters = apres@clusters
clusterid = data.frame(
cluster = rep(1:length(clusters),sapply(clusters,length)),
obs = unlist(clusters)
)
clusterid = clusterid[order(clusterid$obs),]
head(clusterid)
cluster obs
1 2 1
2 2 2
3 2 3
4 2 4
5 2 5
6 2 6
现在我们有一个 data.frame,它告诉我们对于我们作为输入提供的每个观察,分配的集群。让我们将其投影到 pca 上,看看它是如何分离的:
library(RColorBrewer)
COLS = brewer.pal(length(unique(clusterid$cluster)),"Set3")
plot(pca$x[,1:2],col=COLS[clusterid$cluster],pch=20,cex=0.5)
我们可以查看包含信号的变量,
plot(df[,1:2],col=COLS[clusterid$cluster],pch=20,cex=0.5)
那些没有的:
plot(df[,9:10],col=COLS[clusterid$cluster],pch=20,cex=0.5)
因此,如果确实有一种明智的数据聚类方法(您的 pca 建议),那么使用上述方法,您已经可以探索您的数据并找出聚类是否有意义。调整您的聚类参数,您可以轻松地看到最终结果。