特徵值分解和奇異值分解在機器學習領域都是屬於滿地可見的方法。二者有着很緊密的關係,我在接下來會談到,特徵值分解和奇異值分解的目的都是同樣,就是提取出一個矩陣最重要的特徵。先談談特徵值分解吧:算法
1)特徵值:框架
若是說一個向量v是方陣A的特徵向量,將必定能夠表示成下面的形式:機器學習
這時候λ就被稱爲特徵向量v對應的特徵值,一個矩陣的一組特徵向量是一組正交向量。特徵值分解是將一個矩陣分解成下面的形式:ide
其中Q是這個矩陣A的特徵向量組成的矩陣,Σ是一個對角陣,每個對角線上的元素就是一個特徵值。我這裏引用了一些參考文獻中的內容來講明一下。首先,要明確的是,一個矩陣其實就是一個線性變換,由於一個矩陣乘以一個向量後獲得的向量,其實就至關於將這個向量進行了線性變換。好比說下面的一個矩陣:學習
它其實對應的線性變換是下面的形式:ui
由於這個矩陣M乘以一個向量(x,y)的結果是:雲計算
上面的矩陣是對稱的,因此這個變換是一個對x,y軸的方向一個拉伸變換(每個對角線上的元素將會對一個維度進行拉伸變換,當值>1時,是拉長,當值<1時時縮短),當矩陣不是對稱的時候,假如說矩陣是下面的樣子:spa
它所描述的變換是下面的樣子:索引
這實際上是在平面上對一個軸進行的拉伸變換(如藍色的箭頭所示),在圖中,藍色的箭頭是一個最主要的變化方向(變化方向可能有不止一個),若是咱們想要描述好一個變換,那咱們就描述好這個變換主要的變化方向就行了。反過頭來看看以前特徵值分解的式子,分解獲得的Σ矩陣是一個對角陣,裏面的特徵值是由大到小排列的,這些特徵值所對應的特徵向量就是描述這個矩陣變化方向(從主要的變化到次要的變化排列)圖片
當矩陣是高維的狀況下,那麼這個矩陣就是高維空間下的一個線性變換,這個線性變化可能無法經過圖片來表示,可是能夠想象,這個變換也一樣有不少的變換方向,咱們經過特徵值分解獲得的前N個特徵向量,那麼就對應了這個矩陣最主要的N個變化方向。咱們利用這前N個變化方向,就能夠近似這個矩陣(變換)。也就是以前說的:提取這個矩陣最重要的特徵。總結一下,特徵值分解能夠獲得特徵值與特徵向量,特徵值表示的是這個特徵到底有多重要,而特徵向量表示這個特徵是什麼,能夠將每個特徵向量理解爲一個線性的子空間,咱們能夠利用這些線性的子空間幹不少的事情。不過,特徵值分解也有不少的侷限,好比說變換的矩陣必須是方陣。
(說了這麼多特徵值變換,不知道有沒有說清楚,請各位多提提意見。)
2)奇異值:
下面談談奇異值分解。特徵值分解是一個提取矩陣特徵很不錯的方法,可是它只是對方陣而言的,在現實的世界中,咱們看到的大部分矩陣都不是方陣,好比說有N個學生,每一個學生有M科成績,這樣造成的一個N * M的矩陣就不多是方陣,咱們怎樣才能描述這樣普通的矩陣呢的重要特徵呢?奇異值分解能夠用來幹這個事情,奇異值分解是一個能適用於任意的矩陣的一種分解的方法:
假設A是一個M * N的矩陣,那麼獲得的U是一個M * M的方陣(裏面的向量是正交的,U裏面的向量稱爲左奇異向量),Σ是一個M * N的矩陣(除了對角線的元素都是0,對角線上的元素稱爲奇異值),V’(V的轉置)是一個N * N的矩陣,裏面的向量也是正交的,V裏面的向量稱爲右奇異向量),從圖片來反映幾個相乘的矩陣的大小可得下面的圖片
那麼奇異值和特徵值是怎麼對應起來的呢?首先,咱們將一個矩陣A的轉置 * A,將會獲得一個方陣,咱們用這個方陣求特徵值能夠獲得:
這裏獲得的v,就是咱們上面的右奇異向量。此外咱們還能夠獲得:
這裏的σ就是上面說的奇異值,u就是上面說的左奇異向量。奇異值σ跟特徵值相似,在矩陣Σ中也是從大到小排列,並且σ的減小特別的快,在不少狀況下,前10%甚至1%的奇異值的和就佔了所有的奇異值之和的99%以上了。也就是說,咱們也能夠用前r大的奇異值來近似描述矩陣,這裏定義一下部分奇異值分解:
r是一個遠小於m、n的數,這樣矩陣的乘法看起來像是下面的樣子:
右邊的三個矩陣相乘的結果將會是一個接近於A的矩陣,在這兒,r越接近於n,則相乘的結果越接近於A。而這三個矩陣的面積之和(在存儲觀點來講,矩陣面積越小,存儲量就越小)要遠遠小於原始的矩陣A,咱們若是想要壓縮空間來表示原矩陣A,咱們存下這裏的三個矩陣:U、Σ、V就行了。
奇異值的計算是一個難題,是一個O(N^3)的算法。在單機的狀況下固然是沒問題的,matlab在一秒鐘內就能夠算出1000 * 1000的矩陣的全部奇異值,可是當矩陣的規模增加的時候,計算的複雜度呈3次方增加,就須要並行計算參與了。Google的吳軍老師在數學之美系列談到SVD的時候,提及Google實現了SVD的並行化算法,說這是對人類的一個貢獻,可是也沒有給出具體的計算規模,也沒有給出太多有價值的信息。
其實SVD仍是能夠用並行的方式去實現的,在解大規模的矩陣的時候,通常使用迭代的方法,當矩陣的規模很大(好比說上億)的時候,迭代的次數也可能會上億次,若是使用Map-Reduce框架去解,則每次Map-Reduce完成的時候,都會涉及到寫文件、讀文件的操做。我的猜想Google雲計算體系中除了Map-Reduce之外應該還有相似於MPI的計算模型,也就是節點之間是保持通訊,數據是常駐在內存中的,這種計算模型比Map-Reduce在解決迭代次數很是多的時候,要快了不少倍。
Lanczos迭代就是一種解對稱方陣部分特徵值的方法(以前談到了,解A’* A獲得的對稱方陣的特徵值就是解A的右奇異向量),是將一個對稱的方程化爲一個三對角矩陣再進行求解。按網上的一些文獻來看,Google應該是用這種方法去作的奇異值分解的。請見Wikipedia上面的一些引用的論文,若是理解了那些論文,也「幾乎」能夠作出一個SVD了。
因爲奇異值的計算是一個很枯燥,純數學的過程,並且前人的研究成果(論文中)幾乎已經把整個程序的流程圖給出來了。更多的關於奇異值計算的部分,將在後面的參考文獻中給出,這裏再也不深刻,我仍是focus在奇異值的應用中去。
主成分分析在上一節裏面也講了一些,這裏主要談談如何用SVD去解PCA的問題。PCA的問題實際上是一個基的變換,使得變換後的數據有着最大的方差。方差的大小描述的是一個變量的信息量,咱們在講一個東西的穩定性的時候,每每說要減少方差,若是一個模型的方差很大,那就說明模型不穩定了。可是對於咱們用於機器學習的數據(主要是訓練數據),方差大才有意義,否則輸入的數據都是同一個點,那方差就爲0了,這樣輸入的多個數據就等同於一個數據了。如下面這張圖爲例子:
這個假設是一個攝像機採集一個物體運動獲得的圖片,上面的點表示物體運動的位置,假如咱們想要用一條直線去擬合這些點,那咱們會選擇什麼方向的線呢?固然是圖上標有signal的那條線。若是咱們把這些點單純的投影到x軸或者y軸上,最後在x軸與y軸上獲得的方差是類似的(由於這些點的趨勢是在45度左右的方向,因此投影到x軸或者y軸上都是相似的),若是咱們使用原來的xy座標系去看這些點,容易看不出來這些點真正的方向是什麼。可是若是咱們進行座標系的變化,橫軸變成了signal的方向,縱軸變成了noise的方向,則就很容易發現什麼方向的方差大,什麼方向的方差小了。
通常來講,方差大的方向是信號的方向,方差小的方向是噪聲的方向,咱們在數據挖掘中或者數字信號處理中,每每要提升信號與噪聲的比例,也就是信噪比。對上圖來講,若是咱們只保留signal方向的數據,也能夠對原數據進行不錯的近似了。
PCA的所有工做簡單點說,就是對原始的空間中順序地找一組相互正交的座標軸,第一個軸是使得方差最大的,第二個軸是在與第一個軸正交的平面中使得方差最大的,第三個軸是在與第一、2個軸正交的平面中方差最大的,這樣假設在N維空間中,咱們能夠找到N個這樣的座標軸,咱們取前r個去近似這個空間,這樣就從一個N維的空間壓縮到r維的空間了,可是咱們選擇的r個座標軸可以使得空間的壓縮使得數據的損失最小。
仍是假設咱們矩陣每一行表示一個樣本,每一列表示一個feature,用矩陣的語言來表示,將一個m * n的矩陣A的進行座標軸的變化,P就是一個變換的矩陣從一個N維的空間變換到另外一個N維的空間,在空間中就會進行一些相似於旋轉、拉伸的變化。
而將一個m * n的矩陣A變換成一個m * r的矩陣,這樣就會使得原本有n個feature的,變成了有r個feature了(r < n),這r個其實就是對n個feature的一種提煉,咱們就把這個稱爲feature的壓縮。用數學語言表示就是:
可是這個怎麼和SVD扯上關係呢?以前談到,SVD得出的奇異向量也是從奇異值由大到小排列的,按PCA的觀點來看,就是方差最大的座標軸就是第一個奇異向量,方差次大的座標軸就是第二個奇異向量…咱們回憶一下以前獲得的SVD式子:
在矩陣的兩邊同時乘上一個矩陣V,因爲V是一個正交的矩陣,因此V轉置乘以V獲得單位陣I,因此能夠化成後面的式子
將後面的式子與A * P那個m * n的矩陣變換爲m * r的矩陣的式子對照看看,在這裏,其實V就是P,也就是一個變化的向量。這裏是將一個m * n 的矩陣壓縮到一個m * r的矩陣,也就是對列進行壓縮,若是咱們想對行進行壓縮(在PCA的觀點下,對行進行壓縮能夠理解爲,將一些類似的sample合併在一塊兒,或者將一些沒有太大價值的sample去掉)怎麼辦呢?一樣咱們寫出一個通用的行壓縮例子:
這樣就從一個m行的矩陣壓縮到一個r行的矩陣了,對SVD來講也是同樣的,咱們對SVD分解的式子兩邊乘以U的轉置U'
這樣咱們就獲得了對行進行壓縮的式子。能夠看出,其實PCA幾乎能夠說是對SVD的一個包裝,若是咱們實現了SVD,那也就實現了PCA了,並且更好的地方是,有了SVD,咱們就能夠獲得兩個方向的PCA,若是咱們對A’A進行特徵值的分解,只能獲得一個方向的PCA。
潛在語義索引(Latent Semantic Indexing)與PCA不太同樣,至少不是實現了SVD就能夠直接用的,不過LSI也是一個嚴重依賴於SVD的算法,以前吳軍老師在矩陣計算與文本處理中的分類問題中談到:
「三個矩陣有很是清楚的物理含義。第一個矩陣X中的每一行表示意思相關的一類詞,其中的每一個非零元素表示這類詞中每一個詞的重要性(或者說相關性),數值越大越相關。最後一個矩陣Y中的每一列表示同一主題一類文章,其中每一個元素表示這類文章中每篇文章的相關性。中間的矩陣則表示類詞和文章雷之間的相關性。所以,咱們只要對關聯矩陣A進行一次奇異值分解,w 咱們就能夠同時完成了近義詞分類和文章的分類。(同時獲得每類文章和每類詞的相關性)。」
上面這段話可能不太容易理解,不過這就是LSI的精髓內容,我下面舉一個例子來講明一下,下面的例子來自LSA tutorial,具體的網址我將在最後的引用中給出:
這就是一個矩陣,不過不太同樣的是,這裏的一行表示一個詞在哪些title中出現了(一行就是以前說的一維feature),一列表示一個title中有哪些詞,(這個矩陣實際上是咱們以前說的那種一行是一個sample的形式的一種轉置,這個會使得咱們的左右奇異向量的意義產生變化,可是不會影響咱們計算的過程)。好比說T1這個title中就有guide、investing、market、stock四個詞,各出現了一次,咱們將這個矩陣進行SVD,獲得下面的矩陣:
左奇異向量表示詞的一些特性,右奇異向量表示文檔的一些特性,中間的奇異值矩陣表示左奇異向量的一行與右奇異向量的一列的重要程序,數字越大越重要。
繼續看這個矩陣還能夠發現一些有意思的東西,首先,左奇異向量的第一列表示每個詞的出現頻繁程度,雖然不是線性的,可是能夠認爲是一個大概的描述,好比book是0.15對應文檔中出現的2次,investing是0.74對應了文檔中出現了9次,rich是0.36對應文檔中出現了3次;
其次,右奇異向量中一的第一行表示每一篇文檔中的出現詞的個數的近似,好比說,T6是0.49,出現了5個詞,T2是0.22,出現了2個詞。
而後咱們反過頭來看,咱們能夠將左奇異向量和右奇異向量都取後2維(以前是3維的矩陣),投影到一個平面上,能夠獲得:
在圖上,每個紅色的點,都表示一個詞,每個藍色的點,都表示一篇文檔,這樣咱們能夠對這些詞和文檔進行聚類,好比說stock 和 market能夠放在一類,由於他們總是出如今一塊兒,real和estate能夠放在一類,dads,guide這種詞就看起來有點孤立了,咱們就不對他們進行合併了。按這樣聚類出現的效果,能夠提取文檔集合中的近義詞,這樣當用戶檢索文檔的時候,是用語義級別(近義詞集合)去檢索了,而不是以前的詞的級別。這樣一減小咱們的檢索、存儲量,由於這樣壓縮的文檔集合和PCA是殊途同歸的,二能夠提升咱們的用戶體驗,用戶輸入一個詞,咱們能夠在這個詞的近義詞的集合中去找,這是傳統的索引沒法作到的。