PCA(主成分分析法)的理解笔记及算法的实现
前幾天搞定了Open3d庫問題后,準(zhǔn)備手撕PCA算法突然人麻了。我堅(jiān)信學(xué)習(xí)是不斷重復(fù)的過程,特此做個(gè)筆記,歡迎大家評(píng)論和交流!
感謝大佬的文章:
1、主成分分析(PCA)原理詳解_Microstrong-CSDN博客_pca
2、CodingLabs - PCA的數(shù)學(xué)原理
3、(48條消息) 主成分分析PCA以及特征值和特征向量的意義_Mr.horse的博客-CSDN博客??????
4、(46條消息) 三維點(diǎn)云:PCA(下)open3d_eurus_的博客-CSDN博客?
--------------------------------------------------------分割線----------------------------------------------------------------
PCA 是有損的數(shù)據(jù)壓縮方式,它常用于對(duì)高維數(shù)據(jù)進(jìn)行降維,也就是把高維數(shù)據(jù)投影到方差大的幾個(gè)主方向上,方便數(shù)據(jù)分析,方差越大,保留的信息也就越多這個(gè)也就是思想的核心
協(xié)方差矩陣:
1、為什么會(huì)推出這個(gè)形式的協(xié)方差矩陣呢?
答:是將協(xié)方差和方差統(tǒng)一到一個(gè)矩陣中,便于算法的實(shí)現(xiàn)。主對(duì)角線為方差,兩邊為協(xié)方差,且是個(gè)實(shí)對(duì)稱矩陣。
2、方差的作用
答:公式
在PCA中往往都會(huì)先將樣本歸一化就是
所以整個(gè)均值就為0了,那么公式就可以表達(dá)為:
目的是為了在對(duì)應(yīng)維度上的信息盡可能分散,無重合點(diǎn),就是找方差最大。
3、協(xié)方差(這是協(xié)方差不是協(xié)方差矩陣,注意區(qū)分!)
答:對(duì)于高維來說,單一找方差最大的可能會(huì)找到一樣的方向,這個(gè)時(shí)候就需要協(xié)方差起到約束作用,使得多方向線性無關(guān)最好正交。?不相關(guān)??對(duì)于多維來說不相關(guān)就是獨(dú)立。
那么就是對(duì)協(xié)方差矩陣C對(duì)角化,只有對(duì)角化Cov(x,y)=0,使基不獨(dú)立互不干擾互不影響。
-----------------------------------------------------對(duì)C相似對(duì)角化--------------------------------------------------------
令,對(duì)于n階矩陣存在可逆矩陣P使得,又因?yàn)閅是實(shí)對(duì)稱矩陣性質(zhì)更好,不僅一定存在這樣的P而且不同特征值對(duì)應(yīng)的特征向量一定正交。
1、接下來對(duì)P進(jìn)行單位化,為什么呢?
答:便于計(jì)算吧,對(duì)于A·B=|A||B|cos(a)當(dāng)|B|=1時(shí)就是A在B上的投影,我們的坐標(biāo)軸上的i,j(也可以叫做基會(huì)好理解點(diǎn))都會(huì)默認(rèn)為單位向量。打個(gè)比方向量b(3,5)其實(shí)x分量是投影到i軸上的長(zhǎng)度為3,y分量是投影到j(luò)軸上的長(zhǎng)度為5,如果i,j不是單位基的話你還要除以i,j的模才是b在這個(gè)基坐標(biāo)下的坐標(biāo)。
2、為什么特征值要從大到小排?
答:特征值可以簡(jiǎn)單理解為對(duì)應(yīng)特征向量在總體所占的比重。PCA也可以從特征值理解特征值越小說明他的重要程度越小,我們?cè)娇梢院雎运闹匾?#xff0c;不就可以達(dá)到PCA的思想核心了嘛,從N維把不重要的維度去掉降到K維(N<K)
----------------------------------------------------------PCA步驟----------------------------------------------------------
總結(jié)一下PCA的算法步驟:
設(shè)有m條n維數(shù)據(jù)。
1)將原始數(shù)據(jù)按列組成n行m列矩陣X
2)將X的每一行(代表一個(gè)屬性字段)進(jìn)行零均值化,即減去這一行的均值
3)求出協(xié)方差矩陣
4)求出協(xié)方差矩陣的特征值及對(duì)應(yīng)的特征向量(向量還要單位化)
5)將特征向量按對(duì)應(yīng)特征值大小從上到下按行排列成矩陣,取前k行組成矩陣P
6)Y=PX即為降維到k維后的數(shù)據(jù)
P其實(shí)就是變換矩陣,X在這組基下能找到信息量最大的方向,特征值對(duì)于變換后坐標(biāo)對(duì)應(yīng)維度的方差。幾何意義是沒有旋轉(zhuǎn)只對(duì)向量拉伸或者縮短多少倍,就是特征值。打個(gè)比方三維降到二維,數(shù)據(jù)點(diǎn)投影到這個(gè)主成分軸上越多說明越大,這個(gè)軸拉伸倍?。
------------------------------------------------算法的實(shí)現(xiàn)------------------------------------------------------------------
# 功能:計(jì)算PCA的函數(shù) # 輸入: # data:點(diǎn)云,NX3的矩陣 # correlation:區(qū)分np的cov和corrcoef,不輸入時(shí)默認(rèn)為False # sort: 特征值排序,排序是為了其他功能方便使用,不輸入時(shí)默認(rèn)為True # 輸出: # eigenvalues:特征值 # eigenvectors:特征向量 def PCA(data, correlation=False, sort=True)mean = np.array([np.mean(data[:, i]) for i in range(data.shape[1])])#對(duì)每一列求均值#print("mean:" , mean)x = data-mean #歸一化#print("normal:", x)#print("shape:", x.shape)c = np.dot(np.transpose(x),x)/5 #我這里是行和列是反的,所以轉(zhuǎn)置在前,不過我們一般都習(xí)慣把樣本按行特征按列存儲(chǔ)print("C:", c)#協(xié)方差矩陣eigenvalues,eigenvectors=np.linalg.eig(c) #解出特征值特征向量,注意返回的是歸一化后的特征向量print("eigenvalues:" ,eigenvalues)#特征值print("eigenvectors",eigenvectors)#特征向量#sum=np.array([np.sum(pow(eigenvectors[:,i],2)) for i in range(data.shape[1])])#mo=np.array([np.sqrt(sum[i]) for i in range(data.shape[1])])#print("sum",sum)#print("mo", mo)#singlevector=eigenvectors/mo#print("singlevector", singlevector)Y=np.dot(data,eigenvectors[1])#這里也是py里面的矩陣和我們習(xí)慣的要轉(zhuǎn)置的print("Y",Y)#變換后的對(duì)應(yīng)主成分向量上的投影值#eigenvectors=singlevector#if sort:#sort = eigenvalues.argsort()[::-1]#降序排序#eigenvalues = eigenvalues[sort]#這里面0是最大的#eigenvectors = eigenvectors[:, sort]#print("eigenvalues:",eigenvalues)#print("eigenvectors:", eigenvectors)#return eigenvalues, eigenvectorsif __name__ == '__main__':#測(cè)試X = np.array([[-1, -2], [-1, 0], [0, 0], [2, 1], [0, 1]])PCA(X)#三維點(diǎn)云計(jì)算及畫出主成分向量#w, v = PCA(points)#自己三維點(diǎn)云數(shù)據(jù)傳進(jìn)來#point_cloud_vector1 = v[:, 0] #點(diǎn)云主方向?qū)?yīng)的向量#point_cloud_vector2 = v[:, 1]#print('the main orientation of this pointcloud is: ', point_cloud_vector1)#print('the main orientation of this pointcloud is: ', point_cloud_vector2)# 在原點(diǎn)云中畫圖#point = [[0, 0, 0], point_cloud_vector1*100, point_cloud_vector2*100] # 畫點(diǎn):原點(diǎn)、第一主成分、第二主成分#lines = [[0, 1], [0, 2]] # 畫出三點(diǎn)之間兩兩連線#colors = [[1, 0, 0], [0, 0, 0]]# 構(gòu)造open3d中的LineSet對(duì)象,用于主成分顯示#line_set = o3d.geometry.LineSet(points=o3d.utility.Vector3dVector(point), lines=o3d.utility.Vector2iVector(lines))#line_set.colors = o3d.utility.Vector3dVector(colors)#o3d.visualization.draw_geometries([point_cloud_o3d, line_set]) # 顯示原始點(diǎn)云和PCA后的連線最后的結(jié)果是
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?如有錯(cuò)誤歡迎評(píng)論留言指出感謝!共同進(jìn)步!
總結(jié)
以上是生活随笔為你收集整理的PCA(主成分分析法)的理解笔记及算法的实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电商移动Web实战项目(1)
- 下一篇: 明天起,鄂尔多斯这些地方要停电!涉及伊旗