主成分分析,即Principle Component Analysis (PCA),是一種傳統的統計學方法,被機器學習領域引入后,通常被認為是一種特殊的非監督學習算法,其可以對復雜或多變量的數據做預處理,以減少次要變量,便于進一步使用精簡后的主要變量進行數學建模和統計學模型的訓練,所以PCA又被稱為主變量分析。
R語言中,實現這個方法的函數主要有 princomp , prcomp 等。查資料后,這兩種方法的不同主要體現如下:
具體細節大家可以自行查資料學習。
# 使用R自帶iris數據集(150*5,行為樣本,列為特征) 可以自己對比一下2個函數結果的異同
############ prcomp函數 ################
# retx表示返回score,scale表示要標準化
iris.pca <- prcomp(iris[,-5],scale=T,rank=4,retx=T) #相關矩陣分解
summary(iris.pca) #方差解釋度
iris.pca$sdev #特征值的開方
iris.pca$rotation #特征向量,回歸系數
iris.pca$x #樣本得分score
############ princomp函數 ################
library(stats)
# 默認方差矩陣(cor=F),改為cor=T則結果與prcomp相同
iris.pca<-princomp(iris[,-5],cor=T,scores=T)
# 各主成份的SVD值以及相對方差
summary(iris.pca)
# 特征向量,回歸系數
iris.pca$loading
iris.pca$score
下面我們就用R這個自帶的iris數據來畫一下PCA圖。
從這個數據來看,包含150行,5列,最后一列是按species分成了三類。
我們用prcomp函數來計算各個主成分,但是因為最后一列是Species,所以計算的時候需要先排除。
pca1 <- prcomp(iris[,-ncol(iris)],center = TRUE,scale= TRUE)
可以看出PC的信息存在x中。
df1 <- pca1$x # 提取PC score
df1 <- as.data.frame(df1) # 注意:如果不轉成數據框形式后續繪圖時會報錯
可以通過summary函數查看每個主成分的貢獻度。
summ1 <- summary(pca1)
summ1
所以我們可以summary里面的信息把PC1 PC2提取出來作為X和Y軸的lab。summ1$importance[2,1]和summ1$importance[2,2]是PC1和PC2。round函數是取小數點的位數。
xlab1 <- paste0("PC1(",round(summ1$importance[2,1]*100,2),"%)")
ylab1 <- paste0("PC2(",round(summ1$importance[2,2]*100,2),"%)")
df1$Species <- iris_input$Species
把原先的Specis類別信息加進來。
首先還是用ggplot2的來畫,先畫個基本版本的二維PCA圖。
ggplot(data = df1,aes(x = PC1,y = PC2,color = Species))+
geom_point(size = 2.5)
下面我們添加上橢圓形的置信區間。
ggplot(data = df1,aes(x = PC1,y = PC2,color = Species))+
? geom_point(size = 2.5)+
? # 繪制置信橢圓:
? stat_ellipse(aes(fill = Species),type = "norm",geom = "polygon",alpha = 0.25,color = NA)
添加上x,y的lab和title。
ggplot(data = df1,aes(x = PC1,y = PC2,color = Species))+
? geom_point(size = 2.5)+
? # 繪制置信橢圓:
? stat_ellipse(aes(fill = Species),type = "norm",geom = "polygon",alpha = 0.25,color = NA)+
? labs(x = xlab1,y = ylab1,title = "PCA Scores Plot")
換個背景模式。
ggplot(data = df1,aes(x = PC1,y = PC2,color = Species))+
? geom_point(size = 2.5)+
? # 繪制置信橢圓:
? stat_ellipse(aes(fill = Species),type = "norm",geom = "polygon",alpha = 0.25,color = NA)+
? labs(x = xlab1,y = ylab1,title = "PCA Scores Plot")+
? theme_bw()
下面我們嘗試修改色系。
ggplot(data = df1,aes(x = PC1,y = PC2,color = Species))+
? geom_point(size = 2.5)+
? # 繪制置信橢圓:
? stat_ellipse(aes(fill = Species),type = "norm",geom = "polygon",alpha = 0.25,color = NA)+
? labs(x = xlab1,y = ylab1,title = "PCA Scores Plot")+
? theme_bw()+
? scale_colour_manual(values = c("purple","orange","pink"))? ?#改變點的顏色
ggplot(data = df1,aes(x = PC1,y = PC2,color = Species))+
? geom_point(size = 2.5)+
? # 繪制置信橢圓:
? stat_ellipse(aes(fill = Species),type = "norm",geom = "polygon",alpha = 0.25,color = NA)+
? labs(x = xlab1,y = ylab1,title = "PCA Scores Plot")+
? theme_bw()+
? scale_colour_manual(values = c("purple","orange","pink"))+
? scale_fill_manual(values = c("purple","orange","pink"))? ?#可以改變填充色
下面我們試著調整文字等外觀。
ggplot(data = df1,aes(x = PC1,y = PC2,color = Species))+
? geom_point(size = 2.5)+
? # 繪制置信橢圓:
? stat_ellipse(aes(fill = Species),type = "norm",geom = "polygon",alpha = 0.25,color = NA)+
? labs(x = xlab1,y = ylab1,title = "PCA Scores Plot")+
? theme_bw()+
? scale_colour_manual(values = c("purple","orange","pink"))+
? scale_fill_manual(values = c("purple","orange","pink"))+
? theme(plot.title = element_text(hjust = 0.5,size = 15), #修改title的位置
? ? ? ? axis.text = element_text(size = 11),axis.title = element_text(size = 13), #分別修改text和title文字的大小
? ? ? ? legend.text = element_text(size = 11),legend.title = element_text(size = 13),#分別修改legend文字的大小
? ? ? ? plot.margin = unit(c(0.4,0.4,0.4,0.4),'cm'))
下面,我們再測試另外一款經常用來畫PCA的包ggbiplot,這個我經常在宏基因組領域看見,其實也是基于ggplot之上開發的包,只不過替用戶省了很多事。
library(devtools)
install_github("vqv/ggbiplot")
library(ggbiplot)
另外還可以把ggplot上面的有些屬性望上面疊加的。
ggbiplot(pca1, obs.scale = 1, var.scale = 1,
? ? ? ? #是否顯示與變量的箭頭
? ? ? ? var.axes=1,
? ? ? ? #改變箭頭對應的變量的字體大小
? ? ? ? varname.size=4,
? ? ? ? # 分組信息:
? ? ? ? groups = iris$Species,
? ? ? ? # 是否顯示置信橢圓:
? ? ? ? ellipse = T,
? ? ? ? # 是否顯示中心的圓:
? ? ? ? circle = F,
? ? ? ? labels.size = 5) +
? theme_bw()+
? theme(legend.direction = 'horizontal', legend.position = 'top')+
? scale_color_discrete(name = 'Species') +
? theme(axis.text = element_text(size = 15),axis.title = element_text(size = 15),
? ? ? ? legend.text = element_text(size = 15),legend.title = element_text(size = 15))
其中箭頭代表原始變量,方向代表原始變量和主成分的相關性,長度代表原始變量對于主成分的貢獻度。
當然,還有很多其它的包也可以實現簡便的PCA作圖。
library(factoextra)
library(FactoMineR)
iris.pca <- PCA(iris[,-5], graph = T)
PC1,2...柱狀圖
fviz_screeplot(iris.pca, addlabels = TRUE, ylim = c(0, 80))
fviz_pca_biplot(iris.pca, label = "var",
? ? ? ? ? ? ? ? habillage=iris$Species,
? ? ? ? ? ? ? ? addEllipses=TRUE,
? ? ? ? ? ? ? ? ellipse.level=0.95,
? ? ? ? ? ? ? ? ggtheme = theme_minimal())