機器學習算法之主成分分析——代碼實現與相關理論分析

引入

主成分分析(PCA)是一種常見的數據分析方法,通過該方法我們可以對數據進行降維操作,並且保留方差較大(信息量大)的維度。
爲了引入相關概念,我們先看一組數據:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
# 總共十個樣本 每個樣本有兩個特徵值
data = pd.read_csv('principal.csv') # 該數據文件可自己準備
data

在這裏插入圖片描述
該數據中有10個樣本,每個樣本有兩個特徵值。爲了更爲直觀,我們把該數據畫成散點圖呈現出來:

plt.xlim((-3, 3))
plt.ylim((-3, 3))
plt.scatter(x, y)

在這裏插入圖片描述
數據呈現二維分佈,現要求通過主成分分析提取出方差最大的一個維度。

實現過程與理論分析

首先可以看到數據點分佈的很不規律,我們要對數據進行中心化操作,使得樣本點具有一定相關性。

# 首先中心化
x_mean = np.mean(x)
y_mean = np.mean(y)
x_n = x - x_mean
y_n = y - y_mean
# 中心化結果
plt.xlim((-3, 3))
plt.ylim((-3, 3))
plt.scatter(x_n, y_n)

中心化結果
結果展示如圖所示,可以看出樣本點圍繞原點分佈。

其次,我們要計算出協方差矩陣(對角矩陣)。

# 豎直方向上合併爲兩行
# 計算出每個維度上的協方差對角矩陣
martix = np.cov(np.vstack((x_n.reshape(1, -1), y_n.reshape(1, -1))))
martix

結果爲:

array([[0.61655556, 0.61544444],
[0.61544444, 0.71655556]])

由於每個樣本有2個特徵取值,所以協方差矩陣爲2*2的。對角線上分別是x和y的方差,非對角線上是協方差。協方差大於0表示x和y若有一個增,另一個也增;小於0表示一個增,一個減;協方差爲0時,兩者獨立。協方差絕對值越大,兩者對彼此的影響越大,反之越小。
如果樣本是三維的,那麼協方差矩陣爲:(可以看出協方差矩陣屬於對稱矩陣)
在這裏插入圖片描述
第三,求協方差矩陣的特徵值、特徵向量。

# 求協方差矩陣的特徵值、特徵向量
lamt = np.linalg.eig(martix)
lamt

結果爲:

(array([0.0490834 , 1.28402771]), array([[-0.73517866, -0.6778734 ],
[ 0.6778734 , -0.73517866]]))

可分別表示爲:
在這裏插入圖片描述
上面是兩個特徵值,下面是對應的特徵向量,特徵值0.0490833989對應特徵向量爲在這裏插入圖片描述
這裏的特徵向量都歸一化爲單位向量。

特徵值與特徵向量到底代表了什麼??
雖然我係統學習了線性代數,但是印象中課本上並沒有詳細講述特徵值與特徵向量的實際意義。
首先我們回顧一下相關概念:對一個n*n的實對稱矩陣進行分解,我們能夠求出它的特徵值和特徵向量,就會產生n個n維的正交基(在特徵值不同的情況下),每一個正交基會相應一個特徵值。

然後把矩陣投影到這N個基上,此時特徵值的模就表示矩陣在該基的投影長度,也是方差的大小。

特徵值越大。說明矩陣在相應的特徵向量上的方差越大。樣本點越離散。越easy區分,信息量也就越多。因此。特徵值最大的相應的特徵向量方向上所包括的信息量就越多,假設某幾個特徵值非常小。那麼就說明在該方向的信息量非常少,我們就能夠刪除小特徵值相應方向的數據,僅僅保留大特徵值方向相應的數據,這樣做以後數據量減小。但實用的信息量都保留下來了。PCA就是這個原理。

第四,將特徵值按照從大到小的順序排序,選擇其中最大的k個,然後將其對應的k個特徵向量分別作爲列向量組成特徵向量矩陣。這裏特徵值只有兩個,我們選擇其中最大的那個.

即保留最重要的k個特徵(通常k要小於n)。也能夠自己制定。也能夠選擇一個閾值,然後通過前k個特徵值之和減去後面n-k個特徵值之和大於這個閾值,則選擇這個k。

最後進行投影,將樣本數據與特徵值相乘,即投影在選擇的較大特徵值所對應的特徵向量上。

data_n = np.hstack((x_n.reshape(1, -1).T, y_n.reshape(1, -1).T))

final_x = np.dot(data_n, max_)

final_x

結果爲:

array([[-0.82797019],
[ 1.77758033],
[-0.99219749],
[-0.27421042],
[-1.67580142],
[-0.9129491 ],
[ 0.09910944],
[ 1.14457216],
[ 0.43804614],
[ 1.22382056]])

這是投影過後的一維數據(方差最大),且k=1.如若k=2,則對於方差較小的數據投影如下:

final_y = np.dot(data_n, lamt[1][: , 0].reshape(1, -1).T)
final_y

結果如下:

array([[-0.17511531],
[ 0.14285723],
[ 0.38437499],
[ 0.13041721],
[-0.20949846],
[ 0.17528244],
[-0.3498247 ],
[ 0.04641726],
[ 0.01776463],
[-0.16267529]])

我們把這兩類數據再次畫在座標軸上。

final = np.hstack((final_x, final_y))
plt.xlim((-3, 3))
plt.ylim((-3, 3))
plt.scatter(final[: , 0], final[: , 1])

結果如下:
在這裏插入圖片描述
圖中的x軸、y軸實際上是上面計算出的兩個特徵向量!並且我們可以明顯看出投影在x軸(方差最大的特徵向量)上,數據分散程度較高,更能獲取有用信息,也就是我們所需要的主成分!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章