主成分分析(
principal component analysis
,pca
),是一種統計方法。通過正交變換將一組可能存在相關性的變數轉換為一組線性不相關的變數,轉換後的這組變數叫主成分。
在實際課題中,為了全面分析問題,往往提出很多與此有關的變數(或因素),因為每個變數都在不同程度上反映這個課題的某些資訊。
主成分分析首先是由
k.皮爾森(
karl pearson
)對非隨機變數引入的,爾後
h.霍特林將此方法推廣到隨機向量的情形。資訊的大小通常用離差平方和或方差來衡量。
# -*- coding: utf-8 -*-
import numpy as np
from matplotlib import pyplot as plt
from scipy import io as spio
from sklearn.decomposition import pca
'''主成分分析_2維資料降維1維演示函式
'''def pca_2d():
data_2d = spio.loadmat("data.mat")
x = data_2d['x']
m = x.shape[0]
plt = plot_data_2d(x, 'bo') # 顯示二維的資料
plt.show()
x_copy = x.copy()
x_norm, mu, sigma = featurenormalize(x_copy) # 歸一化資料
# plot_data_2d(x_norm) # 顯示歸一化後的資料
# plt.show()
sigma = np.dot(np.transpose(x_norm), x_norm) / m # 求sigma
u, s, v = np.linalg.svd(sigma) # 求sigma的奇異值分解
plt = plot_data_2d(x, 'bo') # 顯示原本資料
drawline(plt, mu, mu + s[0] * (u[:, 0]), 'r-') # 線,為投影的方向
plt.axis('square')
plt.show()
k = 1 # 定義降維多少維(本來是2維的,這裡降維1維)
'''投影之後資料(降維之後)'''
z = projectdata(x_norm, u, k) # 投影
'''恢復資料'''
x_rec = recoverdata(z, u, k) # 恢復
'''作圖-----原資料與恢復的資料'''
plt = plot_data_2d(x_norm, 'bo')
plot_data_2d(x_rec, 'ro')
for i in range(x_norm.shape[0]):
drawline(plt, x_norm[i, :], x_rec[i, :], '--k')
plt.axis('square')
plt.show()
'''主成分分析_pca影象資料降維'''
def pca_faceimage():
print(u'載入影象資料.....')
data_image = spio.loadmat('data_faces.mat')
x = data_image['x']
display_imagedata(x[0:100, :])
m = x.shape[0] # 資料條數
print(u'執行pca....')
x_norm, mu, sigma = featurenormalize(x) # 歸一化
sigma = np.dot(np.transpose(x_norm), x_norm) / m # 求sigma
u, s, v = np.linalg.svd(sigma) # 奇異值分解
display_imagedata(np.transpose(u[:, 0:36])) # 顯示u的資料
print(u'對face資料降維.....')
k = 100 # 降維100維(原先是32*32=1024維的)
z = projectdata(x_norm, u, k)
print(u'投影之後z向量的大小:%d %d' % z.shape)
print(u'顯示降維之後的資料......')
x_rec = recoverdata(z, u, k) # 恢復資料
display_imagedata(x_rec[0:100, :])
# 視覺化二維資料
def plot_data_2d(x, marker):
plt.plot(x[:, 0], x[:, 1], marker)
return plt
# 歸一化資料
def featurenormalize(x):
'''(每乙個資料-當前列的均值)/當前列的標準差'''
n = x.shape[1]
mu = np.zeros((1, n));
sigma = np.zeros((1, n))
mu = np.mean(x, axis=0) # axis=0表示列
sigma = np.std(x, axis=0)
for i in range(n):
x[:, i] = (x[:, i] - mu[i]) / sigma[i]
return x, mu, sigma
# 對映資料
def projectdata(x_norm, u, k):
z = np.zeros((x_norm.shape[0], k))
u_reduce = u[:, 0:k] # 取前k個
z = np.dot(x_norm, u_reduce)
return z
# 畫一條線
def drawline(plt, p1, p2, line_type):
plt.plot(np.array([p1[0], p2[0]]), np.array([p1[1], p2[1]]), line_type)
# 恢復資料
def recoverdata(z, u, k):
x_rec = np.zeros((z.shape[0], u.shape[0]))
u_recude = u[:, 0:k]
x_rec = np.dot(z, np.transpose(u_recude)) # 還原資料(近似)
return x_rec
# 顯示
def display_imagedata(imgdata):
sum = 0
'''顯示100個數(若是乙個乙個繪製將會非常慢,可以將要畫的整理好,放到乙個矩陣中,顯示這個矩陣即可)
- 初始化乙個二維陣列
- 將每行的資料調整成影象的矩陣,放進二維陣列
- 顯示即可
'''m, n = imgdata.shape
width = np.int32(np.round(np.sqrt(n)))
height = np.int32(n / width);
rows_count = np.int32(np.floor(np.sqrt(m)))
cols_count = np.int32(np.ceil(m / rows_count))
pad = 1
display_array = -np.ones((pad + rows_count * (height + pad), pad + cols_count * (width + pad)))
for i in range(rows_count):
for j in range(cols_count):
max_val = np.max(np.abs(imgdata[sum, :]))
display_array[pad + i * (height + pad):pad + i * (height + pad) + height,
pad + j * (width + pad):pad + j * (width + pad) + width] = imgdata[sum, :].reshape(height, width,
order="f") / max_val # order=f指定以列優先,在matlab中是這樣的,python中需要指定,預設以行
sum += 1
plt.imshow(display_array, cmap='gray') # 顯示灰度影象
plt.axis('off')
plt.show()
if __name__ == "__main__":
pca_2d()
pca_faceimage()
PCA主成分分析(降維)
opencv中使用 實現降維分類預處理 參考 降維 我的理解是,通過降維得到基本特徵可以加快學習演算法。並且由於降維後的資料本身就是正交的,和聚類一樣可以實現分類 識別問題。在自我學習中也可以採用大量無標註的影象,對這些影象降維分類,並結合部分編碼資料得到特徵。例如 將很2500張人臉資訊,通過25...
降維 PCA 主成分分析
其實早該整理一下pca了,怎奈一直沒有時間,可能是自己對時間沒有把握好吧,下面進入正題。所謂降維,就是降低資料的維數。在機器學習中尤其常見,之前做過對一幅提取小波特徵,對於一幅大小為800 600的,如果每個點提取五個尺度 八個方向的特徵,那麼每乙個畫素點提取40個特徵,那麼一副的話就是40 800...
資料降維 主成分分析(PCA)
主成分分析 pca 是一種比較經典的降維方法,它的思想主要是將資料對映到低維空間時使得資料在低維空間的方差最大。演算法如下 python 如下,我主要使用了兩種方法特徵值分解和奇異值分解。import numpy as np import matplotlib.pyplot as plt from ...