主成分分析(Principal Components Analysis,PCA)是一種數據降維技術,通過正交變換將一組相關性高的變量轉換為較少的彼此獨立、互不相關的變量,從而減少數據的維數。
1、數據降維
1.1 為什么要進行數據降維?
為什么要進行數據降維?降維的好處是以略低的精度換取問題的簡化。
人們在研究問題時,為了全面、准確地反映事物的特征及其發展規律,往往要考慮很多相關指標的變化和影響。尤其在數據挖掘和分析工作中,前期收集數據階段總是盡量收集能夠獲得的各種數據,能收盡收,避免遺漏。多變量、大樣本的數據為后期的研究和應用提供了豐富的信息,從不同角度反映了問題的特征和信息,但也給數據處理和分析工作帶來了很多困難。
為了避免遺漏信息需要獲取盡可能多的特征變量,但是過多的變量又加劇了問題的復雜性。由於各種變量都是對同一事物的反映,變量之間經常會存在一定的相關性,這就造成大量的信息重復、重疊,有時會淹沒甚至扭曲事物的真正特征與內在規律。因此,我們希望數據分析中涉及的變量較少,而得到的信息量又較多。這就需要通過降維方法,在減少需要分析的變量數量的同時,盡可能多的保留眾多原始變量所包含的有效信息。
變量之間具有一定的相關關系,意味着相關變量所反映的信息有一定程度的重疊,就有可能用較少的綜合指標聚合、反映眾多原始變量所包含的全部信息或主要信息。 因此,需要研究特征變量之間的相關性、相似性,以減少特征變量的數量,便於分析影響系統的主要因素。例如,對學生的評價指標有很多,作業、考勤、活動、獎懲、考試、考核,根據各種指標的關聯度和相似性,最終可以聚合為德智體美等幾個主要的類別指標反映眾多指標中大部分信息。
降維方法可以從事物之間錯綜復雜的關系中找出一些主要因素,從而能有效利用大量統計數據進行定量分析,解釋變量之間的內在關系,得到對事物特征及其發展規律的一些深層次的啟發。
歡迎關注 Youcans 原創系列,每周更新數模筆記
Python數模筆記-PuLP庫
Python數模筆記-StatsModels統計回歸
Python數模筆記-Sklearn
Python數模筆記-NetworkX
Python數模筆記-模擬退火算法
1.2 常用的降維思想和方法
降維的數學本質是將高維特征空間映射到低維特征空間,有線性映射和非線性映射兩類主要方法。
線性映射方法主要有主成分分析(PCA)和線性判別函數(LDA)。主成分分析(PCA)的思想是按均方誤差損失最小化原則,將高維原始空間變換到低維特征向量空間。線性判別函數(LDA)的思想是向線性判別超平面的法向量上投影,使得區分度最大(高內聚,低耦合) 。
非線性映射方法主要有:基於核的非線性降維, 將高維向量的內積轉換成低維的核函數表示,如核主成分分析(KPCA)、核線性判別函數(KLDA) ;二維化和張量化, 將數據映射到二維空間上,如二維主成分分析(2DPCA)、二維線性判別分析(2DLDA)、二維典型相關分析(2DCCA);流形學習方法, 從高維采樣數據中恢復低維流形結構並求出相應的嵌入映射,如等距映射 (ISOMap) , 拉普拉斯特征映射 (LE), 局部線性嵌入 (LPP)。本質上,非線性映射的思想和算法與神經網絡是相通的。
此外,還可以通過聚類分析、神經網絡方法進行數據降維。
1.3 SKlearn 中的降維分析方法
SKlearn 工具包提供了多種降維分析方法。
- 主成分分析
- decomposition.PCA 主成分分析
- decomposition.IncrementalPCA 增量主成分分析
- decomposition.KernelPCA 核主成分分析
- decomposition.SparsePCA 稀疏主成分分析
- decomposition.MiniBatchSparsePCA 小批量稀疏主成分分析
- decomposition.TruncatedSVD 截斷奇異值分解
- 字典學習
- decomposition.DictionaryLearning 字典學習
- decomposition.MiniBatchDictionaryLearning 小批量字典學習
- decomposition.dict_learning 字典學習用於矩陣分解
- decomposition.dict_learning_online 在線字典學習用於矩陣分解
- 因子分析
- decomposition.FactorAnalysis 因子分析(FA)
- 獨立成分分析
- decomposition.FastICA 快速獨立成分分析
- 非負矩陣分解
- decomposition.NMF 非負矩陣分解
- 隱式狄利克萊分布
- decomposition.LatentDirichletAllocation 在線變分貝葉斯算法(隱式狄利克萊分布)
2、主成分分析(PCA)方法
2.1 基本思想和原理
主成分分析是最基礎數據降維方法,它只需要特征值分解,就可以對數據進行壓縮、去噪,應用十分廣泛。
主成分分析的目的是減少數據集變量數量,同時要保留盡可能多的特征信息;方法是通過正交變換將原始變量組轉換為數量較少的彼此獨立的特征變量,從而減少數據集的維數。
主成分分析方法的思想是,將高維特征(n維)映射到低維空間(k維)上,新的低維特征是在原有的高維特征基礎上通過線性組合而重構的,並具有相互正交的特性,即為主成分。
通過正交變換構造彼此正交的新的特征向量,這些特征向量組成了新的特征空間。將特征向量按特征值排序后,樣本數據集中所包含的全部方差,大部分就包含在前幾個特征向量中,其后的特征向量所含的方差很小。因此,可以只保留前 k個特征向量,而忽略其它的特征向量,實現對數據特征的降維處理。
主成分分析方法得到的主成分變量具有幾個特點:(1)每個主成分變量都是原始變量的線性組合;(2)主成分的數目大大少於原始變量的數目;(3)主成分保留了原始變量的絕大多數信息;(4)各主成分變量之間彼此相互獨立。
2.2 算法步驟
主成分分析的基本步驟是:對原始數據歸一化處理后求協方差矩陣,再對協方差矩陣求特征向量和特征值;對特征向量按特征值大小排序后,依次選取特征向量,直到選擇的特征向量的方差占比滿足要求為止。
算法的基本流程如下:
- (1)歸一化處理,數據減去平均值;
- (2)通過特征值分解,計算協方差矩陣;
- (3)計算協方差矩陣的特征值和特征向量;
- (4)將特征值從大到小排序;
- (5)依次選取特征值最大的k個特征向量作為主成分,直到其累計方差貢獻率達到要求;
- (6)將原始數據映射到選取的主成分空間,得到降維后的數據。
在算法實現的過程中,SKlearn 工具包針對實際問題的特殊性,又發展了各種改進算法,例如:
- 增量主成分分析:針對大型數據集,為了解決內存限制問題,將數據分成多批,通過增量方式逐步調用主成分分析算法,最終完成整個數據集的降維。
- 核主成分分析:針對線性不可分的數據集,使用非線性的核函數把樣本空間映射到線性可分的高維空間,然后在這個高維空間進行主成分分析。
- 稀疏主成分分析:針對主成分分析結果解釋性弱的問題,通過提取最能重建數據的稀疏分量, 凸顯主成分中的主要組成部分,容易解釋哪些原始變量導致了樣本之間的差異。
2.3 優點和缺點
主成分分析方法的主要優點是:
1)僅以方差衡量信息量,不受數據集以外的因素影響;
2)各主成分之間正交,可消除原始數據各變量之間的相互影響;
3)方法簡單,易於實現。
主成分分析方法的主要缺點是:
1)各個主成分的含義具有模糊,解釋性弱,通常只有信息量而無實際含義;
2)在樣本非正態分布時得到的主成分不是最優的,因此特殊情況下方差小的成分也可能含有重要信息。
3、SKlearn 中的主成分分析(PCA) 方法
3.1 PCA 算法(decomposition.PCA)
sklearn.decomposition.PCA 類是 PCA算法的具體實現,官網介紹詳見:https://scikit-learn.org/stable/modules/decomposition.html#principal-component-analysis-pca
sklearn.decomposition.PCA(n_components=None, copy=True, whiten=False)
class sklearn.decomposition.PCA(n_components=None, *, copy=True, whiten=False, svd_solver='auto', tol=0.0, iterated_power='auto', random_state=None)
PCA 類的主要參數:
- n_components: int,float n 為正整數,指保留主成分的維數;n 為 (0,1] 范圍的實數時,表示主成分的方差和所占的最小閾值。
- whiten:bool, default=False 是否對降維后的主成分變量進行歸一化。默認值 False。
- svd_solver:{‘auto’, ‘full’, ‘arpack’, ‘randomized’} 指定奇異值分解SVD的算法。'full' 調用 scipy庫的 SVD;'arpack'調用scipy庫的 sparse SVD;'randomized' SKlearn的SVD,適用於數據量大、變量維度多、主成分維數低的場景。默認值 'auto'。
=== 關注 Youcans,分享更多原創系列 https://www.cnblogs.com/youcans/ ===
PCA 類的主要屬性:
- components_: 方差最大的 n-components 個主成分
- explained_variance_: 各個主成分的方差值
- explained_variance_ratio_: 各個主成分的方差值占主成分方差和的比例
PCA 類的主要方法:
- fit(X,y=None) 表示用數據 X 訓練PCA模型
fit() 是scikit-learn中的通用方法,實現訓練、擬合的步驟。PCA是無監督學習,y=None。 - fit_transform(X) 表示用數據 X 訓練PCA模型,並返回降維后的數據
- transform(X) 將數據 X 轉換成降維后的數據,用訓練好的 PCA模型對新的數據集進行降維。
- inverse_transform() 將降維后的數據轉換成原始數據
3.2 decomposition.PCA 使用例程
from sklearn.decomposition import PCA # 導入 sklearn.decomposition.PCA 類
import numpy as np # Youcans, XUPT
X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
modelPCA = PCA(n_components=2) # 建立模型,設定保留主成分數 K=2
modelPCA.fit(X) # 用數據集 X 訓練 模型 modelPCA
print(modelPCA.n_components_) # 返回 PCA 模型保留的主成份個數
# 2
print(modelPCA.explained_variance_ratio_) # 返回 PCA 模型各主成份占比
# [0.9924 0.0075] # print 顯示結果
print(modelPCA.singular_values_) # 返回 PCA 模型各主成份的奇異值
# [6.3006 0.5498] # print 顯示分類結果
X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
modelPCA2 = PCA(n_components=0.9) # 建立模型,設定主成份方差占比 0.9
# 用數據集 X 訓練 模型 modelPCA2,並返回降維后的數據
Xtrans = modelPCA2.fit_transform(X)
# === 關注 Youcans,分享更多原創系列 https://www.cnblogs.com/youcans/ ===
print(modelPCA2.n_components_) # 返回 PCA 模型保留的主成份個數
# 1
print(modelPCA2.explained_variance_ratio_) # 返回 PCA 模型各主成份占比
# [0.9924] # print(Youcans) 顯示結果
print(modelPCA2.singular_values_) # 返回 PCA 模型各主成份占比
# [6.3006] # print 顯示結果
print(Xtrans) # 返回降維后的數據 Xtrans
# [[1.3834], [2.2219], [3.6053], [-1.3834], [-2.2219], [-3.6053]]
注意:建立模型時,PCA(n_components=2) 中的 n_components為正整數,表示設定保留的主成份維數為 2;PCA(n_components=0.9) 中的 n_components 為 (0,1] 的小數,表示並不直接設定保留的主成份維數,而是設定保留的主成份應滿足其方差和占比 >0.9。
3.3 改進算法:增量主成分分析(decomposition.IncrementalPCA)
對於樣本集巨大的問題,例如樣本量大於 10萬、特征變量大於100,PCA 算法耗費的內存很大,甚至無法處理。
class sklearn.decomposition.IncrementalPCA 類是增量主成分分析算法的具體實現,官網介紹詳見:https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.IncrementalPCA.html#sklearn.decomposit
class sklearn.decomposition.IncrementalPCA(n_components=None, *, whiten=False, copy=True, batch_size=None)
主要參數:
inverse_transform() 將降維后的數據轉換成原始數據
IncrementalPCA 的使用例程如下:
# Demo of sklearn.decomposition.IncrementalPCA
from sklearn.datasets import load_digits
from sklearn.decomposition import IncrementalPCA, PCA
from scipy import sparse # Youcans, XUPT
X, _ = load_digits(return_X_y=True)
print(type(X)) # <class 'numpy.ndarray'>
print(X.shape) # (1797, 64)
modelPCA = PCA(n_components=6) # 建立模型,設定保留主成分數 K=6
modelPCA.fit(X) # 用數據集 X 訓練 模型 modelPCA
print(modelPCA.n_components_) # 返回 PCA 模型保留的主成份個數
# 6
print(modelPCA.explained_variance_ratio_) # 返回 PCA 模型各主成份占比
# [0.1489 0.1362 0.1179 0.0841 0.0578 0.0492]
print(sum(modelPCA.explained_variance_ratio_)) # 返回 PCA 模型各主成份占比
# 0.5941
print(modelPCA.singular_values_) # 返回 PCA 模型各主成份的奇異值
# [567.0066 542.2518 504.6306 426.1177 353.3350 325.8204]
# let the fit function itself divide the data into batches
Xsparse = sparse.csr_matrix(X) # 壓縮稀疏矩陣,並非 IPCA 的必要步驟
print(type(Xsparse)) # <class 'scipy.sparse.csr.csr_matrix'>
print(Xsparse.shape) # (1797, 64)
modelIPCA = IncrementalPCA(n_components=6, batch_size=200)
modelIPCA.fit(Xsparse) # 訓練模型 modelIPCA
# === 關注 Youcans,分享更多原創系列 https://www.cnblogs.com/youcans/ ===
print(modelIPCA.n_components_) # 返回 PCA 模型保留的主成份個數
# 6
print(modelIPCA.explained_variance_ratio_) # 返回 PCA 模型各主成份占比
# [0.1486 0.1357 0.1176 0.0838 0.0571 0.0409]
print(sum(modelIPCA.explained_variance_ratio_)) # 返回 PCA 模型各主成份占比
# 0.5838
print(modelIPCA.singular_values_) # 返回 PCA 模型各主成份的奇異值
#[566.4544 541.334 504.0643 425.3197 351.1096 297.0412]
本例程調用了 SKlearn內置的數據集 .datasets.load_digits,並給出了 PCA 算法與 IPCA 算法的對比,兩種算法的結果非常接近,說明 IPCA 的性能降低很小。
3.4 改進算法:核主成分分析(decomposition.KernelPCA)
對於線性不可分的數據集,使用非線性的核函數可以把樣本空間映射到線性可分的高維空間,然后在這個高維空間進行主成分分析。
class sklearn.decomposition.KernelPCA 類是算法的具體實現,官網介紹詳見:https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.KernelPCA.html#sklearn.decomposition.KernelPCA
class sklearn.decomposition.KernelPCA(n_components=None, *, kernel='linear', gamma=None, degree=3, coef0=1, kernel_params=None, alpha=1.0, fit_inverse_transform=False, eigen_solver='auto', tol=0, max_iter=None, remove_zero_eig=False, random_state=None, copy_X=True, n_jobs=None)
KernelPCA 的使用例程如下:
# Demo of sklearn.decomposition.KernelPCA
from sklearn.datasets import load_iris
from sklearn.decomposition import KernelPCA, PCA
import matplotlib.pyplot as plt
import numpy as np # Youcans, XUPT
X, y = load_iris(return_X_y=True)
print(type(X)) # <class 'numpy.ndarray'>
modelPCA = PCA(n_components=2) # 建立模型,設定保留主成分數 K=2
Xpca = modelPCA.fit_transform(X) # 用數據集 X 訓練 模型 modelKPCA
modelKpcaP = KernelPCA(n_components=2, kernel='poly') # 建立模型,核函數:多項式
XkpcaP = modelKpcaP.fit_transform(X) # 用數據集 X 訓練 模型 modelKPCA
modelKpcaR = KernelPCA(n_components=2, kernel='rbf') # 建立模型,核函數:徑向基函數
XkpcaR = modelKpcaR.fit_transform(X) # 用數據集 X 訓練 模型 modelKPCA
modelKpcaS = KernelPCA(n_components=2, kernel='cosine') # 建立模型,核函數:余弦函數
XkpcaS = modelKpcaS.fit_transform(X) # 用數據集 X 訓練 模型 modelKPCA
# === 關注 Youcans,分享更多原創系列 https://www.cnblogs.com/youcans/ ===
fig = plt.figure(figsize=(8,6))
ax1 = fig.add_subplot(2,2,1)
ax2 = fig.add_subplot(2,2,2)
ax3 = fig.add_subplot(2,2,3)
ax4 = fig.add_subplot(2,2,4)
for label in np.unique(y):
position = y == label
ax1.scatter(Xpca[position, 0], Xpca[position, 1], label='target=%d' % label)
ax1.set_title('PCA')
ax2.scatter(XkpcaP[position, 0], XkpcaP[position, 1], label='target=%d' % label)
ax2.set_title('kernel= Poly')
ax3.scatter(XkpcaR[position, 0], XkpcaR[position, 1], label='target=%d' % label)
ax3.set_title('kernel= Rbf')
ax4.scatter(XkpcaS[position, 0], XkpcaS[position, 1], label='target=%d' % label)
ax4.set_title('kernel= Cosine')
plt.suptitle("KernalPCA(Youcans,XUPT)")
plt.show()
本例程調用了 SKlearn內置的數據集 .datasets.load_iris,並給出了 PCA 算法與 3種核函數的KernelPCA 算法的對比,結果如下圖所示。不同算法的降維后映射到二維平面的結果有差異,進一步的討論已經超出本文的內容。
版權說明:
本文內容及例程為作者原創,並非轉載書籍或網絡內容。
本文中案例問題來自: SciKit-learn 官網:https://scikit-learn.org/stable/index.html
YouCans 原創作品
Copyright 2021 YouCans, XUPT
Crated:2021-05-10
歡迎關注 Youcans 原創系列,每周更新數模筆記
Python數模筆記-PuLP庫(1)線性規划入門
Python數模筆記-PuLP庫(2)線性規划進階
Python數模筆記-PuLP庫(3)線性規划實例
Python數模筆記-Scipy庫(1)線性規划問題
Python數模筆記-StatsModels 統計回歸(1)簡介
Python數模筆記-StatsModels 統計回歸(2)線性回歸
Python數模筆記-StatsModels 統計回歸(3)模型數據的准備
Python數模筆記-StatsModels 統計回歸(4)可視化
Python數模筆記-Sklearn (1)介紹
Python數模筆記-Sklearn (2)聚類分析
Python數模筆記-Sklearn (3)主成分分析
Python數模筆記-Sklearn (4)線性回歸
Python數模筆記-Sklearn (5)支持向量機
Python數模筆記-NetworkX(1)圖的操作
Python數模筆記-NetworkX(2)最短路徑
Python數模筆記-NetworkX(3)條件最短路徑
Python數模筆記-模擬退火算法(1)多變量函數優化
Python數模筆記-模擬退火算法(2)約束條件的處理
Python數模筆記-模擬退火算法(3)整數規划問題
Python數模筆記-模擬退火算法(4)旅行商問題