日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

主成分分析(PCA)和基于核函数的主成分分析(KPCA)入门

發(fā)布時間:2024/7/5 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 主成分分析(PCA)和基于核函数的主成分分析(KPCA)入门 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 1 前言
  • 2 PCA的原理
    • 2.1 什么是投影
    • 2.2 投影后的方差
    • 2.3 轉化為求特征值的問題
    • 2.4 符號的表示
  • 3 KPCA的原理
  • 4 PCA和KPCA在Python中的使用
    • 4.1 PCA的使用
    • 4.2 KPCA的使用
  • 5 參考文獻

1 前言

主成分分析是在做特征篩選時的重要手段,這個方法在大部分的書中都只是介紹了步驟方法,并沒有從頭到尾把這個事情給說清楚。本文的目的是把PCA和KPCA給說清楚。主要參考了YouTube上李政軒的Principal Component Analysis and Kernel Principal Component Analysis這個視頻(強烈推薦看一下)。

2 PCA的原理

2.1 什么是投影

主成分分析所做的工作就是將數(shù)據(jù)集從高維投影到低維,從而用極少的幾個特征來涵蓋大部分的數(shù)據(jù)集信息。
所謂的投影,就是下圖所示的這樣。

圖1:向量投影圖

xjx_jxj?投影到vvv上的向量為

xj′=(∣∣xj∣∣cosθ)v∣∣v∣∣x_j'=(||x_j||cos\theta)\dfrac{v}{||v||}xj?=(xj?cosθ)vv?

其中,θ\thetaθxjx_jxj?vvv的夾角。
由于向量之間的內積為

<xj,v>=∣∣xj∣∣?∣∣v∣∣?cosθ<x_j, v>=||x_j|| \cdot ||v|| \cdot cos\theta<xj?,v>=xj??v?cosθ

故有

xj′=<xj,v>∣∣v∣∣2vx_j' = \dfrac{<x_j,v>}{||v||^2}vxj?=v2<xj?,v>?v

如果我們把vvv設置成單位向量的話(即∣∣v∣∣=1||v||=1v=1)就有

xj′=<xj,v>vx_j' = <x_j,v>vxj?=<xj?,v>v

也就是說我們只要求出<xj,v><x_j,v><xj?,v>就可以知道xjx_jxj?投影到vvv上的大小了。
又由于在坐標當中,內積可以表示為

<xj,v>=xjT?v=vT?xj<x_j, v>=x_j^T \cdot v=v^T \cdot x_j<xj?,v>=xjT??v=vT?xj?

故可以用vT?xjv^T \cdot x_jvT?xj?來表示投影后的數(shù)值大小。

2.2 投影后的方差

主成分分析認為,沿某特征分布的數(shù)據(jù)的方差越大,則該特征所包含的信息越多,也就是所謂的主成分。
我們已經(jīng)知道了可以用vT?xjv^T \cdot x_jvT?xj?來表示投影后的數(shù)值大小,那么我們現(xiàn)在就可以算出投影后的方差大小了。注意我們么已經(jīng)把數(shù)據(jù)標準化過了,所以vT?xv^T \cdot xvT?x的均值為vT?0=0v^T \cdot 0=0vT?0=0。

σ2=1N?1∑i=1N(vTxi?0)2=1N?1∑i=1N(vTxi)(vTxi)\sigma^2 = \dfrac{1}{N - 1}\sum_{i=1}^{N}(v^Tx_i-0)^2=\dfrac{1}{N - 1}\sum_{i=1}^{N }(v^Tx_i)(v^Tx_i)σ2=N?11?i=1N?(vTxi??0)2=N?11?i=1N?(vTxi?)(vTxi?)

注意到vTxiv^Tx_ivTxi?是一個數(shù)值,不是向量,故有vTxi=(vTxi)Tv^Tx_i=(v^Tx_i)^TvTxi?=(vTxi?)T于是

σ2=1N?1∑i=1NvTxixiTv=vT(1N?1∑i=1NxixiT)v=vTCv\sigma^2=\dfrac{1}{N - 1}\sum_{i=1}^{N}v^Tx_ix_i^Tv=v^T(\dfrac{1}{N- 1}\sum_{i=1}^{N}x_ix_i^T)v=v^TCvσ2=N?11?i=1N?vTxi?xiT?v=vT(N?11?i=1N?xi?xiT?)v=vTCv

其中,C=1N?1∑i=1NxixiTC=\dfrac{1}{N - 1}\sum_{i=1}^{N}x_ix_i^TC=N?11?i=1N?xi?xiT?是一個m×mm \times mm×m的矩陣,mmm為特征的個數(shù)。
好了,如果我們要找到最大的方差,也就是要找到一個向量vvv使得方差最大。

