日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

pca算法介绍及java实现_PCA算法原理及实现

發布時間:2024/7/23 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pca算法介绍及java实现_PCA算法原理及实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

眾所周知,PCA(principal component analysis)是一種數據降維的方式,能夠有效的將高維數據轉換為低維數據,進而降低模型訓練所需要的計算資源。

以上是比較官方的說法,下面是人話(正常人講的話)版。

pca就是一種能夠有效壓縮數據的方法!打個不太準確的例子:我們現在有一個描述人的健康狀況的數據:(年齡,身高,體重,地區,血壓,心率,肺活量,體溫,體脂),也就是說(年齡,身高,體重,地區,血壓,心率,肺活量,體溫,體脂)這些東西是特征,而這些特征對應的標簽是健康狀況:健康/亞健康/不健康。那么pca就是通過一些方法,將這9個特征壓縮到只有4個,3個甚至更少的特征(暫且稱之為x1, x2, x3, x4),但是我們仍能用這些特征來準確預測它們對應的健康狀況。

在這里補充一下,在數學/機器學習中,我們會把特征抽象為向量,比如上面提到的健康狀況的數據:(年齡,身高,體重,地區,血壓,心率,肺活量,體溫,體脂),我們會抽象為(18, 180, 70,廣東,100,80, 5000, 37, 0.1),其中地區這一項顯得與眾特別,畢竟其他的維度都是數值,就它是文字。我們把這樣的維度稱為類別,因為它是在有限的選項中選出來的(從世界上所有的地區中取一個),在計算機中表示這樣的信息,我們可以有很多方式,但是為了簡化難度,這邊我就暫且不搞,直接把這一列刪掉。于是乎我們的數據(其實就是向量!)就是(18, 180, 70, 100, 80, 5000, 37, 0.1),值得一提的是,這樣的一個數據是屬于一個實體的(也就是說這是描述一個人的健康狀況的),在機器學習中,我們傾向于將一個實體的數據排成一列,也就是(18, 180, 70, 100, 80, 5000, 37, 0.1)^T(轉置)。

本文要介紹的目錄為:使用PCA的必要性

PCA的本質

前置知識的介紹

PCA的數學原理

PCA的思想

PCA的實現

使用PCA的必要性

前面說了,pca就是將高維(很多列屬性)數據轉換為低維(較少列)數據的方法,同時保留大部分信息(可以用保留的信息準確預測)。但是我們可能會想:如果我不壓縮的話,那我不就可以有100%的數據嗎?我閑著沒事干壓縮干哈?其實我一開始使用的時候也有這樣的疑惑,因為我一開始是用在圖像上的,而一個圖像只有500多個維度(列)的數據,使用pca壓縮到100列可以保存原始數據95%的信息,但是我發現我用壓縮的數據和不壓縮的數據對模型的訓練速度并沒有什么影響。。。但是后來我做其他一些有500000維度的數據的時候,發現使用pca將維度降到5000就能保存接近98%的數據,而且訓練速度可以提升數十倍!于是我就成了pca的腦殘粉了。。。所以pca在應對高維度數據的時候是有奇效的!它不僅可以有效減少訓練時間而且還可以防止過擬合,前面一點上文已給出原因,防止過擬合在下文給出。

PCA的本質

其實pca的本質很簡單,上面也有說,就是將高維度數據轉換到低維度,不過在這里為了讓大家能夠有所體會,我使用2維數據降到1維在解釋這點。

如上圖所示,假設我們的原始數據A, B, C是在直角坐標系中的三個點,它們的坐標分別為A(x_a, y_a), B(x_b, y_b), C(x_c, y_c),那么我們現在想要使用pca,將這三個在平面上的點降維到直線上(也就是上圖中黃色的線上)。那么現在的問題就是:平面中的A, B, C點(高維數據)可以通過怎樣的映射關系降維到黃線上(也就是高維的數據如何在低維中表示)。

這條黃線(就是低維)怎么求/確定?

前置知識的介紹

對于上面提到的題一個問題(如何將高維度數據映射到低維度中),我們需要先知道數據點如何被表示。

這看起來似乎是一個很蠢的問題,因為答案貌似很簡單,比如圖xx中的點ABC不就是A(x1, y1), B(x2, y2), C(x3, y3)嗎?對滴!這個答案是沒有問題的,但是這樣的答案并不具有普遍性,也就是說如果我們的坐標系發生了變化(類比直角坐標系變化到極坐標系),那就不能再用(x, y)這樣的形式進行表示了,那么我們這里需要更加普遍的方法。

