PCA降維算法

PCA主成分分析算法,是一種線性降維,將高維座標系映射到低維座標系中。算法

如何選擇低維座標系呢?數組

經過協方差矩陣的特徵值和特徵向量,特徵向量表明座標系,特徵值表明映射到新座標的長度。spa

算法步驟:

輸入:樣本集D={x1,x2,...,xm};code

   低維空間維數korm

第一步:將樣本集中心化。每一列的特徵值減去當前列的均值
blog

第二步:求協方差矩陣的特徵值特徵向量排序

    協方差矩陣:矩陣×矩陣的轉置;索引

      方法:np.dot(x, np.transpot(x))class

    特徵值和特徵向量:協方差矩陣特徵分解。import

      方法一:np.linalg.eig()返回:特徵值,一維數組,沒有排序;特徵向量,二維數組,列表示特徵向量

      方法二:np.linalg.svd(),返回:酉矩陣;奇異值,從大到小排序;酉矩陣

第三步:選取前k個特徵值,對應的特徵向量

    新樣本集:對應的特徵向量×中心化數據

輸出:降維後樣本集。

k選擇問題:

  方差貢獻率:特徵值與全部特徵值總和的比值

  累計貢獻率:前k個特徵值和與全部特徵值總和的比值

  通常根據累計貢獻率選取k值。

代碼以下:

 1 import numpy as np
 2 
 3 
 4 def feature_Normalize(x):
 5     """
 6     歸一化數據
 7     (每一個數據-當前列的均值)/當前列的標準差
 8     :param x: 樣本集
 9     :return: 歸一化後樣本集,均值,標準差
10     """
11     m, n = x.shape
12     mean = np.zeros((1, n))
13     std = np.zeros((1, n))
14     # 計算各列均值
15     mean = np.mean(x, axis=0)
16     # 計算各列標準差
17     std = np.std(x, axis=0)
18     # 對每一個特徵值歸一化
19     for i in range(n):
20             x[:, i] = (x[:, i] - mean[i]) / std[i]
21     return x, mean, std
22 
23 
24 def cal_eigenvalue(nor_x):
25     """
26     求樣本協方差矩陣的特徵值和特徵向量
27     :param nor_x: 歸一化後的樣本集
28     :return: 特徵值,特徵向量,排序索引號
29     """
30     m, n = nor_x.shape
31     # 協方差矩陣
32     sigma = np.dot(np.transpose(nor_x), nor_x)/(m - 1)
33     # 求協方差矩陣的特徵值和特徵向量,eig_vec[:,i]是對應於eig_val[i]的特徵向量
34     eig_val, eig_vec = np.linalg.eig(sigma)
35     index = eig_val.argsort()
36     return eig_val, eig_vec, index
37 
38 
39 def pca(x, k):
40     """
41     提取前k個主成分
42     :param x: 樣本集
43     :param k: 前k個特徵值
44     :return: 返回降維後樣本,累計貢獻度,主成分索引
45     """
46     # 歸一化
47     nor_x, mean, std = feature_Normalize(x)
48     # 求特徵值和特徵向量
49     eig_val, eig_vec, index = cal_eigenvalue(nor_x)
50     eig_index = index[:-(k+1):-1]
51     # 累計貢獻度
52     sum_con = sum(eig_val[eig_index])/sum(eig_val)
53     # 前k個特徵值對應的特徵向量
54     k_eig_vec = eig_vec[:, eig_index]
55     lowDData = np.dot(nor_x, k_eig_vec)
56     return lowDData, sum_con, eig_index
相關文章
相關標籤/搜索