如何在矩阵中找到最相似的列?

时间:2015-03-10 14:14:29

标签: r

我有一个矩阵,我希望找到那些非常相似的列(我不希望找到相同的列

# to generate a matrix
Mat<- matrix(rexp(200, rate=.1), ncol=1000, nrow=400)

我个人认为“cor”或“all.equal”我做了如下,但没有奏效。

indexmax <- apply(Mat, MARGIN = 2, function(x) which(cor(x) >= 0.5, arr.ind = TRUE))

我需要的输出是显示哪些列高度相似以及它们的相似程度(它可以是相关系数)

类似意味着它们的值在某个阈值内是相似的(例如,超过75%的值残差(例如column1-column2)小于abs(0.5)

我也很想知道这与相关性有何不同。他们会得到相同的结果吗?

3 个答案:

答案 0 :(得分:1)

您可以尝试使用相关性(使用更简单的矩阵进行演示)

set.seed(123)
Mat <- matrix(rnorm(300), ncol = 10)
library(matrixcalc)

corr <- cor(Mat)
res <-which(lower.triangle(corr)>.3, arr.ind = TRUE)

data.frame(res[res[,1] != res[,2],], correlation = corr[res[res[,1] != res[,2],]])
  row col correlation
1   8   1   0.3387738
2   6   2   0.3350891

rowcol实际上都是指原始矩阵中的列。因此,例如,第8列和第1列之间的相关性为0.3387738

答案 1 :(得分:0)

我采用线性回归方法:

Mat<- matrix(rexp(200, rate=.1), ncol=100, nrow=400)
combinations <- combn(1:ncol(Mat), m = 2)
sigma <- NULL
for(i in 1:ncol(combinations)){
  sigma <- c(sigma, summary(lm(Mat[,combinations[1,1]] ~ Mat[,combinations[2,1]]))$sigma)
}
sigma <- data.frame(sigma = sigma, comb_nr = 1:ncol(combinations))

剩余标准误差作为可选标准。 您可以通过sigma进一步订购数据框,并获得最佳/最差组合。

答案 2 :(得分:0)

如果您想要一种(不那么优雅)直接的方法,对于您的大小的矩阵可能非常慢,您可以这样做:

set.seed(1)

Mat <- matrix(runif(40000), ncol=100, nrow=400)

col.combs <- t(combn(1:ncol(Mat), 2))

similar <- data.frame(Col1=NULL, Col2=NULL, Corr=NULL, Pct.Diff=NULL)

# Compare each pair of columns
for (k in 1:nrow(col.combs)) {
    i <- col.combs[k, 1]
    j <- col.combs[k, 2]

    # Difference within threshold?
    diff.thresh <- (abs(Mat[, i] - Mat[, j]) < 0.5)

    pair.corr <- cor(Mat[, 1], Mat[, 2])

    if (mean(diff.thresh) > 0.75)
        similar <- rbind(similar, c(i, j, pair.corr, 100*mean(diff.thresh)))
}

在这个例子中,有2590个不同的列对,其中75%以上的值在0.5之内(元素)。您可以通过查看结果数据框来检查实际差异和相关系数。

> head(similar)
   Col1  Col2         Corr Pct.Diff
1     1     2 -0.003187894    76.75
2     1     3  0.074061019    76.75
3     1     4  0.082668387    78.00
4     1     5  0.001713751    75.50
5     1     8  0.052228907    75.75
6     1    12 -0.017921978    78.00

也许这不是最好的解决方案,但可以完成工作。

另外,如果您不确定我使用mean(diff.thresh)的原因,那是因为逻辑向量的总和是TRUE元素的数量。均值是除以长度的总和,这意味着在这种情况下,它是阈值内的值的分数。