標籤:大小 ima sum 變異 tor body span 使用 資料
主成分分析(principal component analysis,簡稱PCA)是一種經典且簡單的機器學習演算法,其主要目的是用較少的變數去解釋原來資料中的大部分變異,期望能將現有的眾多相關性很高的變數轉化為彼此互相獨立的變數,並從中選取少於原始變數數目且能解釋大部分資料變異情況的若干新變數,達到降維的目的,下面我們先對PCA演算法的思想和原理進行推導:
主成分即為我們通過原始變數的線性組合得到的新變數,這裡假設xi(i=1,2,...,p)為原始變數,yi(i=1,2,...,p)為主成分,他們之間的關係如下:
其中,uij為第i個主成分yi與第j個原始變數xj間的線性相關係數,y1,y2,... ... ,yp分別為第一、二...、p主成分,且u11,... ... ,u1p通過與對應的原始變數進行線性組合,使得y1得到最大解釋變異的能力,接著u21,... ... ,u2p通過與對應的原始變數進行線性組合,使得y2對原始變數中的未被y1解釋的變異部分獲得最大的解釋能力,依次類推,直到p個主成分均求出;通常我們基於對原始變數降維的目的,會從這p個主成分中選取少於p的m個成分,且希望m越小的同時,總的解釋能力能超過80%,值得注意的是,得到的這些主成分彼此之間線性無關;
設y=a1x1+a2x2+...+apxp=a‘x,其中a=(a1,a2,...,ap)‘,x=(x1,x2,...,xp)‘,求主成分就是尋找x的線性函數a‘x,使得相應的方差達到最大,即var(a‘x)=a‘∑a,且a‘a=1(使a唯一),∑為x的共變數矩陣;
推導:
基於實對稱矩陣的性質(每個實對稱矩陣都可以分解為單位實特徵向量和實特徵值),譬如對任意實對稱矩陣A,有
A=QΤQ‘
其中,Q為列向量由A的特徵向量組成的矩陣,T為對角線元素為A的特徵值降序排列的對角矩陣,注意這裡的特徵值與Q中特徵列向量一一對應;而針對這個性質,回到PCA中,因為x的共變數矩陣∑為實對稱矩陣,設∑的特徵根為λ1≥λ2≥...≥λp,相對應的單位特徵向量為u1,u2,...,up,令U=(u1,u2,...,up),則U‘U=UU‘=I,即U為正交陣,且:
當取a=u1時:
所以y1=u‘1x就是第一主成分,它的方差為:
同理:
通過上述推導,我們可以使用原始變數的共變數矩陣來求解各主成分,在計算出所有主成分之後,就要進行主成分的選擇,由於主成分與原始變數的共變數矩陣直接掛鈎,我們定義第k個主成分yk的方差貢獻率:
則主成分的選擇過程即為從貢獻率最大的主成分算起,一直到累計貢獻率滿足要求為止;
再定義主成分負荷(loadings,在因子分析中稱為因子載荷):
即為第i個主成分與第j原始變數的相關係數,矩陣A=(aij)稱為因子載荷矩陣,在實際中常用aij代替uij作為主成分係數,因為它是標準化係數,能反映變數影響的大小;
到此我們已經知道了主成分分析的主要原理,接下來我們分別在Python中自編函數來實現這個過程:
Python
使用numpy和sklearn包搭建自訂的PCA演算法(除標準化和求解特徵值、特徵向量外其餘功能均由自訂函數實現)
import numpy as npimport pandas as pdfrom sklearn import preprocessing‘‘‘讀入資料‘‘‘original_data = pd.read_csv(r‘C:\Users\windows\Desktop\kaggle\A\wine_red.csv‘,encoding=‘ANSI‘)‘‘‘資料預先處理‘‘‘data = np.asmatrix(original_data.iloc[:,4:])class My_PCA(): def __init__(self): print(‘自編PCA演算法‘) ‘‘‘根據輸入的資料集和指定的累計貢獻率閾值‘‘‘ def PCA(self,data,alpha=0.8): ‘‘‘資料標準化‘‘‘ scaler = preprocessing.StandardScaler().fit(data) input = scaler.transform(data).astype(dtype=‘float32‘) ‘‘‘計算相關係數矩陣‘‘‘ cor = np.corrcoef(input) ‘‘‘計算相關係數矩陣的特徵值與對應的特徵向量‘‘‘ eigvalue = np.linalg.eig(cor)[0].astype(dtype=‘float32‘) eigvector = np.linalg.eig(cor)[1].astype(dtype=‘float32‘) ‘‘‘計算各主成分方差貢獻‘‘‘ contribute = [eigvalue[i] / np.sum(eigvalue) for i in range(len(eigvalue))] ‘‘‘儲存特徵值排序後與之前對應的位置‘‘‘ sort = np.argsort(contribute) ‘‘‘根據傳入的累計貢獻率閾值alpha提取所需的主成分‘‘‘ pca = [] token = 0 i = 1 while (token <= alpha): token = token + contribute[sort[len(input) - i]] pca.append(sort[len(input) - i]) i += 1 ‘‘‘將得到的各主成分對應的特徵值和特徵向量儲存下來並作為傳回值‘‘‘ PCA_eig = {} for i in range(len(pca)): PCA_eig[‘第{}主成分‘.format(str(i+1))] = [eigvalue[pca[i]], eigvector[pca[i]]] return PCA_eig‘‘‘將演算法所在的類賦值給自訂變數‘‘‘test = My_PCA()‘‘‘調用類中的PCA演算法來產出所需的主成分對應的特徵值和特徵向量‘‘‘pca = test.PCA(data)‘‘‘顯示最大的主成分對應的特徵值和特徵向量‘‘‘pca[‘第1主成分‘]
查看第1主成分結果如下:
以上就是關於PCA演算法的原理及自編函數實現,下一篇中我們將仔細介紹Python和R中各自成熟的第三方PCA函數,敬請期待。
(資料科學學習手劄20)主成分分析原理推導&Python自編函數實現