降維往往作為預處理步驟完残,其中獨立成分分析月杉、因子分析和主成分分析比較流行,主成分分析(PCA)最為廣泛钩杰。
主成分分析會通過線性組合將多個原始變量合并成若干個主成分纫塌,這樣每個主成分都變成了原始變量的線性組合。這種轉(zhuǎn)變的目的讲弄,一方面是可以大幅降低原始數(shù)據(jù)的維度措左,同時也在此過程中發(fā)現(xiàn)原始數(shù)據(jù)屬性之間的關系。
主成分分析的主要步驟如下:
1)通常要先進行各變量的標準化工作避除,標準化的目的是將數(shù)據(jù)按照比例進行縮放怎披,使之落入一個小的區(qū)間范圍之內(nèi)胸嘁,從而讓不同的變量經(jīng)過標準化處理后可以有平等的分析和比較基礎。
2)選擇協(xié)方差陣或者相關陣計算特征根及對應的特征向量凉逛。
3)計算方差貢獻率性宏,并根據(jù)方差貢獻率的閥值選取合適的主成分個數(shù)。
4)根據(jù)主成分載荷的大小對選擇的主成分進行命名状飞。
5)根據(jù)主成分載荷計算各個主成分的得分毫胜。
將主成分進行推廣和延伸即成為因子分析(Factor Analysis),因子分析在綜合原始變量信息的基礎上將會力圖構筑若干個意義較為明確的公因子诬辈;也就是說酵使,采用少數(shù)幾個因子描述多個指標之間的聯(lián)系,將比較密切的變量歸為同一類中焙糟,每類變量即是一個因子口渔。之所以稱其為因子,是因為它們實際上是不可測量的酬荞,只能解釋嗤军。
主成分分析是因子分析的一個特例,兩者的區(qū)別和聯(lián)系主要表現(xiàn)在以下方面:
? 主成分分析會把主成分表示成各個原始變量的線性組合倚舀,而因子分析則把原始變量表示成各個因子的線性組合裙品。這個區(qū)別最直觀也最容易記住。
? 主成分分析的重點在于解釋原始變量的總方差咧党,而因子分析的重點在于解釋原始變量的協(xié)方差秘蛔。
? 在主成分分析中,有幾個原始變量就有幾個主成分傍衡,而在因子分析中深员,因子個數(shù)可以根據(jù)業(yè)務場景的需要人為指定,并且指定的因子數(shù)量不同蛙埂,則分析結果也會有差異倦畅。
? 在主成分分析中,給定的協(xié)方差矩陣或者相關矩陣的特征值是唯一時绣的,主成分也是唯一的叠赐,但是在因子分析中,因子不是唯一的屡江,并且通過旋轉(zhuǎn)可以得到不同的因子芭概。
主成分分析和因子分析在數(shù)據(jù)化運營實踐中主要用于數(shù)據(jù)處理、降維惩嘉、變量間關系的探索等方面罢洲,同時作為統(tǒng)計學里的基本而重要的分析工具和分析方法,它們在一些專題分析中也有著廣泛的應用文黎。
PCA借助于一個正交變換惹苗,將其分量相關的原隨機變量轉(zhuǎn)化成其分量不相關的新隨機變量殿较。主要作用是對高維數(shù)據(jù)進行降維。PCA把原先的n個特征用數(shù)目更少的k個特征取代鸽粉,新特征是舊特征的線性組合斜脂,這些線性組合最大化樣本方差,盡量使新的k個特征互不相關触机。
PCA 可以從數(shù)據(jù)中識別其主要特征帚戳,它是通過沿著數(shù)據(jù)最大方差方向旋轉(zhuǎn)坐標軸來實現(xiàn)的。選擇方差最大的方向作為第一條坐標軸儡首,后續(xù)坐標軸則與前面坐標軸正交片任。協(xié)方差矩陣上的特征值分析可以用一系列的正交坐標軸來獲取。
優(yōu)點:降低數(shù)據(jù)的復雜性蔬胯,識別最重要的多個特征对供。
缺點:不一定需要,且可能損失有用信息氛濒。
PCA的主要算法如下:
組織數(shù)據(jù)形式产场,以便于模型使用;
計算樣本每個特征的平均值舞竿;
每個樣本數(shù)據(jù)減去該特征的平均值(歸一化處理)京景;
求協(xié)方差矩陣;
找到協(xié)方差矩陣的特征值和特征向量骗奖;
對特征值和特征向量重新排列(特征值從大到小排列)确徙;
對特征值求取累計貢獻率;
對累計貢獻率按照某個特定比例選取特征向量集的子集合执桌;
對原始數(shù)據(jù)(第三步后)進行轉(zhuǎn)換鄙皇。
其中協(xié)方差矩陣的分解可以通過按對稱矩陣的特征向量來,也可以通過分解矩陣的SVD來實現(xiàn)仰挣,而在Scikit-learn中伴逸,也是采用SVD來實現(xiàn)PCA算法的。這里給出帶SVD的原始算法和Scikit-learn模塊實現(xiàn)的PCA類膘壶。
import numpy as np
from sklearn.decomposition import PCA
mat = [[-1,-1,0,2,1],[2,0,0,-1,-1],[2,0,1,1,0]]
Mat = np.array(mat, dtype='float64')
print('Before PCA transforMation, data is:\n', Mat)
import sys
#returns choosing how many main factors
def index_lst(lst, component=0, rate=0):
#component: numbers of main factors
#rate: rate of sum(main factors)/sum(all factors)
#rate range suggest: (0.8,1)
#if you choose rate parameter, return index = 0 or less than len(lst)
if component and rate:
print('Component and rate must choose only one!')
sys.exit(0)
if not component and not rate:
print('Invalid parameter for numbers of components!')
sys.exit(0)
elif component:
print('Choosing by component, components are %s......'%component)
return component
else:
print('Choosing by rate, rate is %s ......'%rate)
for i in range(1, len(lst)):
if sum(lst[:i])/sum(lst) >= rate:
return i
return 0
p,n = np.shape(Mat) # shape of Mat
p,n
t = np.mean(Mat, 0) # mean of each column
t
# substract the mean of each column
for i in range(p):
for j in range(n):
Mat[i,j] = float(Mat[i,j]-t[j])
Mat
# covariance Matrix
cov_Mat = np.dot(Mat.T, Mat)/(p-1)
u,d,v = np.linalg.svd(cov_Mat)
Index = index_lst(d, rate=0.95) # choose how many main factors
T2 = np.dot(Mat, u[:,:Index]) # transformed data
print('We choose %d main factors.'%Index)
print('After PCA transformation, data becomes:\n',T2)
pca = PCA(n_components=2) # n_components can be integer or float in (0,1)
pca.fit(mat) # fit the model
print('After PCA transformation, data becomes:')
print(pca.fit_transform(mat)) # transformed data