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