关于 R 中 princomp 和 prcomp 的 区别
来源:互联网 发布:encore制谱软件 编辑:程序博客网 时间:2024/05/20 12:50
主成分分析方法从统计学上讲对子特征提取,典型特征,相似性有重要的作用。简而言之,就是在导致结果的所有因素中发现哪些少数因素是概括了数据集整个特征空间中所包含的信息,因而称为主成分分析。常用的方法有 :
PCA (principle component analysis)
LDA(latent discriminative analysis) <-- 偶看了一篇论文apple 2005年时候的语音合成技术就是基于此算法,在此提一下
SVD(single value decomposition)
不过在我看来,核心都是利用正交化的思想构造特征值矩阵。
R语言中,实现这个方法的函数 princomp , prcomp 等,这里来介绍这两种方法的不同 。读了开发人的邮件后,总结主要如下:
princomp prcomp R mode / Q mode只适用于R mode适用于R mode 和 Q mode基于算法基于 协方差(covariance) 或者 相关矩阵(correlation) 提取的特征(eigen) , 也叫 spectral decomposition基于SVD分解载荷因子的R用法(不懂请把PCA基本算法搞懂)princomp.loadingsprcomp.rotation
- 什么是R mode 和Q mode:
- 首先,什么是 observation 和 variable:
- observation 指 所有观察到的记录数,也就是数据集里面的行数,我们有时也会说有几条数据这个意思,而variable是指因素的个数。
- observation 指 所有观察到的记录数,也就是数据集里面的行数,我们有时也会说有几条数据这个意思,而variable是指因素的个数。
- 首先,什么是 observation 和 variable:
R mode 是指基于variable的分析 ,意思就是说在所有的observation里面,来研究variable之间的关系,哪些是主要的?是典型的?英文:similarity in the variables over subjects. 这里的R 我认为指normal,就是最平常的情况,数据数量大于变量(因素)数量,例如人口统计中,是人口多还是统计指标多?对吧。这里文档里面翻译成 observation 大于 variable。
Q mode 是指基于observation的分析,意思就是说在所有的variable里面,来研究observation之间的关系,哪两条记录相似? 英文:similarity in the subjects over variables。所以这里是指变量(因素)数量大于数据数量,与R 相对。
清楚了什么是R / Q mode ,来看看 具体使用时候他们的异同点:
拿 iowa 一本书里的 protein.csv 数据举例,
1. R mode / Q mode 实验
food = read.csv("protein.csv")food[1,]
Country RedMeat WhiteMeat Eggs Milk Fish Cereals Starch Nuts Fr.Veg1 Albania 10.1 1.4 0.5 8.9 0.2 42.3 0.6 5.5 1.7
dim(food)[1] 25 10这里 数据大于变量,即行大于列,则应该是R mode的数据,来看prcomp 和 princomp得到的载荷(loadings)
pcafood <- prcomp(food[,-1], scale=TRUE)str(pcafood$rotation)num [1:9, 1:9] -0.303 -0.311 -0.427 -0.378 -0.136 ... - attr(*, "dimnames")=List of 2 ..$ : chr [1:9] "RedMeat" "WhiteMeat" "Eggs" "Milk" ... ..$ : chr [1:9] "PC1" "PC2" "PC3" "PC4" ...这里的载荷是一个9*9的矩阵
pcafood2 <- princomp(food[,-1], scale=TRUE)str(pcafood2$loadings)
loadings [1:9, 1:9] -0.1507 -0.1295 -0.0673 -0.4254 -0.127 ... - attr(*, "dimnames")=List of 2 ..$ : chr [1:9] "RedMeat" "WhiteMeat" "Eggs" "Milk" ... ..$ : chr [1:9] "Comp.1" "Comp.2" "Comp.3" "Comp.4" ...
这里的载荷同样是9*9的矩阵
但是, 如果选用Q mode的数据(在那个网站下得到),再来看一下:
raw=read.csv("unempstates.csv")raw[1,] AL AK AZ AR CA CO CT DE FL GA HI ID1 6.4 7.1 10.5 7.3 9.3 5.8 9.4 7.7 10 8.3 9.9 5.5 IL IN IA KS KY LA ME MD MA MI MN MS MO1 6.4 6.9 4.2 4.3 5.7 6.2 8.8 6.9 11.1 10 6.2 7 5.8 MT NE NV NH NJ NM NY NC ND OH OK OR1 5.8 3.6 9.8 7.2 10.5 8.9 10.2 6.7 3.2 8.3 6.4 10.1 PA RI SC SD TN TX UT VT VA WA WV WI1 8.1 7.8 7.6 3.6 5.9 5.9 6.1 8.8 6.2 8.7 8.3 5.9 WY1 4.2
unempstates=t(raw)
dim(unempstates)
这里是一个反应美国** 的数据集,原数据集的行是美国50个州,列是各个指标,这里转置一下,变为Q mode的数据集unempstates[1] 50 416
pcaunempstates <- prcomp(unempstates[,-1], scale=TRUE)str(pcaunempstates$rotation)num [1:415, 1:50] -0.031 -0.0315 -0.0316 -0.0321 -0.0328 ... - attr(*, "dimnames")=List of 2 ..$ : NULL ..$ : chr [1:50] "PC1" "PC2" "PC3" "PC4" ...
pcaunempstates2 <- princomp(unempstates[,-1], scale=TRUE)
str(pcaunempstates2$loadings)
Error in princomp.default(unempstates[, -1], scale = TRUE) : 'princomp'只能在单位比变量多的情况下使用
这里可以看到,princomp不支持对Q mode 数据的pca处理,而prcomp 是可以的.
2. 载荷值的比较
实验前提一点,使用SVD分解和协方差方式做出来的结果其实应该是一样的或者接近的,因为这两种方法其实原理大致相同,只是一方需要有正定矩阵的约束条件
还是回到protein的例子,
food = read.csv("protein.csv")pcafood <- prcomp(food[,-1],scale=TRUE) PC1 PC2 PC3RedMeat -0.3026094 -0.05625165 -0.29757957WhiteMeat -0.3105562 -0.23685334 0.62389724Eggs -0.4266785 -0.03533576 0.18152828Milk -0.3777273 -0.18458877 -0.38565773Fish -0.1356499 0.64681970 -0.32127431Cereals 0.4377434 -0.23348508 0.09591750Starch -0.2972477 0.35282564 0.24297503Nuts 0.4203344 0.14331056 -0.05438778Fr.Veg 0.1104199 0.53619004 0.40755612 PC4 PC5 PC6RedMeat -0.646476536 0.32216008 -0.45986989WhiteMeat 0.036992271 -0.30016494 -0.12100707Eggs -0.313163873 0.07911048 0.36124872Milk 0.003318279 -0.20041361 0.61843780Fish 0.215955001 -0.29003065 -0.13679059Cereals 0.006204117 0.23816783 0.08075842Starch 0.336684733 0.73597332 0.14766670Nuts -0.330287545 0.15053689 0.44701001Fr.Veg -0.462055746 -0.23351666 0.11854972 PC7 PC8 PC9RedMeat 0.15033385 -0.01985770 0.2459995WhiteMeat -0.01966356 -0.02787648 0.5923966Eggs -0.44327151 -0.49120023 -0.3333861Milk 0.46209500 0.08142193 0.1780841Fish -0.10639350 -0.44873197 0.3128262Cereals 0.40496408 -0.70299504 0.1522596Starch 0.15275311 0.11453956 0.1218582Nuts -0.40726235 0.18379989 0.5182749Fr.Veg 0.44997782 0.09196337 -0.2029503
pcafood2 <- princomp(food[,-1],scale=TRUE)
Loadings: Comp.1 Comp.2 Comp.3 Comp.4 Comp.5 Comp.6RedMeat -0.151 -0.133 0.896 -0.289 0.229WhiteMeat -0.129 -0.798 -0.185 -0.400 Eggs Milk -0.425 -0.831 0.220 -0.204 -0.117 -0.149Fish -0.127 0.292 0.522 -0.285 -0.559 0.256Cereals 0.861 -0.406 -0.274 0.114Starch -0.112 -0.241 0.327Nuts 0.114 0.166 0.123 -0.565Fr.Veg 0.169 -0.533 -0.645 Comp.7 Comp.8 Comp.9RedMeat WhiteMeat -0.246 -0.261 -0.146Eggs 0.142 -0.255 0.940Milk Fish -0.336 -0.229 Cereals Starch 0.871 -0.155 -0.167Nuts -0.743 -0.232Fr.Veg 0.180 0.482 为什么这里两种方式算出来的载荷这么不一样? 后来分析得知,原因在于princomp的 cor参数,这个参数其实有两个选项,TRUE和FALSE,TRUE表示采用correlation方式计算,FALSE 表示采用covariance方式计算。默认情况下,是采用FALSE值计算的。所以这里princomp计算的其实是covariance.而标准化(正态分布)后的covariance 其实等价于correlation,并不再是 对应 covariance(X) 了。所以即使用covariance计算,也不可能产生和SVD 分解一样的结果,用式子表示,就是 correlation = covariance( z-score(X) ) .所以要使得两个结果一样,可以把 z-score的 normalization 给去掉,然后再试一次,这个时候应该是covariance(X)了:pcafood2 <- princomp(food[,-1], cor=FALSE,scale=FALSE)
Loadings: Comp.1 Comp.2 Comp.3 Comp.4 Comp.5 Comp.6RedMeat -0.151 -0.133 0.896 -0.289 0.229WhiteMeat -0.129 -0.798 -0.185 -0.400 Eggs Milk -0.425 -0.831 0.220 -0.204 -0.117 -0.149Fish -0.127 0.292 0.522 -0.285 -0.559 0.256Cereals 0.861 -0.406 -0.274 0.114Starch -0.112 -0.241 0.327Nuts 0.114 0.166 0.123 -0.565Fr.Veg 0.169 -0.533 -0.645 Comp.7 Comp.8 Comp.9RedMeat WhiteMeat -0.246 -0.261 -0.146Eggs 0.142 -0.255 0.940Milk Fish -0.336 -0.229 Cereals Starch 0.871 -0.155 -0.167Nuts -0.743 -0.232Fr.Veg 0.180 0.482pcafood <- prcomp(food[,-1],scale=FALSE)
PC1 PC2 PC3RedMeat -0.15065437 -0.13269468 -0.03183702WhiteMeat -0.12948879 -0.04343486 0.79838375Eggs -0.06727094 -0.02094603 0.09809250Milk -0.42537632 -0.83085609 -0.21964423Fish -0.12697617 0.29230731 -0.52238799Cereals 0.86086515 -0.40616852 -0.03819580Starch -0.06685119 0.07604862 0.03432274Nuts 0.11390881 0.07006621 -0.16639124Fr.Veg 0.02023530 0.16922131 -0.02217752 PC4 PC5 PC6RedMeat -0.89605088 0.28880267 -2.290658e-01WhiteMeat 0.18534039 0.39975064 4.418893e-05Eggs -0.07583562 0.07877533 6.934069e-02Milk 0.20364469 0.11700605 1.494390e-01Fish 0.28510797 0.55887353 -2.561571e-01Cereals 0.03449999 0.27438410 -1.138637e-01Starch 0.11186694 0.24093950 -3.270186e-01Nuts -0.12290210 -0.08410214 5.645635e-01Fr.Veg -0.07364522 0.53305272 6.450846e-01 PC7 PC8 PC9RedMeat 0.07965762 -0.06594051 0.09593232WhiteMeat 0.24627505 -0.26052755 0.14578003Eggs -0.14159078 -0.25530955 -0.93990324Milk -0.03659099 -0.01145501 0.03906204Fish 0.33586748 -0.22854504 -0.03552198Cereals 0.01897181 -0.03504168 -0.03807529Starch -0.87124836 -0.15513110 0.16710135Nuts -0.08325422 -0.74349988 0.23193980Fr.Veg -0.18012371 0.48181384 -0.01306739
结果近似了,这里少许失真是因为svd是考虑平方根,所以算平方根的时候会有位数保留出现造成失真。
这是邮件
https://stat.ethz.ch/pipermail/r-help/2011-September/289101.html
- 关于 R 中 princomp 和 prcomp 的 区别
- R语言主成分分析——prcomp VS princomp
- 关于matlab中princomp的使用说明讲解
- 关于matlab中princomp的使用说明讲解小例子
- princomp 与pca的区别与联系
- fopen中r+和w+的区别
- python中%r和%s的区别
- fopen中r+和w+的区别
- python中%s和%r的区别
- python中%r和%s的区别
- python中%r和%s的区别
- python中%r和%s的区别
- python中%r和%s的区别
- 系统中\r和\n的区别?
- python中%r和%s的区别
- Python中%r和%s的区别
- python中%r和%s的区别
- android中关于android.R.....和R....分别是什么意思?两者有什么区别?
- poj 1069 dfs(难在建立一个坐标)
- C程序设计-现代方法
- 第三周 项目1-顺序表的基本运算
- 去掉android二维码的边框
- BP 神经网络之我见s庆
- 关于 R 中 princomp 和 prcomp 的 区别
- 数据结构学习笔记
- 第三周项目1-(3)ListInsert、ListDelete、InitList、DestroyList函数
- 你必须知道的495个C语言问题
- Apple IT 管理指南 01
- MySQL 5.6的安装
- 体验复杂度—汉诺塔
- C与指针
- 查看linux版本的三种常用方法