維數約減--Dimensionality Reduction
維數約減屬於無監督學習范疇,我們希望使用維數約減的原因可能有:通過數據壓縮以減少數據占有內存的大小,為算法運算提高速度,將數據可視化等。
數據壓縮-data compression
某個物體的長度以x1厘米為單位,另一個x2是它以英寸為單位的長度。這是一個非常冗余的數據,所以與其用兩個特征變量x1和x2,但它們都是測量到的長度,或許我們應該把這個數據降到一維,這樣一來只用一個長度的數據。
從二維/2D降到一維/1D到底意味着什么?通過樣本塗上不同的顏色,在這個例子中降低維度的意思指找到這樣一條線,基本所有點都落在這個方向上然后把所有的數據映射到這條線上,這樣做之后就可以直接測量這條線上每個樣本的位置,現在把這個新特征叫做z1,要確定這條線上的位置只需要一個數字,這就是說新特征變量z1能夠表示這條綠線上每一個點的位置。
接着舉一個3D縮減為2D的例子,如下:左邊是原始數據集,中間是投影到2D的數據集,右邊是以z1和z2為坐標軸的2D數據集。我們來更詳細地看一下左側,這是原始數據集(3D點雲),開始它的坐標軸是x1,x2,x3。所以這是一個3D的點雲,但是大部分數據都落在某個2D平面上或者說距離某個2D平面不遠。
可視化數據-data visualization
除了壓縮數據,可視化數據對於機器學習的應用幫助也很大,可以提高開發高效學習算法的效率,而前提要求我們必須很好地理解數據。
假如我們收集了大量的關於全世界不同國家的統計數據集,第一個特征x1是國內生產總值,x2是每人占有的GDP,x3人類發展指數,x4預期壽命,x5x6等。像這里這樣的數據對於每個國家可能有50個特征,我們有這樣的眾多國家的數據集,那么有沒有辦法使得我們能更好地來理解數據?
這里給出了一張有數字的表格,你怎樣將這些數據可視化?如果有50個特征繪制一幅50維度的圖是異常困難的,那有沒有觀察數據的好辦法呢?
我們使用特征向量x(i)來表示每個國家,x(i)有着50個維度。例如,加拿大這個國家的特征用50個數字來代表,我們要能提出一種不同的特征表示方法,使用一個二維的向量z來代替x。
仔細觀察降維算法的輸出結果,它通常不能賦予你想要的這些二維新特征一個物理含義,在這里每個國家用一個點z(i)表示,z(i)是一個二維數據,或許會發現例如那條水平軸即z1軸大致對應了國家總面積或者一個國家的總體經濟活動情況,然而縱軸即z2的數據或許對應着人均GDP或是人均幸福感。
主成分分析法-Principal Component Analysis(PCA)
公式formula
對於降維問題,目前最流行的算法是主成分分析法PCA,首先我們用公式准確的描述想讓PCA來做什么。我們有這樣的一個數據集,這個數據集含有二維實數空間內的樣本X,假設我想對數據進行降維,即從二維降到一維,現在想找到一條直線將數據投影到這條直線上那怎么找到一條好的直線來投影這些數據呢?
更一般的情況是我們有n維的數據想降到k維,在這種情況下我們不僅僅只尋找單個的向量來對數據進行投影我們要找到k個方向來對數據進行投影從而最小化投影誤差。
如果有下圖所示的一些三維數據點,那么我們想要做的是尋找兩個向量,用紅線畫出來, 尋找兩個向量從原點延伸出來,這是u(1)這是第二個向量u(2),這兩個向量一起定義了一個平面或者說定義了一個二維面。因此PCA做的就是尋找一條直線或者平面諸如此類等等對數據進行投影來最小化平方投影90度的或者正交的投影誤差。
PCA 並不是線性回歸
盡管看上去有一些相似但是它們確實是兩種不同的算法,如下圖左側,要在給定某個輸入特征x的情況下預測某個變量y的數值,故對於線性回歸我們想做的是擬合一條直線來最小化點和直線之間的平方誤差。所以我們要最小化的是這些藍線幅值的平方,注意所畫的這些藍色的垂直線,這是垂直距離,它是某個點與通過假設的得到的其預測值之間的y軸方向上的距離。
更一般的是當你做線性回歸的時候有一個特別的變量y,我們將要預測的線性回歸就是用x的所有的值來預測y。然而,在PCA中沒有這么一個特別的或者特殊的變量y,我們所擁有的是特征x1,x2等一直到xn所有的這些特征都是被同樣地對待因此它們中沒有一個是特殊的。
PCA算法實現
在使用PCA之前我們通常會有一個數據預處理的過程:拿到某組有m個無標簽樣本的訓練集一般先進行均值歸一化(meannormalization),這一步很重要,然后還可以進行特征縮放(featurescaling)這根據你的數據而定。這跟我們之前在監督學習中提到的均值歸一和特征縮放是一樣的實際上它們是完全一樣的步驟只不過現在我們針對的是一系列無標簽的數據x(1)到x(m),因此對於均值歸一我們首先應該計算出每個特征的均值μ,然后我們用x-μ來替換掉x這樣就使得所有特征的均值為0。
由於不同特征的取值范圍都很不一樣,比如說如果x1表示房子的面積,x2表示房屋的卧室數量。然后我們可以把每個特征進行縮放,使其處於同一可比的范圍內。
同樣地,跟之前的監督學習類似我們可以用\(x_j{(i)}\)減去平均值μj,除以sj來替換掉第j個特征\(x_j{(i)}\),這里的sj表示特征j的某個量度范圍,因此它可以表示最大值減最小值,更普遍地,它可以表示特征j的標准差進行。
完以上這些數據預處理后接下來就正式進入PCA的算法部分。在上節中我們已經知道了PCA的原理,PCA是在試圖找到一個低維的子空間,然后把原數據投影到子空間上並且最小化平方投影誤差的值,或者說投影誤差的平方和。因此我們想要做的是找到某個具體的向量u(1)指定這條投影線的方向,或者在2D的情況下我們想要找到兩個向量u(1)和u(2)來定義一個投影平面對數據進行投影。
PCA要做的事兒就是要得到一種方法來計算兩個東西,其一是計算這些向量比如這里的u(1),這里的u(1)、u(2)。另一個問題是怎樣計算出這些z,對於左邊這個例子我們要把數據從二維降到一維,對於右邊這個例子我們要把數據從三維降到二維。從原來的x(i)變為現在的z(i),新的z向量是二維的,它應該是{z1,z2}這樣的一個向量。
假如說我們想要把數據從n維降低到k維,我們首先要做的是計算出這個協方差矩陣(covariance matrix)通常以希臘字母大寫的∑來表示,這里區分與后面的求和符號,假如我們把協方差矩陣存為Octave/MATLAB中的一個變量叫Sigma,我們需要做的是計算出Sigma矩陣的特征向量(eigenvectors)。
在Octave/MATLAB中你可以使用如下命令來實現這一功能
[U,S,V]=svd(Sigma);
svd表示奇異值分解(singular value decomposition),這是某種更高級的奇異值分解,此外還有另一個eig命令,也可以用來計算特征向量。參見強大的矩陣奇異值的分解SVD應用
實際上svd命令和eig命令將得到相同的結果,這是因為協方差均值總滿足一個數學性質--對稱正定(symmetric positive definite),但是svd其實要更穩定一些。
協方差矩陣Sigma應該是一個n×n的矩陣,然后svd將輸出三個矩陣分別是U、S、V。這里真正需要的是U矩陣,U矩陣也是一個n×n矩陣。如果我們想將數據的維度從n降低到k的話,我們只需要提取前k列向量,這樣我們就得到了u(1)到u(k),也就是我們用來投影數據的k個方向。
接下來對於原始數據集x,x是一個n維實數,然后我們要找到一個低維的表達z,z是k維實數,我們構建這樣一個矩陣把u(1)、u(2)一直到u(k),並列地合起來,其實就是取出這個U矩陣的前k列元素,將這個新的矩陣成為\(U_{reduce}\)即約減后的矩陣。z等於這個\(U_{reduce}\)矩陣的轉置乘以x。
小結一下:首先對數據集進行預處理,利用均值歸一化確保所有的特征均值為零,必要時可以添加特征縮減,接着計算協方差矩陣sigma∑,為:,利用octave/Matlab中的奇異值分解svd函數得到約減矩陣:
[U,S,V] = svd(Sigma);
Ureduce = U(:,1:k);
計算投影值:z = Ureduce'*x;
重構--將壓縮過的數據還原-Reconstruction
如下圖:現有樣本x(1)樣本x(2),那我們要讓這些樣本投影在一維平面上,我們現在只需要使用一個實數就能在它們全部被投影到這個一維平面z1上,並且明確地指定其位置。
用圖表示出來,我們可以看到這些點都到綠線上去了,與原始樣本點的位置有一定誤差,但已經是與原始數據非常近似了,通過這個公式我們得到x_approx(1)對應於圖上x_approx(1),可以使用同樣的步驟計算出x_approx(2)。
確定k值
在正式確定中心成分的數目k值時,我們需要先了解倆個定義,第一:平均平方映射誤差(Average Squared Projection Error),它是原始數據x和映射值x_approx(i)之間的差,PCA就是要將這個量最小化。這個在上節中也做過定義,它就是要最小化x和其在低維表面上的映射點之間的距離的平方。
\(\frac{1}{m}\sum_{i=1}^{m}||x^{(i)}-x_{approx}^{(i)}||^2\)
第二:數據的總變差(TotalVariation),它是這些樣本x(i)的長度的平方的均值,意思是“平均來看訓練樣本距離零向量(零點)距離。
\(\frac{1}{m}\sum_{i=1}^{m}||x^{(i)}||^2\)
一個非常常用的選擇k值的方法是希望平均平方映射誤差就是x和其映射值之間的平均距離,除以數據的總變差,希望這個比值能夠小於0.01或者說是小於1%。
對於選取k的值,最容易想到的:我們可以從k=1開始,然后我們再進行主成分分析我們算出U_reduce,z(1)、z(2)一直到z(m)。算出所有x_approx(1)一直到x_approx(m),然后看99%(或90%)的差異性是否被保留下來了,如果不是接下來嘗試k=2,然后重新走一遍整個過程檢查是否滿足這個表達式,如果不是我們再重復一次我們嘗試k=3然后試k=4,以此類推一直試到比如我們一直試到k=17然后發現99%的數據都被保留了。我們就會用k=17這是一種用來選擇使得99%的差異性能夠得以保留的最小的k值的方法,但是可以想見這個過程的效率相當地低!!
其實在應用PCA時,它已經給了我們一個可以使計算變得容易很多的量,特別是當你對協方差的矩陣Sigma調用svd時,我們還會得到這個矩陣S,S是一個正方形矩陣實際上是一個n×n的矩陣,它是一個對角矩陣對角線上的元素是\(s_{11},s_{22},s_{33}\)一直到\(s_{nn}\)。
假如說k=3,我們接下來要計算的分子是從i=1到3對Sii求和從i=1到3對Sii求和就是算出這前三個元素的和,這就是分子。然后計算分母分母是這些對角元素的總和。
你要做的就是慢慢地增大k值,把k值設為1、k值設為2、把k值設為3,以此類推並檢驗這個數值。找出能夠確保99%的差異性被保留的最小的k值,找出能夠確保99%的差異性被保留的最小的k值。
順便說一下,如果想要向他們解釋你實現的PCA的性能的一個好方法實際上是這個數值把它算出來,它會告訴你百分之多少的差異性被保留了下來,如果你把這個數值展現出來,那么熟悉PCA的人們就可以通過它來更好地理解你用來代表原始數據的100維數據近似得有多好。
PCA應用中的幾點建議
首先介紹如何通過PCA來提高學習算法的速度,比如說你遇到了一個監督學習問題注意這個監督學習算法問題有輸入x和標簽y,而你的樣本x(i)是非常高維的數據,比如說x(i)是一個10,000維的向量,如一張100×100的圖片。如果x(i)是包含了這10000像素強度值的特征向量,那么就會有10000維特征向量。
如果你輸入10,000維的特征向量到邏輯回歸中或者到一個神經網絡、支持向量機中,或是任何別的算法中,像這樣有很高維的特征向量運行會比較慢。使用PCA能夠降低數據的維數從而使算法更加高效地運行。
提取出x並暫時把y放在一邊,通過這一步會得到一組無標簽的訓練集,從x(1)到x(m)這可能會有10,000維數據也就是10,000維數據樣本所以就是從數據組中x(1)到x(m)中提取出輸入向量。
最后要注意一點PCA定義了從x到z的對應關系,這種從x到z的對應關系只可以通過在訓練集上運行PCA定義出來。
具體來講,計算出這樣一個降維的矩陣U_reduce,但是降維矩陣U_reduce中的數據就像一個PCA所學習的參數一樣,我們需要使參數唯一地適應這些訓練集而不是適應交叉驗證或者測試集。
因此U_reduce矩陣中的數據應該只通過對訓練集運行PCA來獲得,找出了降維矩陣U_reduce或者找出了這些特征擴展的參數之后,均值均一化,在訓練集中找到了所有這些參數后就可以將同樣的對應關系應用到其他樣本中了可能是交叉驗證數集樣本或者測試數據集中。
總結一下,當在運行PCA的時候只是在訓練集那一部分來進行的而不是交叉驗證的數據集,這就定義了從x到z的映射,然后就可以將這個映射應用到交叉驗證數據集中和測試數據集中。
假設x(i)為有n個特征的數據集,我們將數據進行壓縮並用壓縮后的數據z(i)來代替原始數據,在降維過程中我們從n個特征降維到k個,比先前的維度低。例如如果我們有非常小的特征數目,假如k值為1000,n值為10000,那么1000維度的數據和用10000維度的數據比起來對於同樣是1000個特征來說或許更不容易過擬合。所以有些人認為PCA是一種避免過擬合的方法,然而這並不是一個合適的PCA應用。仔細想想PCA是如何工作的它並不需要使用數據的標簽label,只需要輸入數據x(i),同時使用這個方法時PCA把某些信息舍棄掉了。而只使用正則化將會是一種避免過擬合絕對好的方法。
建議一開始不要將PCA方法就直接放到算法里,先使用原始數據x(i)看看效果,只有一個原因讓我們相信算法出現了問題那就是你的學習算法收斂地非常緩慢占用內存或者硬盤空間非常大,所以你想來壓縮數據只有當你的x(i)效果不好只有當你有證據或者充足的理由來確定x(i)效果不好的時候那么就考慮用PCA來進行壓縮數據。