我先說答案,再說為什么是這個答案~。答案就是通過坐標系的基向量來表示數據(向量)。如圖所示,我們取i和j作為基向量(在這里i的坐標為(1,0), j的坐標為(0, 1)),那么數據A(1, 2),就可以表示為(1*i, 2*j)。于是我們把這個問題拓展開來,二維上的數據點可以通過(基向量i*數據點在基向量i上的投影長度,基向量j*數據點在基向量j上的投影長度)表示,那么三維上的數據點也可以用這樣的方式,于是乎n(n>=2)維上的點可以表示為:(基向量i*數據點在基向量i上的投影長度,基向量j*數據點在基向量j上的投影長度,…,基向量n * 數據點在基向量n上的投影長度),于是乎我們這個子問題就解決了,即找到了一種在不同維度坐標系下表示數據的方法。

PCA的數學原理

那么接下來的問題就是,我們如何把一個數據點從一個維度轉變到另一個維度。

在解決這個問題之前,我們先用矩陣描述一下上一個問題,比如我們現在基向量為(0,1)和(1,0)的坐標中表示(3,2),則可以寫作為:

假設我們現在有一個新的坐標系,這個坐標系的基向量i和j在普通平面直角坐標系中的表示是(0, -1)和(1, 0),(其實就是普通直角坐標系順時針旋轉90度),如下圖所示(黑色為新的坐標系):

A點在普通直角坐標系中為(3, 2),在新的直角坐標系中為(-2, 3)。新的坐標(-2, 3)可以通過以下方式計算:

于是乎我們找到了二維空間下數據變換的方式:

新的基向量矩陣*原基向量矩陣的轉置*原數據向量=新的數據向量

也就是說我們想要將高維數據轉換為低維數據可以通過:

低維空間的基向量矩陣 * 高維空間的基向量矩陣的轉置 * 高維數據向量 = 低維數據向量

而參考上圖,我們可以知道‘高維空間的基向量矩陣的轉置 * 高維數據向量’是等于高維數據向量本身的,于是乎可以得到:

低維空間的基向量矩陣 * 高維數據向量 = 低維數據向量(此處應有數學公式)

接下來我們解決第二個大問題,也就是如下這條黃線(就是低維)怎么求/確定?

PCA的思想

這樣要確定低維,要么就要給出標準,也就是什么樣的低維是好的?

在這里先確定兩個標準,稍后解釋為什么確定這兩標準:不同特征之間的方差盡可能大。

不同特征之間的協方差等于0。

設立這兩個標準的原因是這樣的:

先做一個前提假設哈!

假設我們現在有兩個樣本(在這個例子中就是兩個人),他們的健康狀況如下:

好了,我要來解釋了。

第一個標準的解釋其實不算太難,假設我們現在要處理上面的數據,也就是要將小王和老丁的數據的進行降維,而他們的健康數據包含9個特征(健康水平是算作label而不是特征X,相當于y=f(X)中的y),理想狀態是每個特征描述的東西都是完全不同的(因為特征描述的是對象的特性,如果兩個特征描述的東西很類似甚至可以被代替,那就浪費了大把的計算資源了。比如說現在有這樣兩個特征,第一個特征是:是否為男性,第二個特征是:是否為女性。如果第一個特征為真,則第二個特征必定為假,也就是這兩個東西描述的都是同一個特性,就是性別),也就是說在原始數據中,不同的特征它們之間的方差應該是很大的(可以理解為方差越大,這兩個東西越不同)。而每個特征之間我們希望降維之后它們也和原來的數據一樣,不同的特征之間保持有大的方差,于是乎就有了第一個標準:不同特征之間的方差盡可能大。

第二個標準的解釋其實和第一個標準是類似的,只不過形式不同。上面說過了,我們是希望原數據中不同的特征降維后還是不同,而希望它們不同就等價于說它們之間不相關,而協方差就是用來衡量兩個特征之間的相關程度的,當協方差等于0的時候,就說明這兩個特征之間是無關的。所以就有了這個標準:不同特征之間的協方差等于0。

