內容:
將M個N維原始數據映射爲M個K維數據,同時最大程度保留原始數據的特徵
輸入:
M*N矩陣
輸出:
M*K矩陣
原理:
1. 計算樣本協方差矩陣(N*N)
例如N=3時,樣本協方差矩陣爲:
2. 將協方差矩陣對角化
對於任意對稱矩陣A,必定存在矩陣Q和∑,使得
其中∑爲對角矩陣,∑對角線上的值即A的特徵值,Q的每個向量即A的特徵向量
3. 選出最大的K個特徵值對應的特徵向量組成降維矩陣
每個特徵向量都是N維,組成N*K矩陣
4. 將原矩陣與降維矩陣相乘得到最終矩陣
將N維數據降爲K維的同時保留了最大特徵(協方差矩陣特徵值中最大的)
實現:
1. Python實現
##Python實現PCA
import numpy as np
#X is M*N matrix
#k is the dimensions you want
def pca(X,k):
#mean of each feature
M, N = X.shape
mean=np.array([np.mean(X[:,i]) for i in range(N)])
#normalization
norm_X=X-mean
#scatter matrix is N*N
scatter_matrix=np.dot(norm_X.T,norm_X)
#Calculate the eigenvectors and eigenvalues
eig_val, eig_vec = np.linalg.eig(scatter_matrix)
eig_pairs = [(np.abs(eig_val[i]), eig_vec[:,i]) for i in range(N)]
# sort eig_vec based on eig_val from highest to lowest
eig_pairs.sort(reverse=True)
# select the top k eig_vec
feature=np.array([ele[1] for ele in eig_pairs[:k]])
#get new data
data=np.dot(norm_X,feature.T)
return data
X = np.array([[-1, 1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
print(pca(X,1))
'''
[[-0.50917706]
[-2.40151069]
[-3.7751606 ]
[ 1.20075534]
[ 2.05572155]
[ 3.42937146]]
'''
2. sklearn庫實現
from sklearn.decomposition import PCA
pca=PCA(n_components=1)
P = np.array([[-1, 1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
pca.fit(P)
print(pca.transform(P))
'''
[[ 0.50917706]
[ 2.40151069]
[ 3.7751606 ]
[-1.20075534]
[-2.05572155]
[-3.42937146]]
'''
PCA函數:
print(help(PCA))
1. 函數原型
PCA(n_components=None, copy=True, whiten=False, svd_solver='auto', tol=0.0, iterated_power='auto', random_state=None)
- n_components: int, float, None 或 string,PCA算法中所要保留的主成分個數,也即保留下來的特徵個數,如果 n_components = 1,將把原始數據降到一維;如果賦值爲string,如n_components=‘mle’,將自動選取特徵個數,使得滿足所要求的方差百分比;如果沒有賦值,默認爲None,特徵個數不會改變(特徵數據本身會改變)。
- copy:True 或False,默認爲True,即是否需要將原始訓練數據複製。
- whiten:True 或False,默認爲False,即是否白化,使得每個特徵具有相同的方差。
2. PCA對象的屬性
- explained_variance_ratio_:返回所保留各個特徵的方差百分比,如果n_components沒有賦值,則所有特徵都會返回一個數值且解釋方差之和等於1。
- n_components_:返回所保留的特徵個數。
3. PCA常用方法
- fit(X): 用數據X來訓練PCA模型。
- fit_transform(X):用X來訓練PCA模型,同時返回降維後的數據。
- inverse_transform(newData) :將降維後的數據轉換成原始數據,但可能不會完全一樣,會有些許差別。
- transform(X):將數據X轉換成降維後的數據,當模型訓練好後,對於新輸入的數據,也可以用transform方法來降維。