網(wǎng)站首頁 編程語言 正文
前言
????????PCA降維,一般是用于數(shù)據(jù)分析和機(jī)器學(xué)習(xí)。它的作用是把一個高維的數(shù)據(jù)在保留最大信息量的前提下降低到一個低維的空間,從而使我們能夠提取數(shù)據(jù)的主要特征分量,從而得到對數(shù)據(jù)影響最大的主成分,便于我們對數(shù)據(jù)進(jìn)行分析等后續(xù)操作。
????????例如,在機(jī)器學(xué)習(xí)中,當(dāng)你想跟據(jù)一個數(shù)據(jù)集來進(jìn)行預(yù)測工作時,往往要采用特征構(gòu)建、不同特征相乘、相加等操作,來擴(kuò)建特征,所以,當(dāng)數(shù)據(jù)處理完畢后,每個樣本往往會有很多個特征,但是,如果把所有數(shù)據(jù)全部喂入模型,可能會導(dǎo)致糟糕的結(jié)果。在高維數(shù)據(jù)集中,往往只有部分特征有良好的預(yù)測能力,很多特征純粹是噪音(沒有預(yù)測能力),很多特征彼此之間也可能高度相關(guān),這些因素會降低模型的預(yù)測精度,訓(xùn)練模型的時間也更長。降低數(shù)據(jù)集的維度在某種程度上能解決這些問題,這時候就用到了PCA降維。
? ? ? ? 假設(shè)原始數(shù)據(jù)集的特征有500個,通過PCA降維,降到了400,那么我們就可以用降維后得到的這400個特征代替原始數(shù)據(jù)集的那500個,此時再喂給模型,那么模型的預(yù)測能力相比之前會有所提升。但要明白一點的是,降維后得到的這400個特征是新的特征,是原始數(shù)據(jù)集在高維空間某一平面上的投影,能夠反映原特征提供的大部分信息,并不是指在原來的500個中篩選400個特征。
PCA降維的一般步驟為:
1.將原始數(shù)據(jù)進(jìn)行標(biāo)準(zhǔn)化(一般是去均值,如果特征在不同的數(shù)量級上,則還要將其除以標(biāo)準(zhǔn)差)
2.計算標(biāo)準(zhǔn)化數(shù)據(jù)集的協(xié)方差矩陣
3.計算協(xié)方差矩陣的特征值和特征向量
4.保留最重要(特征值最大)的前k個特征(k就表示降維后的維度)
5.找到這k個特征值對應(yīng)的特征向量
6.將標(biāo)準(zhǔn)化數(shù)據(jù)集乘以該k個特征向量,得到降維后的結(jié)果
實現(xiàn)PCA降維,一般有兩種方法:
首先先來解釋一下代碼中用到的數(shù)據(jù)集:
????????在這兩個代碼中,用的是sklean庫中自帶的iris(鳶尾花)數(shù)據(jù)集。iris數(shù)據(jù)集包含150個樣本,每個樣本包含四個屬性特征(花萼長度、花萼寬度、花瓣長度、花瓣寬度)和一個類別標(biāo)簽(分別用0、1、2表示山鳶尾、變色鳶尾和維吉尼亞鳶尾)。
data = load_iris() y = data.target x = data.data
y就表示數(shù)據(jù)集中的類別標(biāo)簽,x表示數(shù)據(jù)集中的屬性數(shù)據(jù)。因為鳶尾花類別分為三類,所以我們降維后,要跟據(jù)y的值,分別對這三類數(shù)據(jù)點進(jìn)行繪圖。
第一種,就是依照上面PCA的步驟,通過矩陣運(yùn)算,最終得到降維后的結(jié)果:
import numpy as np from sklearn.datasets import load_iris import matplotlib.pyplot as plt def pca(dataMat, topNfeat): meanVals = np.mean(dataMat, axis=0) meanRemoved = dataMat - meanVals # 標(biāo)準(zhǔn)化(去均值) covMat = np.cov(meanRemoved, rowvar=False) eigVals, eigVets = np.linalg.eig(np.mat(covMat)) # 計算矩陣的特征值和特征向量 eigValInd = np.argsort(eigVals) # 將特征值從小到大排序,返回的是特征值對應(yīng)的數(shù)組里的下標(biāo) eigValInd = eigValInd[:-(topNfeat + 1):-1] # 保留最大的前K個特征值 redEigVects = eigVets[:, eigValInd] # 對應(yīng)的特征向量 lowDDatMat = meanRemoved * redEigVects # 將數(shù)據(jù)轉(zhuǎn)換到低維新空間 # reconMat = (lowDDatMat * redEigVects.T) + meanVals # 還原原始數(shù)據(jù) return lowDDatMat def plotPCA(lowMat): reconArr = np.array(lowMat) red_x, red_y = [], [] blue_x, blue_y = [], [] green_x, green_y = [], [] for i in range(len(reconArr)): if y[i] == 0: red_x.append(reconArr[i][0]) red_y.append(reconArr[i][1]) elif y[i] == 1: blue_x.append(reconArr[i][0]) blue_y.append(reconArr[i][1]) else: green_x.append(reconArr[i][0]) green_y.append(reconArr[i][1]) plt.scatter(red_x, red_y, c='r', marker='x') plt.scatter(blue_x, blue_y, c='b', marker='D') plt.scatter(green_x, green_y, c='g', marker='.') plt.show() if __name__ == '__main__': data = load_iris() y = data.target x = data.data matx = np.mat(x) lowDMat = pca(matx, 2) plotPCA(lowDMat)
第二種,是在sklearn庫中調(diào)用PCA算法來實現(xiàn):
import matplotlib.pyplot as plt from sklearn.decomposition import PCA # 加載PCA算法包 from sklearn.datasets import load_iris import numpy as np data = load_iris() y = data.target x = data.data pca = PCA(n_components=2) # 加載PCA算法,設(shè)置降維后主成分?jǐn)?shù)目為2 reduced_x = pca.fit_transform(x) # 對樣本進(jìn)行降維 # reduced_x = np.dot(reduced_x, pca.components_) + pca.mean_ # 還原數(shù)據(jù) red_x, red_y = [], [] blue_x, blue_y = [], [] green_x, green_y = [], [] # print(reduced_x) for i in range(len(reduced_x)): if y[i] == 0: red_x.append(reduced_x[i][0]) red_y.append(reduced_x[i][1]) elif y[i] == 1: blue_x.append(reduced_x[i][0]) blue_y.append(reduced_x[i][1]) else: green_x.append(reduced_x[i][0]) green_y.append(reduced_x[i][1]) plt.scatter(red_x, red_y, c='r', marker='x') plt.scatter(blue_x, blue_y, c='b', marker='D') plt.scatter(green_x, green_y, c='g', marker='.') plt.show()
????????在第二個代碼中,值得一說的是fit_transform()這個函數(shù),它其實就是fit()和transform()這兩個函數(shù)的結(jié)合,相當(dāng)于先調(diào)用fit()再調(diào)用transform()。fit()和transform()這兩個函數(shù)在sklearn庫中經(jīng)常出現(xiàn),fit()函數(shù)可以理解為求傳入的數(shù)據(jù)集的一些固有的屬性(如方差、均值等等),相當(dāng)于一個訓(xùn)練過程,而transform()函數(shù),可以理解為對訓(xùn)練后的數(shù)據(jù)集進(jìn)行相應(yīng)的操作(如歸一化、降維等等)。在不同的模塊中,這兩個函數(shù)的具體實現(xiàn)也不一樣,比如在PCA模塊里,fit()相當(dāng)于去均值,transform()則相當(dāng)于降維。
這兩種代碼運(yùn)行后,生成的圖像如下(圖一為第一種代碼,圖二為第二種代碼):
圖一
圖二
????????可以看到,第一種代碼畫出的圖像與第二種代碼畫出的圖像關(guān)于y=0這條直線對稱,雖然不清楚這是什么原因(后續(xù)有空的話我會去找找原因),但是這并不影響降維的結(jié)果。
降維前的數(shù)據(jù)(部分):? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
降維后的數(shù)據(jù)(部分):
????????所以,此時我們使用降維后的二維數(shù)據(jù)集就可以用來表示降維前四維數(shù)據(jù)集的大部分信息。
? ? ? ? 降維后得到的數(shù)據(jù)可以通過逆操作來進(jìn)行數(shù)據(jù)集的還原,具體原理就不過多解釋,具體操作代碼的話我已在代碼的注釋里面寫出,但是重建出來的數(shù)據(jù)會和原始數(shù)據(jù)有一定的誤差(如下圖)
????????原因的話你可以這樣理解:我們的原始數(shù)據(jù)為四維空間,現(xiàn)在用PCA降維到二維空間,則保留數(shù)據(jù)投影方差最大的兩個軸向,因此舍棄掉了另外兩個相對不重要的特征軸,從而造成了一定的信息丟失,所以會產(chǎn)生重構(gòu)誤差。
總結(jié)
原文鏈接:https://blog.csdn.net/qq_48958559/article/details/122449213
相關(guān)推薦
- 2024-03-03 layui彈窗編輯表單清空
- 2022-07-10 css盒子塌陷及其解決方法
- 2022-04-01 k8s 1.22 安裝ingress報錯the server could not find the
- 2022-07-09 python?監(jiān)控某個進(jìn)程內(nèi)存的情況問題_python
- 2022-03-18 linux下修改文件權(quán)限chmod命令詳細(xì)解析_Linux
- 2023-11-20 Linux、jetson nano、JTX、英偉達(dá)、nVidia查看cuda版本
- 2022-03-19 CentOS7下安裝MongoDB數(shù)據(jù)庫過程_MongoDB
- 2022-09-03 React實現(xiàn)輪播圖效果_React
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支