好了!現在我們已經有了處理標準了,接下來我們就要把這個標準給抽象化(就是寫成數學公式)方便我們計算!

我重新上面的數據貼出來:

寫成向量的形式

讓我們先寫出標準1的公式吧:

其中X就是一個特征的數據,用我們上面的例子來說,假設X是身高,則X為(180, 175),則/mu就是177.5,m等于2,于是就求得Var(X)= xxx,同樣的道理可以用來算年齡呀,血壓呀,心率呀啥的。

這里有個技巧,就是我們先對X進行處理,就是將其減去它的均值:X = X - /mu,于是乎我們的公式就變成了:

標準2的公式如下:

我們用上面的技巧,于是乎我們的公式就變成了:

現在我們把這兩個標準給寫成數學的公式了,這樣我們就可以用計算機來算了。但是這兩個公式是分開的。。(就是說他們是兩個公式),這樣并不太方便于我們計算,我們要像個辦法把他們組合起來,這樣優化起來才能”聯動”。在這里我介紹一個矩陣,叫做協方差矩陣:

可以發現,這個矩陣的正對角線就是我們的標準1,也就是方差,而其他的位置則為協方差。所以我們的目的就是使得協方差的位置為0,然后選取方差最大的值(選取方差最大的值可能有點疑惑,是這樣的:我們的特征矩陣X是可以有很多特征的,比如年齡,血壓,心率,肺活量等等,而方程右邊的a和b就是這些特征中的一個,那么勢必有些特征的方差比較大,有些特征的方差比較小。而那些方差比較小的特征我們就覺得它們沒有那么好的區分效果,而那些方差大的就覺得它們有很好的區分效果,于是乎就把它們選中)。

于是乎我們的目標就變成了,通過優化方法,使得協方差矩陣對角化(就是非對角線的位置值為0)。接下來是很簡單的數學推導了。

假設我們最終的協方差矩陣(就是上面說的對角化后的矩陣)為D,X為我們的特征矩陣,C為我們特征矩陣X的協方差矩陣,我們要找到一個矩陣P,使得我們的X特征矩陣可以變成D矩陣。

也就是說,我們現在的目標就變成了找到一個矩陣P,使得矩陣以上等式成立。這里需要一丟丟線性代數的知識,主要是關于實對稱矩陣的知識,但是這里就不說啦!

最后我們就可以得到矩陣P,這個矩陣P是由我們的特征X矩陣找到的,你也可以理解為它蘊含著我們X矩陣的信息,而這些信息的重要性是越往上的越重要,比如:

則第一行中的(0.2 0.3)的重要性要高于第二行的(0.4 0.2),然后我們想將我們的數據降到一維度,則:

其中X是原始特征,newX是降維后的特征,而(0.2 0.3)就是我們P矩陣的第一列。從之前的知識可以知道,我們是將X矩陣降維到一維。

PCA的實現import numpy as npimport pandas as pdimport matplotlib.pyplot as plt

定義一個均值函數。#計算均值,要求輸入數據為numpy的矩陣格式,行表示樣本數,列表示特征def?meanX(dataX):return?np.mean(dataX,axis=0)#axis=0表示依照列來求均值。假設輸入list,則axis=1

開始實現pca的函數:def pca(XMat, k):'''XMat:傳入的是一個numpy的矩陣格式,行表示樣本數,列表示特征k:表示取前k個特征值相應的特征向量finalData:指的是返回的低維矩陣reconData:相應的是移動坐標軸后的矩陣'''average = meanX(XMat)m, n = np.shape(XMat)data_adjust = []avgs = np.tile(average, (m, 1))data_adjust = XMat - avgscovX = np.cov(data_adjust.T) #計算協方差矩陣featValue, featVec= np.linalg.eig(covX) #求解協方差矩陣的特征值和特征向量index = np.argsort(-featValue) #依照featValue進行從大到小排序finalData = []if k > n:print('k must lower than feature number')returnelse:#注意特征向量時列向量。而numpy的二維矩陣(數組)a[m][n]中,a[1]表示第1行值selectVec = np.matrix(featVec.T[index[:k]]) #所以這里須要進行轉置finalData = data_adjust * selectVec.TreconData = (finalData * selectVec) + averagereturn finalData, reconData

到這里整個流程基本就結束了~

總結

以上是生活随笔為你收集整理的pca算法介绍及java实现_PCA算法原理及实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。