【问题标题】:R: Feature selection in Affinity PropagationR:Affinity Propagation 中的特征选择
【发布时间】:2020-06-28 21:05:25
【问题描述】:

菜鸟在这里寻求帮助。

所以我正在使用 Affinity 传播 APcluster 对数据集进行一些聚类。 现在我有几个问题想要解决:

1:可视化,显然 Plot() 函数不喜欢我的表,当有超过 15 个特征时。有什么方法可以绕过吗?

2:与1相关,所以我想我可以通过使用PCA来减少表中的特征,或者检查相关性。前者会给我 2-3 个关键组件来使用,后者应该允许我消除多余的组件。但是,PCA 做得并不好,PCA1 和 2 只占 22%……

所以有没有机会构建一个循环,在这个循环中我可以从表中随机选择一个特征并将其删除,使用剩余的特征运行 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)

【问题讨论】:

    标签: r cluster-analysis feature-selection


    【解决方案1】:

    我认为您不应该全神贯注于选择聚类变量,而是继续进行可视化并理解聚类。

    如果确实存在信号,即数据集中存在一些分离迹象,则大多数聚类算法将使用更多有用的列。所以例如在下面的例子中,我使用了 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)
    

    您可以看到,如果您投影到第一台 PC,您仍然可以看到来自原始数据的分离。查看解释的方差,大约是 30%,这是有道理的,因为其他列只是噪音:

    head(100*(pca$sdev^2)/sum( (pca$sdev^2)))
    [1] 21.624484  9.839297  9.657884  8.239994  7.875396  7.289238
    

    现在,如果我们进行聚类,我们也可以取出聚类ID,而不受包提供的绘图功能的限制:

    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 建议的对数据进行聚类的明智方法,那么使用上述方法,您已经可以探索您的数据并确定聚类是否有意义。调整您的聚类参数,您可以轻松地看到最终结果。

    【讨论】:

    • 非常感谢,您的回答比我提出的问题要好。让我试试我的数据 tmr 上的代码。对不起,我正在使用我的笔记本电脑,我现在被 APcluster 包卡住了,它不会安装,甚至是二进制文件。我太菜鸟了……而且我敢肯定有些代码我不完全理解。如果你不介意,我可以在我尝试过之后问你?
    • 是的,不用担心.. 安装 R 包有时是一门艺术......一旦你开始了,只需留言,或者你可以邀请我到聊天室..
    • 嗨,伙计,我试图四处搜索,但我认为我无法启动聊天室。我运行了代码,它们运行良好。我想我对 clusters = apres@clusters clusterid = data.frame( cluster = rep(1:length(clusters),sapply(clusters,length)), obs = unlist(clusters) 中的编码部分不太清楚)
    • 你介意把我放到聊天室里,这样我们才能有效率地交谈吗?\
    猜你喜欢
    • 2013-02-21
    • 1970-01-01
    • 2018-06-01
    • 2017-12-10
    • 1970-01-01
    • 2021-07-26
    • 2017-04-06
    相关资源
    最近更新 更多