【问题标题】:Principal component analysis using R. Automatic and manual results do not match使用 R 进行主成分分析。自动和手动结果不匹配
【发布时间】:2020-11-15 18:39:22
【问题描述】:

使用以下 Box1 的 R 代码进行了两种不同的主成分分析方法来分析以下数据 (ch082.dat)。
https://drive.google.com/file/d/1xykl6ln -bUnXIs-jIA3n5S3XgHjQbkWB/view?usp=sharing

第一种方法使用旋转矩阵(参见 Box1 代码的“#rotated data”下的“ans_mat”),并且, 第二种方法使用'pcomp'函数(参见Box1代码的'#rotated data'下的'rpca')。

但是,使用旋转矩阵的方法和使用“pcomp”函数的方法之间的答案存在细微的差异。 让它匹配

我的问题

我应该怎么做才能使基于旋转矩阵的方法的结果与'pcomp'函数的结果相匹配?

就我尝试过的各种数据(包括其他数据)而言,实际差异似乎仅限于规模变化和镜像转换。

  • 基于旋转矩阵的方法的结果显示在左侧面板中。
  • 基于 pcomp 函数的方法的结果显示在右侧面板中。

镜像反转可见“ch082.dat”数据。(见图1); 似乎在某些 j 中,“相关矩阵的第 j 个特征向量”的符号和“prcomp 函数的输出值的第 j 列”的符号可能是相反的。如果特征值有一定程度的重叠,则差异可能比镜像反演更复杂。
图1

尽管对数据进行了集中化和标准化,但 Box2 的数据存在规模变化(参见图 2)。
图2

Box.1

#dataload
##Use the 'setwd' function to specify the directory containing 'ch082.dat'.
##For example, if you put this file directly under the C drive of your Windows PC, you can run the following command.

setwd("C:/") #Depending on where you put the file, you may need to change the path.
getwd()
w1<-read.table("ch082.dat",header = TRUE,row.names = 1,fileEncoding = "UTF-8")
w1

#Function for standardizing data
#Thanks to https://qiita.com/ohisama2/items/5922fac0c8a6c21fcbf8
standalize <- function(data)
{ for(i in length(data[1,]))
{
  x <- as.matrix(data[,i])
  y <- (x-mean(x)/sd(x))
  data[,i] <- y
}
  return(data)}


#Method using rotation matrix
z_=standalize(w1)
B_mat=cor(z_) #Compute correlation matrix
eigen_m <- eigen(B_mat)
sample_mat <- as.matrix(z_)
ans_mat=sample_mat

for(j in 1:length(sample_mat[1,])){
ans_mat[,j]=sample_mat%*%eigen_m$vectors[,j]
}

#Method using "rpca" function
rpca <- prcomp(w1,center=TRUE, scale=TRUE)

#eigen vectors
eigen_m$vectors
rpca

#rotated data
ans_mat
rpca$x

#Graph Plots
par(mfrow=c(1,2))
plot(
  ans_mat[,1], 
  ans_mat[,2], 
  main="Rotation using eigenvectors"
)
plot(rpca$x[,1], rpca$x[,2], 
     main="Principal component score")
par(mfrow=c(1,1))

#summary
summary(rpca)$importance

盒子2。

sample_data <- data.frame(
  X = c(2,4, 6, 5,7, 8,10),
  Y = c(6,8,10,11,9,12,14)
)

X = c(2,4, 6, 5,7, 8,10)
Y = c(6,8,10,11,9,12,14)
plot(Y ~ X)

w1=sample_data 

参考
https://logics-of-blue.com/principal-components-analysis/ (用日文写的)

【问题讨论】:

    标签: r statistics pca


    【解决方案1】:

    两组结果一致。首先,我们可以稍微简化您的代码。你不需要你的函数或 for 循环:

    z_ <- scale(w1)
    B_mat <- cor(z_)
    eigen_m <- eigen(B_mat)
    ans_mat <- z_ %*% eigen_m$vectors
    

    现在是prcomp 版本

    z_pca <- prcomp(z_)
    z_pca$sdev^2    # Equals eigen_m$values
    z_pca$rotation  # Equals eigen_m$vectors
    z_pca$x         # Equals ans_mat
    

    您的原始代码错误地标记了ans_mat 列。它们实际上是主成分分数。你可以解决这个问题

    colnames(ans_mat) <- colnames(z_pca$x)
    

    PC 负载(以及因此的分数)不是针对反射唯一定义的。换句话说,将一个组件中的所有负载或分数乘以 -1 会翻转它们,但不会改变它们之间的关系。将 z_pca$x[, 1] 乘以 -1,绘图将匹配:

    z_pca$x[, 1] <- z_pca$x[, 1] * -1
    dev.new(width=10, height=6)
    par(mfrow=c(1,2))
    plot(ans_mat[,1], ans_mat[,2], main="Rotation using eigenvectors")
    plot(z_pca$x[,1], z_pca$x[,2], main="Principal component score")
    

    【讨论】:

    • 感谢您的回答。我根据您的说明修改了代码,但是对于my data,仍然是 eigen_m$vectors[,1]=- z_pca$rotation[,1] 。
    • 对于Box2的数据,最终的结果似乎是一致的。对应于图的绘图。 2的疑问文本,两种方法的尺度匹配。
    • 我应该注意到这一点。 pc 负载(以及因此的分数)并不是关于反射的唯一定义。换句话说,将一个组件中的所有负载或分数乘以 -1 会翻转它们,但不会改变它们之间的关系。将 ans_mat[, 1] 或 rpca$x[, 1] 乘以 -1,但不能同时乘以两者,绘图将匹配。目前它们是彼此的镜像。
    • >"pc 加载(以及因此的分数)在反射方面并不是唯一定义的。"⇒非常感谢。现在一切都清楚了。因此,如果我们将特征向量乘以一个非零标量,它仍然是对应于相同特征值的特征向量。如果特征空间是二维或更多维,即使我们进行保留特征空间的变换,只要保持正交性,它仍然是对应于相同特征值的特征向量。因此,主成分分析在此具有任意性感觉,我说的对吗?谢谢。
    • 是的,尽管乘以除 1 以外的任何值,-1 会改变特征向量/分数与特征值的关系。
    猜你喜欢
    • 2013-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-04
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多