2.3 轉化為求特征值的問題

我們可以將求最大方差的問題寫成

maxvTCvs.t.∣∣v∣∣=1max \quad v^TCv \\ s.t. \quad ||v||=1maxvTCvs.t.v=1

又由于∣∣v∣∣=vTv||v||=v^Tvv=vTv ,故上式即

maxvTCvs.t.vTv=1max \quad v^TCv \\ s.t. \quad v^Tv=1maxvTCvs.t.vTv=1

利用拉格朗日乘子法可以將上述問題轉化為

f(v,λ)=vTCv?λ(vTv?1)f(v,\lambda)=v^TCv-\lambda (v^Tv-1)f(v,λ)=vTCv?λ(vTv?1)

其中,f(v,λ)f(v, \lambda)f(v,λ)的平穩(wěn)點,和我們所要求的最大方差問題是等價的,即求下述方程式的解

{?f?v=2Cv?2λv=0?f?λ=vTv?1=0\begin{cases}\dfrac{\partial f}{\partial v}=2Cv-2\lambda v=0 \\ \dfrac{\partial f}{\partial \lambda}=v^Tv-1=0 \end{cases}???????v?f?=2Cv?2λv=0?λ?f?=vTv?1=0?

上述方程組等價于

{Cv=λv∣∣v∣∣=1\begin{cases}Cv=\lambda v \\ ||v|| =1\end{cases}{Cv=λvv=1?

看到了沒,Cv=λvCv=\lambda vCv=λv不就是求特征值和特征向量的方程嗎!更神奇的地方在下面,我們再回到最初求最大方差的問題

vTCv=vTλv=λvTv=λv^TCv=v^T\lambda v=\lambda v^Tv=\lambdavTCv=vTλv=λvTv=λ

是不是很神奇!要求的方差就是我們這里的特征值!所以我們只需要把Cv=λvCv=\lambda vCv=λv的特征值求出來,然后按大小排個序就,選出最大的幾個特征值,并求出對應的特征向量,最后用這幾個特征向量來完成數(shù)據(jù)集在其上的投影vTxv^TxvTx,這樣就完成了特征的篩選!

2.4 符號的表示

值得注意的是,CCC是一個m×mm \times mm×m的矩陣

C=1N?1∑i=1NxixiT=1N?1[x1,x2,...,xN][x1Tx2T...xNT]C=\dfrac{1}{N - 1}\sum_{i=1}^{N}x_ix_i^T=\dfrac{1}{N - 1}[x_1,x_2,...,x_N] \begin{bmatrix}x_1^T \\ x_2^T \\... \\ x_N^T \end{bmatrix}C=N?11?i=1N?xi?xiT?=N?11?[x1?,x2?,...,xN?]?????x1T?x2T?...xNT???????

其中,每個xix_ixi?為一個列向量

xi=[xi(1)xi(2)...xi(m)]x_i=\begin{bmatrix}x_i^{(1)} \\ x_i^{(2)} \\... \\x_i^{(m)} \end{bmatrix}xi?=??????xi(1)?xi(2)?...xi(m)????????

其中,mmm為特征的個數(shù)。
為了方便表示,我們作出如下定義

XT=[x1,x2,...,xN]X^T=[x_1,x_2,...,x_N]XT=[x1?,x2?,...,xN?]

于是,CCC可以表示為

C=1N?1XTXC=\dfrac{1}{N - 1}X^TXC=N?11?XTX

3 KPCA的原理

基于核函數(shù)的主成分分析和主成分分析的步驟是一樣的,只不過用核函數(shù)替代了原來的數(shù)據(jù)。這里對什么是核函數(shù)不作說明,請參考其它文章。
對于線性不可分的數(shù)據(jù)集,我們可以將其映射到高維上,再進行劃分。

C=1N?1∑i=1N?(xi)?(xi)T=1N[?(x1),...,?(xN)][?(x1)T...?(xN)T]C=\dfrac{1}{N - 1}\sum_{i=1}^{N}\phi (x_i)\phi(x_i)^T=\dfrac{1}{N}[\phi(x_1),...,\phi(x_N)]\begin{bmatrix}\phi(x_1)^T \\ ... \\ \phi(x_N)^T \end{bmatrix}C=N?11?i=1N??(xi?)?(xi?)T=N1?[?(x1?),...,?(xN?)]????(x1?)T...?(xN?)T????

我們令

XT=[?(x1),...,?(xN)]X^T=[\phi(x_1),...,\phi(x_N)]XT=[?(x1?),...,?(xN?)]

那么

C=1N?1XTXC=\dfrac{1}{N - 1}X^TXC=N?11?XTX

在這里,?(x)\phi(x)?(x)我們是不知道的,所以上式是沒法算的。就算知道了,計算成本也太大了。故引入核函數(shù),我們知道核函數(shù)有

K=XXT=[?(x1)T...?(xN)T][?(x1),?,?(xN)]=[κ(x1,x1)...κ(x1,xN)???κ(xN,x1)?κ(xN,xN)]K=XX^T=\begin{bmatrix} \phi(x_1)^T \\...\\ \phi(x_N)^T \end{bmatrix} [ \phi(x_1) , \cdots ,\phi(x_N)]=\begin{bmatrix} \kappa(x_1,x_1) & ... & \kappa(x_1,x_N) \\ \vdots & \ddots & \vdots \\ \kappa(x_N, x_1) & \cdots & \kappa(x_N,x_N) \end{bmatrix}K=XXT=????(x1?)T...?(xN?)T????[?(x1?),?,?(xN?)]=????κ(x1?,x1?)?κ(xN?,x1?)?...???κ(x1?,xN?)?κ(xN?,xN?)?????

上述的KKK我們根據(jù)核函數(shù)的性質是可以算出來的,現(xiàn)在來看看KKKCCC之間有沒有關系。
如果要求KKK的特征值和特征向量的話,我們有下式

(XXT)u=λu(XX^T)u=\lambda u(XXT)u=λu

其中,uuu為矩陣KKK的特征向量,λ\lambdaλ為矩陣KKK的特征值。
我們對左右兩邊同時左乘一個XTX^TXT

XT(XXT)u=λXTuX^T(XX^T)u=\lambda X^TuXT(XXT)u=λXTu

(XTX)(XTu)=λ(XTu)(X^TX)(X^Tu)=\lambda (X^Tu)(XTX)(XTu)=λ(XTu)

又由于(N?1)?C=XTX(N - 1) \cdot C=X^TX(N?1)?C=XTX,所以我們發(fā)現(xiàn)矩陣KKKCCC的特征值是相同的,都為λ\lambdaλCCC的特征向量為XTuX^TuXTu。
由于我們希望特征向量是單位向量,所以我們對其做一下單位化

v=1∣∣XTu∣∣XTu=1uTXXTuXTu=1uTKuXTu=1uTλuXTu=1λXTuv=\dfrac{1}{||X^Tu||}X^Tu=\dfrac{1}{\sqrt{u^TXX^Tu}}X^Tu=\dfrac{1}{\sqrt{u^TKu}}X^Tu=\dfrac{1}{\sqrt{u^T\lambda u}}X^Tu=\dfrac{1}{\sqrt{\lambda}}X^Tuv=XTu1?XTu=uTXXTu?1?XTu=uTKu?1?XTu=uTλu?1?XTu=λ?1?XTu

在上式中,λ\lambdaλuuu可以通過矩陣KKK求得,但是XTX^TXT仍舊是不可知的。那么CCC的特征向量還是算不出來,難道費了這么大的勁,我們白算了?不急,我們接著往下看。雖然求不出vvv,但是vvv并不是我們的最終目標,我們只要知道xxxvvv上的投影就可以了

vT?(xj)=(1λXTu)T?(xj)=1λuTX?(xj)=1λuT[?(x1)T??(xN)T]?(xj)=1λuT[κ(x1,xj)?κ(xN,xj)]v^T\phi(x_j)=(\dfrac{1}{\sqrt{\lambda}}X^Tu)^T\phi(x_j)=\dfrac{1}{\sqrt{\lambda}}u^TX\phi(x_j)=\dfrac{1}{\sqrt{\lambda}}u^T\begin{bmatrix} \phi(x_1)^T \\ \vdots \\ \phi(x_N)^T \end{bmatrix} \phi(x_j)=\dfrac{1}{\sqrt{\lambda}}u^T\begin{bmatrix} \kappa(x_1, x_j) \\ \vdots \\ \kappa(x_N, x_j) \end{bmatrix}vT?(xj?)=(λ?1?XTu)T?(xj?)=λ?1?uTX?(xj?)=λ?1?uT?????(x1?)T??(xN?)T??????(xj?)=λ?1?uT????κ(x1?,xj?)?κ(xN?,xj?)?????

上式中所有的量都是可以求得的,也就說我們在沒有求出特征向量的情況下,直接算出了樣本在特征向量上的投影!
這樣一來問題就解決了!是不是很神奇!

4 PCA和KPCA在Python中的使用

在python的sklearn包中,已經(jīng)對PCA和KPCA進行了實現(xiàn),我們只需要調用函數(shù)即可,非常方便。

4.1 PCA的使用

我們用的數(shù)據(jù)集是UCI上關于葡萄酒的數(shù)據(jù)集,得到數(shù)據(jù)集后對其進行預處理,使得其均值為0。

import pandas as pd from sklearn.preprocessing import StandardScalerdf = pd.read_csv('http://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data', header=None) x, y = df.iloc[:, 1:].values, df.iloc[:, 0].values sc = StandardScaler() x = sc.fit_transform(x)

這個時候得到的xxx是一個178×13178 \times 13178×13規(guī)模的數(shù)據(jù)集,也就是說有131313個特征,每個特征下有178178178個數(shù)據(jù)。
我們用主成分分析法將131313個特征通過線性組合得到一個222個特征的數(shù)據(jù)集。

from sklearn.decomposition import PCApca = PCA(n_components=2) x_pca = pca.fit_transform(x)

然后我們來看下效果

import matplotlib.pyplot as pltplt.scatter(x_pca[y==1, 0], x_pca[y==1, 1], color='red', marker='^', alpha=0.5) plt.scatter(x_pca[y==2, 0], x_pca[y==2, 1], color='blue', marker='o', alpha=0.5) plt.scatter(x_pca[y==3, 0], x_pca[y==3, 1], color='lightgreen', marker='s', alpha=0.5) plt.xlabel('PC1') plt.ylabel('PC2') plt.show()

可以得到

圖2:葡萄酒數(shù)據(jù)主成分分析后效果

很顯然,此時已經(jīng)可以看成是線性可分的數(shù)據(jù)集了,效果不錯。

4.2 KPCA的使用

PCA的使用是有局限性的,如果遇到了,一個像下面這樣的線性不可分的數(shù)據(jù)集,就比較麻煩了。

from sklearn.datasets import make_moonsx2, y2 = make_moons(n_samples=100, random_state=123)plt.scatter(x2_std[y2==0, 0], x2_std[y2==0, 1], color='red', marker='^', alpha=0.5) plt.scatter(x2_std[y2==1, 0], x2_std[y2==1, 1], color='blue', marker='o', alpha=0.5) plt.xlabel('PC1') plt.ylabel('PC2') plt.show()

圖3:非線性不可分的數(shù)據(jù)集

不相信的話我們可以用PCA先試下看

x2_std = sc.fit_transform(x2) x_spca = pca.fit_transform(x2_std)fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(14,6)) ax[0].scatter(x_spca[y2==0, 0], x_spca[y2==0, 1], color='red', marker='^', alpha=0.5) ax[0].scatter(x_spca[y2==1, 0], x_spca[y2==1, 1], color='blue', marker='o', alpha=0.5) ax[1].scatter(x_spca[y2==0, 0], np.zeros((50,1))+0.02, color='red', marker='^', alpha=0.5) ax[1].scatter(x_spca[y2==1, 0], np.zeros((50,1))+0.02, color='blue', marker='o', alpha=0.5) ax[0].set_xlabel('PC1') ax[0].set_ylabel('PC2') ax[1].set_ylim([-1, 1]) ax[1].set_yticks([]) ax[1].set_xlabel('PC1') plt.show()

圖4:PCA在非線性可分數(shù)據(jù)集的效果

從圖中可以看出,經(jīng)過主成分分析之后,數(shù)據(jù)仍舊是線性不可分的。接下來,我們用基于核函數(shù)的主成分分析來試下看。

from sklearn.decomposition import KernelPCAkpca = KernelPCA(n_components=2, kernel='rbf', gamma=15) x_kpca = kpca.fit_transform(x2_std)fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(14,6)) ax[0].scatter(x_kpca[y2==0, 0], x_kpca[y2==0, 1], color='red', marker='^', alpha=0.5) ax[0].scatter(x_kpca[y2==1, 0], x_kpca[y2==1, 1], color='blue', marker='o', alpha=0.5) ax[1].scatter(x_kpca[y2==0, 0], np.zeros((50,1))+0.02, color='red', marker='^', alpha=0.5) ax[1].scatter(x_kpca[y2==1, 0], np.zeros((50,1))+0.02, color='blue', marker='o', alpha=0.5) ax[0].set_xlabel('PC1') ax[0].set_ylabel('PC2') ax[1].set_ylim([-1, 1]) ax[1].set_yticks([]) ax[1].set_xlabel('PC1') plt.show()

圖5:KPCA在非線性可分數(shù)據(jù)集的效果

由圖可知,只需要把數(shù)據(jù)集投影到經(jīng)變換后的特征PC1PC1PC1上就可以實現(xiàn)線性劃分了,這個時候只需要一個特征PC1PC1PC1就夠了。

5 參考文獻

[1] https://www.youtube.com/watch?v=G2NRnh7W4NQ&t=1s
[2] Raschka S. Python Machine Learning[M]. Packt Publishing, 2015.

總結

以上是生活随笔為你收集整理的主成分分析(PCA)和基于核函数的主成分分析(KPCA)入门的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。