【數據降維】主成分分析法
主要內容
本系列馬上就要進入建模的階段了,但是在這之前還有一些準備工作要做,能讓我們最終得到的分析結果更好,數據降維便是其中之一。
數據降維實際上是對輸入特徵的一次精簡。通常來說當我們已經通過數據處理得到了一組變數(特徵)之後,我們並不會直接將這些變數輸入某種統計模型(比如SVM)。因為第一,某些變數之間可能存在著某種線性非線性的關係,如果一股腦將全部變數都輸入模型可能會影響模型的精度。第二,變數(特徵)數量相對數據條數有可能過大,從而不符合某些模型的需求。打個比方,如果你有100條數據,卻有200個特徵,那麼大多數的模型都回報錯,提醒你變數(特徵)數量太多。
正是由於以上的原因也是為了更好的理解數據,閱讀數據的信息,我們會採用一些數據降維的辦法對變數(特徵)數目進行一定程度的縮減,在不丟失絕大多數信息的前提下儘可能的生成解釋力更強的特徵,同時去除不必要的特徵。
我們這篇文章主要介紹的就是主成分分析法。主成分分析(Principal Component Analysis,PCA)大概是數據降維最常用的方法之一了,主要通過線性變換的方式,達到特徵壓縮解釋變數的目的。該演算法主要分為6個步驟:
1)構建p*n階的變數矩陣
2)將p*n階的變數矩陣X的每一行(代表一個屬性欄位)進行標準化
3)求出協方差矩陣C
4)求出協方差矩陣的特徵值及對應的特徵向量
5)將特徵向量按對應特徵值大小從上到下按行排列成矩陣,取前k列組成矩陣P
6)Y=XP即為降維到k維後的數據
2-5所設計的演算法步驟,主要是為了找到p個變數的正規化線性組合,從而使它的方差達到最大。在本篇文章里我們並不會對其中所涉及的數學推導進行解讀,對於大部分R語言的使用者,我們只需要了解模型的輸入與輸出,了解我們可以用PCA幹什麼就OK了。
1.輸入
PCA演算法的輸入是一個變數矩陣,即每列代表一個變數,每行代表一條數據。舉個例子,如果我們有三個變數,四條數據,那麼此時n=4,p=3,我們就可以生生如下的4*3階變數矩陣:
[1,] [2,] [3,][1,] x1 y1 z1[2,] x2 y2 z2[3,] x3 y3 z3[4,] x4 y4 z4
這個變數矩陣就是我們要輸入R語言中PCA函數的東西。
2.輸出
介紹完了輸入的變數矩陣,我們再來說說我們期望以及我們可以從PCA這個方法中得到的東西。
我們使用PCA方法的最終目的是為了一組新的變數來代替原有的變數,即生成原有變數的一種重新組合(線性組合或非線性組合)的方法。比如,如果原有的變數是x,y,z,那麼我們可能最終通過某種計算得知x^2+3y,5y-2z^3已經可以解釋98%的原有變數x,y,z中所包含的信息,那麼我們就將使用x^2+3y,5y-2z^3作為我們新的模型變數。
上面兩個新變數是過去變數的非線性組合,而PCA生成的則是變數之間的線性組合。這樣的線性組合可以用一個矩陣清晰的表達,比如以下矩陣(本文後面例子的結果):
> p$loadingsLoadings: Comp.1 Comp.2 Comp.3 Comp.4Sepal.Length 0.361 -0.657 -0.582 0.315Sepal.Width -0.730 0.598 -0.320Petal.Length 0.857 0.173 -0.480Petal.Width 0.358 0.546 0.754
其中Comp.1-Comp.4就是我們新生成的變數,而Sepal.Length, Sepal.Width, Petal.Length, Petal.Width則是原始的變數,通過這個矩陣我們可以知道(以Comp.1和Comp.2為例):
Comp.1=0.361*Sepal.Length+0.857*Petal.Length+0.358*Petal.WidthComp.2=-0.657*Sepal.Length-0.730*Sepal.Width+0.173*Petal.Length
實際上,這就是我們期望的輸出,亦即想要的新變數的生成方法。
下面我們就真刀實槍用R語言的對一組變數進行主成分分析,Rcode非常簡單:
R語言里使用PCA方法
我們這次使用的是iris這個數據集(經常被各種例子用到的經典數據集),數據集概況如下:
> head(iris) Sepal.Length Sepal.Width Petal.Length Petal.Width Species1 5.1 3.5 1.4 0.2 setosa2 4.9 3.0 1.4 0.2 setosa3 4.7 3.2 1.3 0.2 setosa4 4.6 3.1 1.5 0.2 setosa5 5.0 3.6 1.4 0.2 setosa6 5.4 3.9 1.7 0.4 setosa
顯然,前四列是鳶尾花的不同特徵,最後一列是其屬於的品種,那麼輸入的模型矩陣即為該數據集的前四列的矩陣,即:
iris[,1:4]
接著我們只需使用一個函數(princomp())就可以完成主成分分析的工作:
p<-princomp(iris[,1:4])
我們可以繼續查看返回的結果:
> summary(p)Importance of components: Comp.1 Comp.2 Comp.3 Comp.4Standard deviation 2.0494032 0.49097143 0.27872586 0.153870700Proportion of Variance 0.9246187 0.05306648 0.01710261 0.005212184Cumulative Proportion 0.9246187 0.97768521 0.99478782 1.000000000> p$loadingsLoadings: Comp.1 Comp.2 Comp.3 Comp.4Sepal.Length 0.361 -0.657 -0.582 0.315Sepal.Width -0.730 0.598 -0.320Petal.Length 0.857 0.173 -0.480Petal.Width 0.358 0.546 0.754
從summary()里我們可以看到,主成分分析法為我們生成了四個新的變數,第一個變數可以解釋原數據92.5%的方差,第二個變數則可以解釋元數據5.3%的方差。顯然,這兩個數據加起來已經可以解釋原數據97.8%的信息了,所以我們可以用這兩個新的變數代替原來四個初始變數。
從loadings裡面我們可以進一步查看這四個變數(主要關注的是前兩個變數)是怎麼生成的,通過返回的矩陣我們可知:
Comp1=0.361*Sepal.Length+0.857*Petal.Length+0.358*Petal.WidthComp2=-0.657*Sepal.Length-0.730*Sepal.Width+0.173*Petal.Length
可以看到,新生成的變數是原有變數的線性組合。
還記得原來演算法的第五步和第六步嗎?我們重溫一下:
5)取前k列組成矩陣P
6)Y=XP即為降維到k維後的數據
P是於是我們可以用一行代碼通過矩陣乘法生成新的變數:
newfeature<-as.matrix(iris[,1:4])%*%as.matrix(p$loadings[,1:2])
結語
更多內容請關注我的專欄:R語言與數據挖掘 - 知乎專欄
或者關注我的知乎賬號:溫如
推薦閱讀: