奇异值(Singular value decomposition SVD)分解
SVD分解
SVD分解是LSA的數(shù)學基礎,本文是我的LSA學習筆記的一部分,之所以單獨拿出來,是因為SVD可以說是LSA的基礎,要理解LSA必須了解SVD,因此將LSA筆記的SVD一節(jié)單獨作為一篇文章。本節(jié)討論SVD分解相關數(shù)學問題,一個分為3個部分,第一部分討論線性代數(shù)中的一些基礎知識,第二部分討論SVD矩陣分解,第三部分討論低階近似。本節(jié)討論的矩陣都是實數(shù)矩陣。
基礎知識
數(shù)學知識不清楚可以參考:http://student.zjzk.cn/course_ware/web-gcsx/main.htm
1. 矩陣的秩:矩陣的秩是矩陣中線性無關的行或列的個數(shù) 參考:http://student.zjzk.cn/course_ware/web-gcsx/gcsx/chapter3/chapter3.1.htm
2. 對角矩陣:對角矩陣是除對角線外所有元素都為零的方陣
3. 單位矩陣:如果對角矩陣中所有對角線上的元素都為1,該矩陣稱為單位矩陣
4. 特征值:對一個M x M矩陣C和向量X,如果存在λ使得下式成立
?
則稱λ為矩陣C的特征值,X稱為矩陣的特征向量。非零特征值的個數(shù)小于等于矩陣的秩。
5. 特征值和矩陣的關系:考慮以下矩陣
該矩陣特征值λ1 = 30,λ2 = 20,λ3 = 1。對應的特征向量
假設VT=(2,4,6) 計算S x VT
有上面計算結果可以看出,矩陣與向量相乘的結果與特征值,特征向量有關。觀察三個特征值λ1 = 30,λ2 = 20,λ3 = 1,λ3值最小,對計算結果的影響也最小,如果忽略λ3,那么運算結果就相當于從(60,80,6)轉變?yōu)?60,80,0),這兩個向量十分相近。這也表示了數(shù)值小的特征值對矩陣-向量相乘的結果貢獻小,影響小。這也是后面談到的低階近似的數(shù)學基礎。
矩陣分解
1. 方陣的分解
1) 設S是M x M方陣,則存在以下矩陣分解
其中U 的列為S的特征向量,為對角矩陣,其中對角線上的值為S的特征值,按從大到小排列:
2) 設S是M x M 方陣,并且是對稱矩陣,有M個特征向量。則存在以下分解
其中Q的列為矩陣S的單位正交特征向量,仍表示對角矩陣,其中對角線上的值為S的特征值,按從大到小排列。最后,QT=Q-1,因為正交矩陣的逆等于其轉置。
2. 奇異值分解
上面討論了方陣的分解,但是在LSA中,我們是要對Term-Document矩陣進行分解,很顯然這個矩陣不是方陣。這時需要奇異值分解對Term-Document進行分解。奇異值分解的推理使用到了上面所講的方陣的分解。
假設C是M x N矩陣,U是M x M矩陣,其中U的列為CCT的正交特征向量,V為N x N矩陣,其中V的列為CTC的正交特征向量,再假設r為C矩陣的秩,則存在奇異值分解:
其中CCT和CTC的特征值相同,為
Σ為M X N,其中,其余位置數(shù)值為0,的值按大小降序排列。以下是Σ的完整數(shù)學定義:
σi稱為矩陣C的奇異值。
用C乘以其轉置矩陣CT得:
上式正是在上節(jié)中討論過的對稱矩陣的分解。
奇異值分解的圖形表示:
從圖中可以看到Σ雖然為M x N矩陣,但從第N+1行到M行全為零,因此可以表示成N x N矩陣,又由于右式為矩陣相乘,因此U可以表示為M x N矩陣,VT可以表示為N x N矩陣
3. 低階近似
LSA潛在語義分析中,低階近似是為了使用低維的矩陣來表示一個高維的矩陣,并使兩者之差盡可能的小。本節(jié)主要討論低階近似和F-范數(shù)。
給定一個M x N矩陣C(其秩為r)和正整數(shù)k,我們希望找到一個M x N矩陣Ck,其秩不大于K。設X為C與Ck之間的差,X=C – Ck,X的F-范數(shù)為
當k遠小于r時,稱Ck為C的低階近似,其中X也就是兩矩陣之差的F范數(shù)要盡可能的小。
SVD可以被用與求低階近似問題,步驟如下:
1. 給定一個矩陣C,對其奇異值分解:
2. 構造,它是將的第k+1行至M行設為零,也就是把的最小的r-k個(the r-k smallest)奇異值設為零。
3. 計算Ck:
回憶在基礎知識一節(jié)里曾經(jīng)講過,特征值數(shù)值的大小對矩陣-向量相乘影響的大小成正比,而奇異值和特征值也是正比關系,因此這里選取數(shù)值最小的r-k個特征值設為零合乎情理,即我們所希望的C-Ck盡可能的小。完整的證明可以在Introduction to Information Retrieval[2]中找到。
我們現(xiàn)在也清楚了LSA的基本思路:LSA希望通過降低傳統(tǒng)向量空間的維度來去除空間中的“噪音”,而降維可以通過SVD實現(xiàn),因此首先對Term-Document矩陣進行SVD分解,然后降維并構造語義空間。
二、下面這篇文字深入淺出解釋了奇異值分解的意義:
原文地址:http://blog.csdn.net/xiahouzuoxin/article/details/41118351
特征值與特征向量的幾何意義
矩陣的乘法是什么,別只告訴我只是“前一個矩陣的行乘以后一個矩陣的列”,還會一點的可能還會說“前一個矩陣的列數(shù)等于后一個矩陣的行數(shù)才能相乘”,然而,這里卻會和你說——那都是表象。
矩陣乘法真正的含義是變換,我們學《線性代數(shù)》一開始就學行變換列變換,那才是線代的核心——別會了點貓膩就忘了本——對,矩陣乘法?就是線性變換,若以其中一個向量A為中心,則B的作用主要是使A發(fā)生如下變化:
伸縮
clf; A = [0, 1, 1, 0, 0;...1, 1, 0, 0, 1]; % 原空間 B = [3 0; 0 2]; % 線性變換矩陣plot(A(1,:),A(2,:), '-*');hold on grid on;axis([0 3 0 3]); gtext('變換前');Y = B * A;plot(Y(1,:),Y(2,:), '-r*'); grid on;axis([0 3 0 3]); gtext('變換后');1
從上圖可知,y方向進行了2倍的拉伸,x方向進行了3倍的拉伸,這就是B=[3 0; 0 2]的功勞,3和2就是伸縮比例。請注意,這時B除了對角線元素為各個維度的倍數(shù)外,非正對角線元素都為0,因為下面將要看到,對角線元素非0則將會發(fā)生切變及旋轉的效果。
切變
clf; A = [0, 1, 1, 0, 0;...1, 1, 0, 0, 1]; % 原空間 B1 = [1 0; 1 1]; % 線性變換矩陣 B2 = [1 0; -1 1]; % 線性變換矩陣 B3 = [1 1; 0 1]; % 線性變換矩陣 B4 = [1 -1; 0 1]; % 線性變換矩陣Y1 = B1 * A; Y2 = B2 * A; Y3 = B3 * A; Y4 = B4 * A;subplot(2,2,1); plot(A(1,:),A(2,:), '-*'); hold on;plot(Y1(1,:),Y1(2,:), '-r*'); grid on;axis([-1 3 -1 3]); subplot(2,2,2); plot(A(1,:),A(2,:), '-*'); hold on;plot(Y2(1,:),Y2(2,:), '-r*'); grid on;axis([-1 3 -1 3]); subplot(2,2,3); plot(A(1,:),A(2,:), '-*'); hold on;plot(Y3(1,:),Y3(2,:), '-r*'); grid on;axis([-1 3 -1 3]); subplot(2,2,4); plot(A(1,:),A(2,:), '-*'); hold on;plot(Y4(1,:),Y4(2,:), '-r*'); grid on;axis([-1 3 -1 3]);2
旋轉
所有的變換其實都可以通過上面的伸縮和切變變換的到,如果合理地對變換矩陣B取值,能得到圖形旋轉的效果,如下,
clf; A = [0, 1, 1, 0, 0;...1, 1, 0, 0, 1]; % 原空間 theta = pi/6; B = [cos(theta) sin(theta); -sin(theta) cos(theta)]; Y = B * A; figure; plot(A(1,:),A(2,:), '-*'); hold on;plot(Y(1,:),Y(2,:), '-r*'); grid on;axis([-1 3 -1 3]);3
好,關于矩陣乘就這些了。那么,我們接著就進入主題了,對特定的向量,經(jīng)過一種方陣變換,經(jīng)過該變換后,向量的方向不變(或只是反向),而只是進行伸縮變化(伸縮值可以是負值,相當于向量的方向反向)?這個時候我們不妨將書上對特征向量的定義對照一遍:
數(shù)學教材定義: 設A是n階方陣,如果存在?λ?和n維非零向量X,使??,則?λ?稱為方陣A的一個特征值,X為方陣A對應于或屬于特征值?λ?的一個特征向量。
上面特定的向量不就是特征向量嗎??λ?不就是那個伸縮的倍數(shù)嗎?因此,特征向量的代數(shù)上含義是:將矩陣乘法轉換為數(shù)乘操作;特征向量的幾何含義是:特征向量通過方陣A變換只進行伸縮,而保持特征向量的方向不變。特征值表示的是這個特征到底有多重要,類似于權重,而特征向量在幾何上就是一個點,從原點到該點的方向表示向量的方向。
特征向量有一個重要的性質(zhì):同一特征值的任意多個特征向量的線性組合仍然是A屬于同一特征值的特征向量。關于特征值,網(wǎng)上有一段關于“特征值是震動的譜”的解釋:
戲說在朝代宋的時候,我國就與發(fā)現(xiàn)矩陣特征值理論的機會擦肩而過。話說沒有出息的秦少游在往池塘里扔了一顆小石頭后,剛得到一句“投石沖開水底天”的泡妞詩對之后,就猴急猴急地去洞房了,全然沒有想到水波中隱含著矩陣的特征值及特征向量的科學大道理。大概地說,水面附近的任一點水珠在原處上下振動(實際上在做近似圓周運動),并沒有隨著波浪向外圈移動,同時這些上下振動的水珠的幅度在漸漸變小,直至趨于平靜。在由某塊有著特定質(zhì)量和形狀的石頭被以某種角度和速度投入某個面積和深度特定的水池中所決定的某個矩陣中,紋波蕩漾中水珠的漸變過程中其特征值起著決定性的作用,它決定著水珠振動的頻率和幅度減弱的衰退率。
在理解關于振動的特征值和特征向量的過程中,需要加入復向量和復矩陣的概念,因為在實際應用中,實向量和實矩陣是干不了多少事的。機械振動和電振動有頻譜,振動的某個頻率具有某個幅度;那么矩陣也有矩陣的譜,矩陣的譜就是矩陣特征值的概念,是矩陣所固有的特性,所有的特征值形成了矩陣的一個頻譜,每個特征值是矩陣的一個“諧振頻點”。
美國數(shù)學家斯特讓(G..Strang)在其經(jīng)典教材《線性代數(shù)及其應用》中這樣介紹了特征值作為頻率的物理意義,他說:
大概最簡單的例子(我從不相信其真實性,雖然據(jù)說1831年有一橋梁毀于此因)是一對士兵通過橋梁的例子。傳統(tǒng)上,他們要停止齊步前進而要散步通過。這個理由是因為他們可能以等于橋的特征值之一的頻率齊步行進,從而將發(fā)生共振。就像孩子的秋千那樣,你一旦注意到一個秋千的頻率,和此頻率相配,你就使頻率蕩得更高。一個工程師總是試圖使他的橋梁或他的火箭的自然頻率遠離風的頻率或液體燃料的頻率;而在另一種極端情況,一個證券經(jīng)紀人則盡畢生精力于努力到達市場的自然頻率線。特征值是幾乎任何一個動力系統(tǒng)的最重要的特征。
其實,這個矩陣之所以能形成“頻率的譜”,就是因為矩陣在特征向量所指的方向上具有對向量產(chǎn)生恒定的變換作用:增強(或減弱)特征向量的作用。進一步的,如果矩陣持續(xù)地疊代作用于向量,那么特征向量的就會凸現(xiàn)出來。
更多關于特征向量及特征值的實際例子參見Wikipedia:?http://zh.wikipedia.org/wiki/特征向量?。
特征值分解
設A有n個特征值及特征向量,則:
將上面的寫到一起成矩陣形式:
若(x1,x2,...,xn)可逆,則左右兩邊都求逆,則方陣A可直接通過特征值和特征向量進行唯一的表示,令
Q=(x1,x2,...,xn)
Σ?=?diag(λ1,?λ2,?...,?λn)
則??,該表達式稱為方陣的特征值分解,這樣方陣A就被特征值和特征向量唯一表示。
一個變換方陣的所有特征向量組成了這個變換矩陣的一組基。所謂基,可以理解為坐標系的軸。我們平常用到的大多是直角坐標系,在線性代數(shù)中可以把這個坐標系扭曲、拉伸、旋轉,稱為基變換。我們可以按需求去設定基,但是基的軸之間必須是線性無關的,也就是保證坐標系的不同軸不要指向同一個方向或可以被別的軸組合而成,否則的話原來的空間就“撐”不起來了。從線性空間的角度看,在一個定義了內(nèi)積的線性空間里,對一個N階對稱方陣進行特征分解,就是產(chǎn)生了該空間的N個標準正交基,然后把矩陣投影到這N個基上。N個特征向量就是N個標準正交基,而特征值的模則代表矩陣在每個基上的投影長度。特征值越大,說明矩陣在對應的特征向量上的方差越大,功率越大,信息量越多。不過,特征值分解也有很多的局限,比如說變換的矩陣必須是方陣。
在機器學習特征提取中,意思就是最大特征值對應的特征向量方向上包含最多的信息量,如果某幾個特征值很小,說明這幾個方向信息量很小,可以用來降維,也就是刪除小特征值對應方向的數(shù)據(jù),只保留大特征值方向對應的數(shù)據(jù),這樣做以后數(shù)據(jù)量減小,但有用信息量變化不大,PCA降維就是基于這種思路。
Matlab中通過eig函數(shù)就可求得特征值和特征向量矩陣。
>> B = [ 3 -2 -.9 2*eps-2 4 1 -eps-eps/4 eps/2 -1 0-.5 -.5 .1 1 ] B =3.0000 -2.0000 -0.9000 0.0000-2.0000 4.0000 1.0000 -0.0000-0.0000 0.0000 -1.0000 0-0.5000 -0.5000 0.1000 1.0000>> [V D] = eig(B) V =0.6153 -0.4176 -0.0000 -0.1437-0.7881 -0.3261 -0.0000 0.1264-0.0000 -0.0000 -0.0000 -0.91960.0189 0.8481 1.0000 0.3432 D =5.5616 0 0 00 1.4384 0 00 0 1.0000 00 0 0 -1.0000D對角線的元素即為特征值(表示了伸縮的比例),D就是特征值分解公式中的Q,V的每一列與D沒列對應,表示對應的特征向量,即特征值分解中的Σ。
奇異值分解
特征值分解是一個提取矩陣特征很不錯的方法,但是它只適用于方陣。而在現(xiàn)實的世界中,我們看到的大部分矩陣都不是方陣,比如說有M個學生,每個學生有N科成績,這樣形成的一個M * N的矩陣就可能不是方陣,我們怎樣才能像描述特征值一樣描述這樣一般矩陣呢的重要特征呢?奇異值分解就是用來干這個事的,奇異值分解是一個能適用于任意的矩陣的一種分解的方法。我們有必要先說說特征值和奇異值之間的關系。
對于特征值分解公式,?ATA?是方陣,我們求?ATA?的特征值,即??,此時求得的特征值就對應奇異值的平方,求得的特征向量v稱為右奇異向量,另外還可以得到:
所求的ui就是左奇異向量,?σi?就是奇異值。已有人對SVD的幾何機理做了清晰的分析,非常受用,就不重復造輪子,下文為轉載自http://blog.sciencenet.cn/blog-696950-699432.html?。
SVD分解
SVD之所以很有效,是因為:在很多情況下,前10%甚至1%的奇異值的和就占了全部的奇異值之和的99%以上了。在這里,我們用圖像簡單的實踐一下SVD的大妙處,下面是matlab對圖像進行SVD分解的例子,
<code class="sourceCode matlab" style="margin: 0px; padding: 0.5em; line-height: normal; font-family: Monaco, 'Courier New', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; color: rgb(51, 51, 51); border: none; display: block; background-color: rgb(248, 248, 255); background-position: initial initial; background-repeat: initial initial;">I = imread(<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'lena_gray.bmp'</span>); <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">% 512x512的Lena圖像</span> im = double(I); [s,v,d]=svd(im); <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">% svd分解,svd分解后特征值v對角線按從大到小排列,因此可以選擇特征值大的進行恢復</span> recv1=s(:,<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">20</span>)*v(<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">20</span>,<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">50</span>)*d(:,<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">50</span>)'; <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">% svd取最高的100個特征值進行恢復</span> recv2=s(:,<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">50</span>)*v(<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">50</span>,<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">100</span>)*d(:,<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">100</span>)'; <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">% svd取最高的100個特征值進行恢復</span> recv3=s(:,<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">200</span>)*v(<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">200</span>,<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">200</span>)*d(:,<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">1</span>:<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">200</span>)'; <span class="co" style="margin: 0px; padding: 0px; color: rgb(96, 160, 176); font-style: italic;">% svd取最高的100個特征值進行恢復</span>subplot(<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">221</span>);imshow(I); title(<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'原圖'</span>); subplot(<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">222</span>);imshow(mat2gray(recv1)); title(<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'恢復:左奇異20、右奇異50'</span>); subplot(<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">223</span>);imshow(mat2gray(recv2)); title(<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'恢復:左奇異50、右奇異100'</span>); subplot(<span class="fl" style="margin: 0px; padding: 0px; color: rgb(64, 160, 112);">224</span>);imshow(mat2gray(recv3)); title(<span class="st" style="margin: 0px; padding: 0px; color: rgb(64, 112, 160);">'恢復:左奇異200、右奇異200'</span>);</code>圖注:SVD二維圖像壓縮恢復
如果按左下角的方式壓縮原圖,則存儲量變?yōu)?#xff1a;50x50+100x100+50=12500,而存儲原圖像的存儲量為512x512=262144,則壓縮比為262144/12500=20.97,這里沒有考慮存儲數(shù)據(jù)類型的差異。
SVD分解相對于特征值分解的優(yōu)勢就是:
另外值得注意的一點:不論是奇異值分解還是特征值分解,分解出來的特征向量都是正交的。
奇異值分解與PCA
關于奇異值與PCA的關系,?http://www.cnblogs.com/LeftNotEasy/archive/2011/01/19/svd-and-applications.html?給了很好的解釋,也直接整理過來,感謝原作者:
圖注:SVD與PCA
PCA就是一種用于對數(shù)據(jù)進行降維的方法(降維肯定會丟失數(shù)據(jù),只不過能在減少大量存儲量的同時損失盡可能少),參見之前matlab對圖像進行SVD分解的例子,更容易理解:實現(xiàn)了SVD就實現(xiàn)了PCA,PCA僅是SVD的包裝。
PCA的應用很廣,主要用在機器學習中對特征進行降維,還能用于去噪,下面兩圖是PCA降維和PCA去噪的例子(圖片來自鄒博PPT:北京9月秋季班·機器學習初步)
圖注:PCA降維
降維說白了就是將信息通過投影到更低得多維度,這樣必然會帶來信息的丟失,但就如上圖,這種信息的丟失卻有時對分類沒有影響,反而能降低識別算法的維度,提高速度,緩解所謂的維度災難。
PCA去噪的前提是噪聲的特征值會比信號的特征值小,即信噪比高的情況,否則PCA去噪會產(chǎn)生逆效果——把信號去掉了而噪聲沒去掉。
SVD其它
SVD還有其它很多方面的應用,通過查找資料,這里先做個簡單的羅列,有機會再一個個研究:
另外,開源視覺庫OpenCV中也提供SVD分解的算法。
參考
總結
以上是生活随笔為你收集整理的奇异值(Singular value decomposition SVD)分解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: struct output SVM
- 下一篇: Self-Tuning Spectral