--- GA: UA-159972578-2 --- ###### tags: `R` `PCA` `Principal Component Analysis` `Visualization` `尺度縮減` `主成分分析` `資料前處理` # PCA 主成分分析 (Principal Component Analysis) 看code完整執行結果: [Rpubs Ver.](https://rpubs.com/RitaTang/pca) [Play with PCA Shiny App](http://ba.cm.nsysu.edu.tw:4949/tonychuo/PCA.Rmd) ![](https://i.imgur.com/gleUY4k.png) + O&M和environmental survey方向完全相反,代表兩個變數負相關 + cabel和environmental survey呈現直角,代表互相獨立 ![](https://i.imgur.com/DMInQIp.png) + 兩段式趨勢分析 + 期數可以自訂,這裡只做了兩段,可以看出兩期間移動的軌跡 ## 何謂PCA + 一種尺度縮減的方法 + 將高維度資料降至低維度資料 + 降維的過程中,保持資料裡每個變數的變異性 + 一顆西瓜有很多種切法/切面,找出從哪個切面可以看到最多西瓜籽 + 先從資訊保留量最大的方向壓縮(保留資料變數之間的變異性) + 通常在壓第一次的時候就解釋了60-80%的變異 + 再往能保留最多資訊的方向繼續壓縮(邊際效果遞減) + ![](https://i.imgur.com/uSN84An.png) + ![](https://i.imgur.com/0pdFBOn.png) + 做PCA可以看到: + 變數 v.s 變數的關係 + 獨立(直角) + 正相關(在同一側) + 負相關(在反方向) + 資料點 v.s 變數 + 資料點在變數間表現突出(outlier) + 資料點 v.s 資料點 + Cluster:點與點靠得很近為一群(組內差異小,組間差異大) + 用於競爭/策略分析 + 不用再一張一張圖去畫、放在一起看(太慢又太多維度組合要畫) + 將資料所有的變數投射在一個平面上觀察整體趨勢 + 加上時間因素可以看出移動方向/趨勢 + 看得到對手和自己的定位變化 + 決定自己未來要往哪裡去 ## 【範例1】分析每隻隊伍對不同武器的關係 + col(var):武器 + row(ind):隊伍 ### 資料介紹 + 遊戲比賽的資料,有13隻隊伍對於5個武器的使用量及獲勝的比率 + tot_rate:各隊伍整體獲勝的比率 + xxx_rate:各隊伍使用各類武器的獲勝的比率 + xxx_num:武器的使用量 ### 讀取資料 ```{r echo=FALSE} pacman::p_load(FactoMineR,factoextra,dplyr,corrplot) load("data/csdf2.rdata") str(csdf) ``` ``` ## 'data.frame': 13 obs. of 11 variables: ## $ tot_rate : num 0.546 0.453 0.585 0.498 0.353 ... ## $ USP_wr : num 0.408 0.646 0.333 0.6 0.481 ... ## $ HE_wr : num 0.702 0.506 0.333 0.333 0.36 ... ## $ Incendiary_wr : num 0.474 0.324 0.503 0.271 0.456 ... ## $ M4A4_wr : num 0.542 0.535 0.498 0.462 0.513 ... ## $ AK47_wr : num 0.596 0.405 0.812 0.597 0.144 ... ## $ USP_num : int 76 65 84 30 81 78 81 38 129 20 ... ## $ HE_num : int 47 79 42 9 50 51 46 9 129 28 ... ## $ Incendiary_num: int 253 207 191 70 171 299 169 72 486 62 ... ## $ M4A4_num : int 216 286 219 143 195 216 193 143 383 127 ... ## $ AK47_num : int 441 291 293 196 284 437 272 196 942 128 ... ``` ### 標出資料點與變數(維度)方向 ```{r} df = csdf[7:11] # 7:11是使用武器的獲勝次數 pca = PCA(df) ``` ![](https://i.imgur.com/Z5uZUP8.png) ![](https://i.imgur.com/7Rdf4zY.png) ```{r} fviz_pca_var(pca) # 美化一點的PCA函數(加上網格) ``` ![](https://i.imgur.com/clSJyUr.png) ### PCA維度解釋程度 ```{r} get_eigenvalue(pca) # 特徵值/資訊保留量/累積資訊保留量 ``` ``` ## eigenvalue variance.percent cumulative.variance.percent ## Dim.1 4.42066955 88.4133910 88.41339 ## Dim.2 0.33382021 6.6764041 95.08980 ## Dim.3 0.15645429 3.1290858 98.21888 ## Dim.4 0.06564889 1.3129778 99.53186 ## Dim.5 0.02340706 0.4681412 100.00000 ``` + Dim.1 解釋了88%的變異 + 有邊際效果遞減,累加到解釋完所有的變異(100%) ### 將兩張圖疊在一起,畫出PCA圖 ```{r} fviz_pca_biplot(pca, repel=T, # repel讓label不要重疊 pointsize="cos2", col.ind="#E7B800", alpha.ind=0.3) # pointsize放變數就會自動生成legend # col.ind放分群變數 ``` ![](https://i.imgur.com/NW2bamI.png) + 可以看出變數(武器)的維度經壓縮後都投射在同一方向 + 正相關 + 點對軸線(無限延伸的方向)畫垂直線,該落點即為該維度上的值 + Dim1+2保留了94%資訊量(解釋了94%的變異),因此可以相信這張圖 + 軸線的長度代表一個標準差 + 有些PCA圖會畫出長短不一的射線,有些怕混淆會畫等長 + 愈短代表變異量愈小 ### 集群分析 ```{r} kmg = kmeans(df,3)$cluster %>% factor table(kmg) ``` ### 結合集群分析的PCA分析圖 + 圖1 (將同一群的用橢圓匡起來) ```{r} fviz_pca_biplot( pca, repel=T, col.var="black", col.ind=kmg, alpha.ind=0.6, pointshape=16, pointsize=10*csdf$tot_rate, labelsize=3, addEllipses = TRUE, ellipse.level = 0.6, mean.point = F) # addEllipses畫分群的橢圓 # 1,2群太小太遠畫不出來 # level是橢圓的範圍大小 # mean.point幫忙計算群中心點並標出來(但會太混雜所以拿掉) ``` ![](https://i.imgur.com/VFTVvT3.png) + 圖2 (點與點之間連線) ```{r} fviz_pca_biplot( pca, repel=T, col.var="black", col.ind=kmg, alpha.ind=0.6, pointshape=16, pointsize=10*csdf$tot_rate, labelsize=3, addEllipses = TRUE, ellipse.type = "convex", mean.point = F) # convex是將點連線 ``` ![](https://i.imgur.com/qkHanAU.png) ### 正規化 + 為了修正變數都往同個方向投射,我們應該看<b>比例</b>而非看<b>數量</b>。 + 因為比較「事件」會受到「數量大小」影響,導致PCA壓縮後都擠在「同方向」(正相關)。 + 例如: + 做文字分析時,寫長文的人/感性的人,情緒普遍偏高;相反的人情緒較平淡。 + 比較結婚、離婚、出生、死亡(事件)受到縣市的大小/人口密度影響。 + 這樣是不能直接比較的,比較要放在同一個基準;遇到這種情況,做正規化比較好。 + 正規化:數量轉比率0~1(皆是正數)。 + 標準化=常態化:平均值是0,標準差是1。 + 有正有負,中間是0。 + 當0對你有意義/重要的、有兩極在擺動的情況就很適合做標準化。 ```{r} # regulization mx = csdf[7:11] %>% as.matrix() mx2 = mx/rowSums(mx) # 正規化的方向是row(因為是每個隊伍) # 如果是直的方向的正規化,要先做轉置: t(t(x)/rowSums(t(x))) pca2=PCA(mx2) # kmeans kmg2 = kmeans(df,3)$cluster %>% factor table(kmg2) # plot fviz_pca_var(pca2) # 維度投射圖 fviz_pca_biplot( pca2, repel=T, col.var="black", col.ind=kmg2, alpha.ind=0.6, pointshape=16, pointsize=10*csdf$tot_rate, labelsize=3, addEllipses = TRUE, ellipse.type = "convex", mean.point = F) ``` ![](https://i.imgur.com/oraroT3.png) ![](https://i.imgur.com/0n1nm8L.png) ## 【範例2】獲勝比率 <b>已經是比率,不需做正規化</b> ```{r} mx3 = csdf[,1:6] %>% as.matrix() # 1:6是使用武器的獲勝比率 pca3=PCA(mx3) # kmeans kmg3 = kmeans(mx3,4)$cluster %>% factor table(kmg3) # plot fviz_pca_biplot( pca3, repel=T, col.var="black", col.ind=kmg3, alpha.ind=0.6, pointshape=16, pointsize=10*csdf$tot_rate, labelsize=3, addEllipses = TRUE, ellipse.type = "convex", mean.point = FALSE) ``` ![](https://i.imgur.com/hjrgCHR.png)