主成分分析(PCA)及其可视化的基础指南

PCA.jpg

主成分分析(PCA)及其可视化的基础指南

后台很多同学私信想学习一下主成分分析(PCA),今天就简单写一下。之后有看到文章再实战复现。

主成分分析(PCA)是一种将数据降维技巧,它将大量相关变量转化成一组很少的不相关变量,这些无相关变量称为主成分。

22

本文代码领取:后台回复“20210507


下面以R语言自带的iris范例数据集为例,探索一下主成分分析的具体过程。

#导入iris数据集
data<-irisr
head(data)
> head(data)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

1. 数据标准化

如果不对数据进行scale处理,本身数值大的基因对主成分的贡献会大。如果关注的是变量的相对大小对样品分类的贡献,则应scale,以防数值高的变量导入的大方差引入的偏见。但是定标(scale)可能会有一些负面效果,因为定标后变量之间的权重就是变得相同。如果我们的变量中有噪音的话,我们就在无形中把噪音和信息的权重变得相同,但PCA本身无法区分信号和噪音。在这样的情形下,我们就不必做定标。

#对原数据进行z-score归一化;
dt<-as.matrix(scale(data[,1:4])) #不含Species列
head(dt)
> head(dt)
     Sepal.Length Sepal.Width Petal.Length Petal.Width
[1,]       -0.898      1.0156        -1.34       -1.31
[2,]       -1.139     -0.1315        -1.34       -1.31
[3,]       -1.381      0.3273        -1.39       -1.31
[4,]       -1.501      0.0979        -1.28       -1.31
[5,]       -1.018      1.2450        -1.34       -1.31
[6,]       -0.535      1.9333        -1.17       -1.05

2. 计算协方差

#计算协方差
rm1<-cor(dt)
rm1

3. 计算特征值及相应的特征向量

特征值与特征向量均为矩阵分解的结果。特征值表示标量部分,一般为某个主成分的方差,其相对比例可理解为方差解释度或贡献度 ;特征值从第一主成分会逐渐减小。

特征向量为对应主成分的线性转换向量(线性回归系数),特征向量与原始矩阵的矩阵积为主成分得分。特征向量是单位向量,其平方和为1

#特征分解
rs1<-eigen(rm1)
rs1
> rs1
eigen() decomposition
$values
[1] 2.9185 0.9140 0.1468 0.0207

$vectors
       [,1]    [,2]   [,3]   [,4]
[1,]  0.521 -0.3774  0.720  0.261
[2,] -0.269 -0.9233 -0.244 -0.124
[3,]  0.580 -0.0245 -0.142 -0.801
[4,]  0.565 -0.0669 -0.634  0.524
#提取结果中的特征值,即各主成分的方差;
val <- rs1$values
#转换成标准差Standard deviation
Standard_deviation <- sqrt(val)
Standard_deviation
#计算方差贡献率和累积贡献率;
Proportion_of_Variance <- val/sum(val)
Proportion_of_Variance
Cumulative_Proportion <- cumsum(Proportion_of_Variance)
Cumulative_Proportion
> Standard_deviation
[1] 1.708 0.956 0.383 0.144
> Proportion_of_Variance
[1] 0.72962 0.22851 0.03669 0.00518
> Cumulative_Proportion
[1] 0.730 0.958 0.995 1.00

4. 绘制碎石图

#碎石图绘制
par(mar=c(6,6,2,2))
plot(rs1$values,type="b",
     cex=2,
     cex.lab=2,
     cex.axis=2,
     lty=2,
     lwd=2,
     xlab = "PC",
     ylab="Proportion_of_Variance")
210506_1

5. 计算主成分得分

#提取结果中的特征向量(也称为Loadings,载荷矩阵);
U<-as.matrix(rs1$vectors)
U
#进行矩阵乘法,获得PC score;
PC <-dt %*% U
colnames(PC) <- c("PC1","PC2","PC3","PC4")
head(PC)
> head(PC)
       PC1    PC2     PC3      PC4
[1,] -2.26 -0.478  0.1273  0.02409
[2,] -2.07  0.672  0.2338  0.10266
[3,] -2.36  0.341 -0.0441  0.02828
[4,] -2.29  0.595 -0.0910 -0.06574
[5,] -2.38 -0.645 -0.0157 -0.03580
[6,] -2.07 -1.484 -0.0269  0.00659

6. 可视化

#合并Species列
df<-data.frame(PC,iris$Species)
head(df) 
> head(df) 
    PC1    PC2     PC3      PC4 iris.Species
1 -2.26 -0.478  0.1273  0.02409       setosa
2 -2.07  0.672  0.2338  0.10266       setosa
3 -2.36  0.341 -0.0441  0.02828       setosa
4 -2.29  0.595 -0.0910 -0.06574       setosa
5 -2.38 -0.645 -0.0157 -0.03580       setosa
6 -2.07 -1.484 -0.0269  0.00659       setosa
library(ggplot2)
#提取主成分的方差贡献率,生成坐标轴标题
xlab<-paste0("PC1(",round(Proportion_of_Variance[1]*100,2),"%)")
ylab<-paste0("PC2(",round(Proportion_of_Variance[2]*100,2),"%)")
#绘制散点图并添加置信椭圆
p1<-ggplot(data = df,aes(x=PC1,y=PC2,color=iris.Species))+
  stat_ellipse(aes(fill=iris.Species),type ="norm", geom ="polygon",alpha=0.2,color=NA)+
  geom_point(size = 2)+
  labs(x=xlab,y=ylab,color="")+
  guides(fill=F) +
  theme_classic(base_line_size = 1) +
  theme(axis.title.x = element_text(size = 15, 
                                    color = "black",
                                    face = "bold"),
          axis.title.y = element_text(size = 15, 
                                    # family = "myFont", 
                                    color = "black",
                                    face = "bold", 
                                    vjust = 1.9, 
                                    hjust = 0.5, 
                                    angle = 90),
        legend.text = element_text(color="black", # 设置图例标签文字
                                   size = 10, 
                                   face = "bold"),
        axis.text.x = element_text(size = 13,  # 修改X轴上字体大小,
                                   color = "black", # 颜色
                                   face = "bold", #  face取值:plain普通,bold加粗,italic斜体,bold.italic斜体加粗
                                   vjust = 0.5, # 位置
                                   hjust = 0.5, 
                                   angle = 0), #角度
        axis.text.y = element_text(size = 13,  
                                   color = "black",
                                   face = "bold", 
                                   vjust = 0.5, 
                                   hjust = 0.5, 
                                   angle = 0) 
  ) 
p1
210506_2
#用3个主成分绘制3D图
#载入scatterplot3d包
library(scatterplot3d)
color = c(rep('purple',50),rep('orange',50),rep('blue',50))
scatterplot3d(df[,1:3],
              color=color,
              pch = 16,
              angle=30,
              box=T,
              type="p",
              lty.hide=2,
              lty.grid = 2)
legend(x = -3, y =4.5,
       c('Setosa','Versicolor','Virginica'),
       fill=c('purple','orange','blue'),
       box.col=NA)
210506_3

注:以上分析可以用R中最常见的两个PCA函数:prcomp()princomp()一步到位。具体步骤,之后再写。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容