1. 程式人生 > >(數據科學學習手劄20)主成分分析原理推導&Python自編函數實現

(數據科學學習手劄20)主成分分析原理推導&Python自編函數實現

encoding 處理 enter png ces pen pos 資料 font

主成分分析(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個主成分中選取少於pm個成分,且希望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 np
import pandas as pd
from sklearn import preprocessing


‘‘‘讀入數據‘‘‘
original_data = pd.read_csv(rC:\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自編函數實現