聚類(Clustering)
1.無監督學習:簡介
聚類演算法:第一個無監督學習演算法(無標籤的資料)
什麼是無監督學習呢?
對比:監督學習問題指的是,我們有一系列標籤,然後用假設函式去擬合它,作為對比,在無監督學習中,我們的資料並沒有任何標籤,無監督學習要做的就是將這系列沒有標籤的資料輸入到演算法中,然後我們要讓演算法找到隱含在資料中的結構。例如聚類演算法,當然還有一些其他的無監督學習演算法,而不單單是簇。
在這裡我們有一系列點,卻沒有標籤。因此,我們的訓練集可以寫成只有x^(1), x^(2)….. 一直到x^(m)。我們沒有任何標籤y。因此,圖上畫的這些點沒有標籤資訊。也就是說,在非監督學習中,我們需要將一系列無標籤的訓練資料,輸入到一個演算法中,然後我們告訴這個演算法,快去為我們找找這個資料的內在結構給定資料。我們可能需要某種演算法幫助我們尋找一種結構。圖上的資料看起來可以分成兩個分開的點集(稱為簇),一個能夠找到我圈出的這些點集的演算法,就被稱為聚類演算法。
這將是我們介紹的第一個非監督學習演算法。當然,此後我們還將提到其他型別的非監督學習演算法,它們可以為我們找到其他型別的結構或者其他的一些模式,而不只是簇。
我們將先介紹聚類演算法。此後,我們將陸續介紹其他演算法。那麼聚類演算法一般用來做什麼呢?
在這門課程的早些時候,我曾經列舉過一些應用:比如市場分割。也許你在資料庫中儲存了許多客戶的資訊,而你希望將他們分成不同的客戶群,這樣你可以對不同型別的客戶分別銷售產品或者分別提供更適合的服務。社交網路分析:事實上有許多研究人員正在研究這樣一些內容,他們關注一群人,關注社交網路,例如Facebook,Google+,或者是其他的一些資訊,比如說:你經常跟哪些人聯絡,而這些人又經常給哪些人發郵件,由此找到關係密切的人群。因此,這可能需要另一個聚類演算法,你希望用它發現社交網路中關係密切的朋友。我有一個朋友正在研究這個問題,他希望使用聚類演算法來更好的組織計算機叢集,或者更好的管理資料中心。因為如果你知道資料中心中,那些計算機經常協作工作。那麼,你可以重新分配資源,重新佈局網路。由此優化資料中心,優化資料通訊。
2.K-均值演算法
K-均值是最普及的聚類演算法,演算法接受一個未標記的資料集,然後將資料聚類成不同的組。
K-均值是一個迭代演算法,假設我們想要將資料聚類成n個組,其方法為:
第一步是隨機生成兩點(聚類中心(兩類))
K均值演算法是一個迭代演算法,它會做兩件事,第一件是簇分配,第二個是移動聚類中心。演算法內部每次內迴圈的第一步是要進行簇分配,即我要遍歷圖中的每個綠點,然後根據每個點是與紅色聚類中心更近,還是藍色聚類中心更近,來將每個資料點分配給兩個聚類中心之一。
具體來說
1.遍歷你的資料集
然後將每個點染成紅色或藍色,這取決於點是更接近藍色聚類中心還是紅色聚類中心。
2.移動聚類中心
將兩個聚類中心,也就是紅色和藍色的叉,將其移動到同色的點的均值處,所以接下來要做的是找到所有紅色的點,求出所有紅色點的平均位置,然後把紅色的聚類中心移動到這裡,藍色聚類中心同理。
3.簇分配步驟:
再次檢查所有的無標籤資料,然後根據這些點與紅色還是藍色聚類中心更近,將其塗成藍色或者紅色,再重新分配給紅色或者藍色聚類中心。再計算出所有同色點的平均位置,移動紅色/藍色聚類中心。
4.重複2,3,直到你繼續進行K均值演算法的迭代,聚類中心也不會再改變了,並且點的顏色也不會再改變了。此時,K均值已經聚合了。
更規範的格式寫出K均值演算法:
接受兩個輸出:
1.K,表示你想從資料中聚類處的簇的個數
2.一系列無標籤的只用x表示的資料集(無監督學習,不需要y值)
同時非監督學習的K均值演算法中,約定x^(i)是一個n維實數向量。
K均值聚類演算法要做的事:
第一步是初始化K個聚類中心,記作u1,u2...uK。
簇分配步驟:(1)迭代,用c(i)表示第1到第K個最接近x^(i)的聚類中心(看看它離哪個聚類中心更近一些),將其染成對應的顏色。
(2)移動聚類中心
如果存在一個沒有點的聚類中心會怎麼樣?
這時最常見的做法是直接移除那個聚類中心,並最終得到K-1個簇,而不是K個簇。
K均值演算法另一個常見應用,它可以用來解決分離不佳的簇的問題。
3.優化目標
之前學習的演算法都有一個優化目標函式或者說代價函式,K均值演算法也有一個優化目標函式,或者一個用於最小化的代價函式。
求解這個優化目標函式,一方面是因為這將幫助我們對學習演算法進行除錯,確保K均值演算法執行正確。第二點也是最重要的一點,我們也要運用它幫助K均值演算法找到更好的簇,並且避免區域性最優解。
K均值演算法要做的事情就是它要找打c^(i)和ui,也就是能最小化代價函式J的c和u。這個代價函式有時也叫失真代價函式或者K均值演算法的失真。
K均值演算法實際做的就是,它把兩個系列的變數,把它們分成兩半,第一組是變數c,然後是變數u。首先它會最小化J關於變數c,接著最小化J關於變數u,然後保持迭代。
我們可以用這個是真函式來除錯K均值演算法,並幫助我證明K均值是收斂的,並且能夠正常執行。
如何用這個方法幫助K均值找到更好的簇?以及幫助K均值避免區域性最優解?
4.隨機初始化
如何初始化K均值聚類演算法?如何使演算法避開區域性最優解?
我通常用來初始化K均值聚類的方法是隨機挑選K個訓練樣本 ,然後設定u1到uk,讓它們等於這K個樣本。
上圖才是真正的K均值演算法初始化的方法,在你實現K均值聚類時,最好使用這種方法。即使隨機狀態可能會讓你的演算法最終可能會收斂得到不同的結果,這取決於聚類的初始化狀態,隨機初始化的狀態不同,K均值最後可能會得到不同的結果。
具體而言,K均值演算法可能會落到區域性最優,就不能很好的最小化畸變函式J。如果你擔心K均值演算法落在區域性最優,如果你想讓K均值演算法找到最有可能的聚類,我們可以嘗試多次隨機初始化,並執行K均值演算法很多次,以此來保證我們最終能得到一個足夠好的結果,一個儘可能好的區域性或全域性最優值。
選取執行100次的畸變函式值中最小的那一個!事實證明,如果你執行K均值演算法時,所用的聚類數相當小,那麼多次隨機初始化,通常能夠保證你能找到較好的區域性最優解。保證你能找到更好的聚類。如果K值很大,那麼多次使用K均值演算法就不會有太大改善。
5.選取聚類數量
K均值聚類中如何選擇聚類數量?如何選擇引數K的值?
比較好的方法仍然是通過觀察視覺化的圖,或者通過觀察聚類演算法的輸出等,即比較好的方法是手動選擇聚類的數目。
在無監督學習中,資料沒有標籤,因此並不總是有一個明確的答案。因此,用一個自動化的演算法來選擇聚類數量很困難。
肘部法則:
我們所要做的是改變K,也就是聚類總數,我們先用一個類來聚類,所有的資料都會分到一個類中,然後計算代價函式,即畸變函式J,把它畫出來,然後我們再用兩個類來跑K均值演算法,可能多次隨機初始化,也可能只初始化一次,但是在兩類的情況下,一般畸變值會小一些,然後再畫在這裡。再用三個類來跑K均值聚類,很可能得到一個更小的畸變值,再畫回到圖裡,再用四類五類去跑均值演算法,最終會得到一條曲線顯示隨著聚類數量的增多,畸變值下降的曲線。
肘部法則就是觀察這個圖,可以看到這條曲線有一條肘部,類比於人的肘部。
這將是一種用來選擇聚類個數的合理方法。
但也許沒有清晰的拐點!所以它是一種值得嘗試的方法,但是你不能期望它能解決任何問題。
另外一種,如果下游目標能給你一個評估標準,那麼決定聚類數量更好的方式是看哪個聚類數量能更好地應用於後續目的。
這就給了我們另一種方法去選擇聚類數量,你可以從下游的角度去思考多少個分類能滿足下游要求。
大部分時候聚類數量K仍然是通過手動、人工輸入或者我們的經驗來決定,一種可以嘗試的方法是使用“肘部法則”,但是不能期望每次都有好的效果。選擇聚類數量,更好的思路是問自己,執行K均值聚類的目的是什麼?
聚類參考資料:
降維(Dimensionality Reduction)
6.動機一:資料壓縮
第二種無監督學習問題:降維
你想要使用降維的目的?
一是資料壓縮。資料壓縮不僅能讓我們對資料進行壓縮,使資料佔用更少的記憶體或硬碟空間,它還能讓我們對學習演算法進行加速。
什麼是降維?
cm和英寸作為兩個特徵值,描述的都是物體的長度,存在一定的資料冗餘。如果我們能把資料從二維減少到一維,就能減少這種冗餘。
那麼我們把資料從二維降到一維,究竟意味著什麼?
總結一下:如果允許我們通過投影這條綠線上所有的原始樣本來近似原始的資料集,那麼我只需要一個數就能指定點在直線上的位置,即只用一個數字就可以指定每個訓練樣本的位置。
這樣就能把記憶體(資料空間)的需求減半。這將允許我們讓學習演算法執行的更快,同時這也是資料壓縮中更有趣的一種應用。
從三維降到二維:
這樣的處理過程可以被用於把任何維度的資料降到任何想要的維度,例如將1000維的特徵降至100維。
正如我們所看到的,最後,這將使我們能夠使我們的一些學習演算法執行也較晚,但我們會在以後的視訊提到它。
7.動機二:資料視覺化
降維的第一個應用時壓縮資料
第二個應用就是視覺化資料
它能很好的幫助我們對學習演算法進行優化,讓我們能更好的瞭解我們的資料,幫助我們更好的對資料進行視覺化。
如何視覺化這些資料?
如果你有50維的特徵,你很難繪製50維的資料。怎麼樣才能很好的檢查這些資料呢?
只用一個數字來概述這50個數字!
但是當你觀察降維演算法的輸出時,你會發現z通常不是你所期望的具有物理意義的特徵,我們需要去弄清楚這些特徵是什麼意思?
通過z1和z2能讓你快速捕捉在不同的國家之間兩個維度的變化。
記下來PCA(主成分分析),可以進行降維操作,也可以用來實現我們之前提到的壓縮資料。
8.主成分分析問題
降維問題最常用的演算法叫做主成分分析(PSA)演算法,我們先討論PCA的公式描述(試著用公式準確的表述PCA的用途)
點到投影點的距離比較小!所以PCA所做的是:它會找一個低維平面,然後將資料投影到上面,使藍色線段的平方最短,這些藍色線段的長度被稱為投影誤差。即它會試圖尋找一個投影平面對資料進行投影,使得最小化這個距離。
應用PCA之前,通常需要先進行均值歸一化和特徵規範化,使得特徵x1,x2,其均值為0並且其數值在可比較的範圍之內。
這也是為什麼,主成分分析會選擇紅色的直線而不是洋紅色的直線。
PCA做的就是如果想將資料從二維降到一維,我們要試著找一個向量,假設為u^(i),使得資料投影后,能夠最小化投影誤差的方向。該向量不分正負,因為它定義的是同一條直線。
對於N維降到K維,這時不只是想找單個向量,來對資料進行投影,而是想尋找K個方向,來對資料進行投影,來最小化投影誤差。對於三維向量,即想把所有的資料點投影到這k個向量展開的線性子空間上。
更正式的,我們想要找出能夠最小化投影距離的方式,來對資料進行投影,也就是資料點和投影后的點之間的距離。投影誤差就是該點與二維平面上對應的投影點之間的距離,最小化平方投影。
有點類似於線性迴歸,但PCA不是線性迴歸,儘管有一點相似,但是是兩種不相同的演算法。線性歸回做的是用所有的x值來預測y。在PCA中特徵值都是一樣的,計算的是同等的特徵值x1,x2...xn。
總計一下PCA所做的事:它試圖找到一個低維平面,來對資料進行投影,以便最小化投影誤差的平方,以及最小化每個點與投影后的對應點之間的距離的平方值。
怎麼找到對資料投影的這個低維平面?
9.主成分分析演算法
自主使用主成分分析演算法,並且能夠用PCA對自己的資料進行降維。
在使用PCA之前,首先要做的是進行資料預處理,執行均值標準化,對資料進行特徵縮放(分母sj是特徵j的一些測量值(最大值減去最小值),或者是一個特徵j的標準偏差)
做完PCA的資料預處理以後,我們要去尋找最小化投影距離的向量了(我們需要想出一個方法計算兩個東西,一個是計算這些向量例如u(1),u(2),如何來計算這些資料?):
數學上的證明很複雜。
下面是求解過程,我們想要把n維向量降到k維,我們首先要做的是計算協方差,協方差用∑表示,不用於數學求和公式,它表示的是一個矩陣,如何求解矩陣sigma的特徵向量?
Octave要使用命令svd(),svd代表奇異值分解,這是一個更高階的分解演算法,高階的線性代數應用。eig()函式也可以用來做相同的事,但是svd()函式更穩定。協方差矩陣總是滿足在數學上的一個性質叫做正定矩陣。其他程式語言中也會有類似的線性代數庫求解奇異值矩陣,它得到的是一個nn矩陣。而你真正需要的是U矩陣,這個U矩陣也將是一個nn矩陣,這個矩陣的列就是u^(1), u^(2), u^(3)...等。
所以我們想要減少資料的維數從n維降到k維,我們需要做的就是提取前k個向量,即我們想投影到資料的方向。
接下來從svd線性代數的數值過程中得到了矩陣U S D,我們將用U矩陣的前k個列獲取u(1)-u(k)的向量,一個n*k的矩陣,把它成為Ureduce,這是一類U矩陣被降維的版本,將使用它來對資料進行降維。
接下來計算z!z是k為向量,x將是我們資料集中的例子。
計算矩陣的正確向量化公式:
沒有數學證明,但是因為程式碼量比較少,按照這個步驟進行操作,你的降維演算法是可以執行的很好的。
PCA演算法是嘗試找到一個線或者一個面把資料投影到這個面或者線上以便於最小化平方投影誤差。
10.選擇主成分的數量
怎麼選擇PCA演算法中的k?
我們希望在平均均方誤差與訓練集方差的比例儘可能小的情況下選擇儘可能小的k值。
如果我們希望這個比例小於1%,就意味著原本資料的偏差有99%都保留下來了,如果我們選擇保留95%的偏差,便能非常顯著地降低模型中特徵的維度了。
我們可以先令k=1,然後進行主要成分分析,獲得Ureduce和z,然後計算比例是否小於1%。如果不是的話再令k=2,如此類推,直到找到可以使得比例小於1%的最小k 值(原因是各個特徵之間通常情況存在某種相關性)。
還有一些更好的方式來選擇k,當我們在Octave中呼叫“svd”函式的時候,我們獲得三個引數:[U, S, V] = svd(sigma)。
其中的S是一個n×n的矩陣,只有對角線上有值,而其它單元都是0,我們可以使用這個矩陣來計算平均均方誤差與訓練集方差的比例。
在壓縮過資料後,我們可以採用如下方法來近似地獲得原有的特徵:
11.重建的壓縮表示
之前把1000維降維到100維的特徵向量,如果這是一個壓縮方法,那麼對應應該有一種近似表示,可以把壓縮的資料回到原來的表示:
即原始資料的重構:
12.主成分分析法的應用建議
如何選擇K,如何選擇低維表示z的維度?
降低維數可以提高演算法的運算效率,如何具體去做PCA的一些具體建議?
在計算機視覺中,你有100*100個畫素點,如果x^(i)特徵向量包含10000個畫素強度值,這就是10000維的特徵向量。對於這種高維的特徵向量,執行學習演算法將變得非常緩慢。如果你要使用10000維的特徵向量進行logistic迴歸,或者輸入神經網路,或支援向量機,或其他你想要的操作,因為資料太大,包含10000個數字,將會是你的演算法執行的非常慢,幸運的是,用PCA演算法,可以減少資料的維度,從而使演算法執行的更加高效。首先檢查已經被標記的訓練集,並抽取輸入,抽取出這些x,把y先臨時放到一邊,就得到了一個無標籤的訓練集。10000維的樣本,僅僅抽取了輸入的向量,接著用PCA得到原始資料的低維表示,變成了1000維。這就給了我們一個新的訓練集,一個新的訓練樣本,可以把這個低維的訓練樣本輸入可能是神經網路或者是迴歸演算法。對於一個新樣本,也是通過PCA演算法進行轉換後輸入到學習演算法中。
最後注意一點:PCA所做的是定義一個從x到z的對映,這個對映只能通過在訓練集上執行PCA來定義,具體而言,PCA學習的這個對映所做的就是計算一系列引數,進行特徵縮放和均值歸一化,它還計算Ureduce。
但我們應該只在訓練集上擬合這些引數,而不是交叉驗證集或者是測試集上。在訓練集上找到這些引數後,你可以把這個對映用在交叉驗證集或者測試集上的其他樣本上。
總結一下:當執行PCA時,僅僅在訓練集上的資料上執行,不能用在交叉訓練集和測試集資料上,定義了x到z的對映後,可以將這個對映用在交叉驗證集或者測試集上的其他樣本上。
總而言之,我們討論了PCA演算法的以下應用:
壓縮資料
加速學習演算法
選擇k:需要保留99%的方差
視覺化應用
此外,有一種常見的對PCA演算法的誤用。(嘗試使用PCA去防止過擬合)
通過減少資料維度來解決過擬合不是一種很好的方式,相比於正則化。
它會扔掉一部分特徵,轉換為無標籤資料,所以即使99%方差資訊被保留,它也有可能扔掉了一些有用資訊。
使用PCA的比較好的方式是使用它來提高演算法的運算速度,但是使用PCA防止過擬合不是一個好應用,應該使用正則化來防止過擬合。
濫用問題:
有些人在設計機器學習系統的時候,可能會寫下這樣一個計劃:
建議:應該首先考慮使用最原始的資料x(i),只有這麼做不能達到目的的情況下,才考慮使用PCA和z(i),因此使用PCA之間,與其考慮減少資料維度,不如考慮放棄PCA這一步,在原始資料上直接訓練演算法往往是更好的。只有當你的演算法執行速度很慢,或記憶體不足,或硬碟空間太大,因此你需要去壓縮資料表示,即有強有力的證據證明x(i)不能有效的工作再用PCA。