<機器學習>無監督學習算法總結


  本文僅對常見的無監督學習算法進行了簡單講述,其他的如自動編碼器,受限玻爾茲曼機用於無監督學習,神經網絡用於無監督學習等未包括。同時雖然整體上分為了聚類和降維兩大類,但實際上這兩類並非完全正交,很多地方可以相互轉化,還有一些變種的算法既有聚類功能又有降維功能,一些新出現的和尚在開發創造中的無監督學習算法正在打破聚類和降維的類別划分。另外因時間原因,可能有個別小錯誤,如有發現還望指出。

一.聚類(clustering)

1.k-均值聚類(k-means)

  這是機器學習領域除了線性回歸最簡單的算法了。該算法用來對n維空間內的點根據歐式距離遠近程度進行分類。

  INPUT:

    K(number of clusters)

    Training set{x1,x2,x3,....xn} (xi belongs to R^n)

  OUTPUT:

    K個聚類中心

  算法工作原理摘要:

  

   自己手寫的python實現K—means:

#簇數為k
#數據空間維度為n
#訓練集元素數為m
def
K_means_demo(k,n,m): clusters=np.random.randint(0,40,size=[k,n]) #隨機生成聚類中心 tr_set=np.random.randint(0,40,size=[m,n]) #因為是模擬,所以自己隨機生成的數據集for iter in range(0,5): clu_asist=np.zeros(shape=[k,n],dtype=int) for i in range(0,m): #遍歷訓練集內每個樣本 min=9999999 owner=0 for j in range(0,k): #遍歷所有聚心找到最近的聚心owner dis=0 for p in range(0,n): abso =tr_set[i][p] - clusters[j][p] dis+=abso*abso #dis為第i個元素和第j個聚心的歐式距離的平方 if dis-min < 0: min=dis owner=j for p in range(0,n): #漸進更新均值 clu_asist[owner][p]+=(tr_set[i][p]-clu_asist[owner][p])//(p+1) clusters=clu_asist
  return clusters

在上面的代碼中我手動設定了迭代更新次數為5,因為我做的demo規模比較小,迭代幾次便收斂了,而在實際使用中一般用( 迭代次數 || EarlyStop )作為迭代終止條件。

  動畫演示:

 

通讀本算法,可以發現k-means對聚心初始值非常敏感,如果初始情況不好會震盪的。這里可以采取一些措施預判聚心大致要在哪個位置,然后直接將其初始化。

另外,關於收斂的判斷,可以采取多種方法。比如使用代價函數,或者F-Measure和信息熵方法。

K-means優缺點分析:

- 優點: 算法簡單易實現; 

- 缺點: 需要用戶事先指定類簇個數; 聚類結果對初始類簇中心的選取較為敏感; 容易陷入局部最優; 只能發現球形類簇。

 

2.層次聚類(Hierarchical Clustering)

  顧名思義,層次聚類就是一層一層地進行聚類。既可以由下向上對小的類別進行聚合(凝聚法),也可以由上向下對大的類別進行分割(分裂法)。在應用中,使用較多的是凝聚法。

  INPUT:training_set D,聚類數目或者某個條件(一般是樣本距離的閾值)

  OUTPUT:聚類結果

  凝聚法:

  跟競賽中經常出現的並查集問題略相似,凝聚法指的是先將每個樣本當做一個類簇,然后依據某種規則合並這些初始的類簇,直到達到某種條件或者減少到設定的簇數。

  在算法迭代中每次均選取類簇距離最小的兩個類簇進行合並。關於類簇距離的計算表示方法主要有以下幾種:

  (1)取兩個類中距離最小的兩個樣本的距離作為兩個集合的距離

  (2)取兩個類中距離最大的兩個樣本的距離作為兩個集合的距離

  (3)計算兩個集合中每兩兩點的距離並取平均值,這種方法要略費時

  (4)比(3)輕松一些,取這些兩兩點距的中位數

  (5)求每個集合中心點,然后以中心點代表集合來計算集合距離

  (6)......

  迭代會在簇數減少到設定數量時結束,當然,如果設定了閾值f,那么當存在兩個距離小於f的集合時則會繼續迭代直到不存在這樣的兩個集合。

  分裂法:

  首先將所有樣本歸類到一個簇,然后依據某種規則逐漸分裂,直到達到某種條件或者增加到設定的簇數。

  (手寫再拍照真不容易QAQ)

  

 層次聚類和K-means作比較:

  (1)K-means時間復雜度為O(N),而層次聚類時間復雜度為O(N^2),所以分層聚類不能很好地處理大批量數據,而k-means可以。

  (2)K-means不允許嘈雜數據,而層次聚類可以直接使用嘈雜數據集進行聚類

  (3)當聚類形狀為超球形(如2D圓形,3D球形)時,k-means聚類效果更好。

3.基於密度聚類Mean Shift

  mean shift這種基於核函數估計的爬山算法不僅可以用於聚類,也可用於圖像分割與目標跟蹤等。這個概念早在1975年就被Fukunaga等人提出,而后1998年Bradski將其用於人臉跟蹤則使得其優勢大大體現出來。我們這里只談論作為聚類算法的mean shift。

    什么是漂移向量?

  給定n維空間內數據點集X與中心點x,並以D表示數據集中與中心點x距離小於半徑h的點的集合,則漂移向量Mh表示為: Mh =Exi∈D[xi-x]  。

    什么是漂移操作?

  計算得到漂移向量后將中心位置更新一下,使得中心位置始終處於力的平衡位置。更新公式為: x ← x + Mh   。

  另外,mean shift用於聚類時一般不使用核函數,如果用了核函數,權重改變,就不是“均值”漂移了。

  均值飄移算法實現過程:

    1.在未被標記的點中隨機選取一個點作為起始中心點center;

    2.找出以center為中心半徑為h的空間內所有的點,記作集合D,認為這些點歸屬於類簇c。同時將這些點屬於這個類的概率加1,這個參數將用於最后步驟的分類;

    3.計算D內數據點與中心點center的漂移向量Mh

    4.進行漂移操作x ← x + M ;

    5.重復步驟2.3.4直到迭代收斂,記下此時的center位置。在這一過程中遇到的點都歸類到簇c;

    6.如果收斂時當前簇c的center與其它已存在的簇c‘中心的距離小於閾值,則合並c和c'。否則,把c作為新的聚類,增加1類;

    7.重復步驟1-6直到所有的數據點都被標記訪問;

    8.分類:根據每個類對每個點的訪問頻率,取頻率最大的類作為當前點集的所屬類。

  shift mean跟k-means作比較,兩者都用集合內點的均值進行中心點移動,不同的是shift mean可以自行決定類簇數。

4.基於密度聚類DBSCAN

  DBSCAN:“深度學習的神經網絡,比你們用了幾十年的k-means不知道高到哪里去了,我跟他談笑風生。”  (手動滑稽)DBSCAN可能是聚類領域最迷的算法了,它可以發現任何形狀的簇,而且實現簡單易懂。至於是誰首先提出的我也不曉得了,就不給各位普及歷史了emmm,以下是一段抄來的介紹:DBSCAN(Density-Based Spatial Clustering of Applications with Noise,具有噪聲的基於密度的聚類方法)是一種基於密度的空間聚類算法。 該算法將具有足夠密度的區域划分為簇,並在具有噪聲的空間數據庫中發現任意形狀的簇,它將簇定義為密度相連的點的最大集合。

  INPUT:Training_set D,半徑Eps,密度閾值MinPts

  OUTPUT:類簇clusters

  DBSCAN需要兩個參數即掃描半徑Eps與最小包含點數MinPts。掃描半徑是最難選定的了,會對結果有較大影響。可以用k距離做大量試驗來觀察,找到突變點。一般很難一次性選准,還是要做大量實驗。MinPts可以理解為標題中的“密度”,一般這個值都是偏小一些,然后進行多次嘗試。根據這兩個參數可將樣本中的點分為三類:

    <1>核點(core point) 若樣本 x_i的 \varepsilon鄰域內至少包含了MinPts個樣本,即 N_{\varepsilon }(X_i)\geq MinPts,則稱樣本點 x_i為核心點。

    <2>邊界點(Border point) 若樣本 x_i的 \varepsilon鄰域內包含的樣本數目小於MinPts,但是它在其他核心點的鄰域內,則稱樣本點 x_i為邊界點。

    <3>噪音點(Noise)。既不是核心點也不是邊界點的點。

  偽代碼:

(這一段copy自他人博客)
(1) 首先將數據集D中的所有對象標記為未處理狀態 (2) for(數據集D中每個對象p) do (3) if (p已經歸入某個簇或標記為噪聲) then (4) continue; (5) else (6) 檢查對象p的Eps鄰域 NEps(p) ; (7) if (NEps(p)包含的對象數小於MinPts) then (8) 標記對象p為邊界點或噪聲點; (9) else (10) 標記對象p為核心點,並建立新簇C, 並將p鄰域內所有點加入C (11) for (NEps(p)中所有尚未被處理的對象q) do (12) 檢查其Eps鄰域NEps(q),若NEps(q)包含至少MinPts個對象,則將NEps(q)中未歸入任何一個簇的對象加入C; (13) end for (14) end if (15) end if (16) end for

  動畫演示:

  

  

5.高斯混合模型(GMM)與EM

  針對GMM,一般采用EM算法進行聚類。這里的“高斯”在二維時便是正態分布,高斯混合模型是對高斯模型進行簡單的擴展,GMM使用多個高斯分布的組合來刻畫數據分布。因為GMM含有隱變量ak,所以要采用含有隱變量模型參數的極大似然估計法即EM算法。EM比前面所講算法均要復雜。

  直接求解極大似然函數極值對應的參數比較困難,因此采用迭代逐步近似極大似然函數。首先要獲得似然函數L(θ)的一個下限,然后逐步極大化這個下限便可近似獲得極大似然函數的極值以及對應的參數。

  似然函數      ,其中Z是隱變量

  根據Jensen不等式L(θ)B(θ,θi,獲得L(θ)的下限

  可見,每次迭代時最大化B(θ,θi)即可逐漸逼近似然函數極大值,進一步化簡,極大化B(θ,θi)也就是極大化Q(θ,θi)

  這里的Q函數便是整個EM算法的核心。其意義是logP(Y,Z|θ)logP(Y,Z|θ)關於P(Z|Y,θi)P(Z|Y,θi)的期望。

  結合上面所講,EM算法可以分為交替進行的兩部分:

    E-step:計算Q函數

    M-step:求Q函數最大值,並得到相應參數θ

  為防止落入局部最優,需要多次迭代。

  算法流程:

       

  因為沒怎么用過這個算法,只是有所了解,所以抱歉沒法給出更具體詳細的實現與改進歷史。有興趣的話可以自行google

 

6.基於圖論聚類

(沒學這個,學完再給補上)

二.降維(demensionality reduction)

1.主成分分析(PCA)

  它算是出現最多的降維算法了吧。goodfellow的《深度學習》中對PCA講解太籠統了,可能很多人看不明白,下面我會盡量直白地說。

  PCA在1901年由pearson提出,1933年hotelling對PCA做了改進推廣。指的是將n維特征映射到k維上(k<n),通過正交變換將一組可能存在相關性的變量數據轉換為一組線性不相關的變量,轉換后的變量被稱為主成分。PCA可看作一個端到端的算法。

  下圖是一個f:3D->2D的PCA演示

  

  INPUT:原始維度n,目標維度k,無標簽訓練集D

  OUTPUT:轉換矩陣M

  具體操作時可以采用特征值分解和奇異值分解兩種手段,這里選取了特征值分解,奇異值分解下一個算法會講到。

  操作步驟:

  <1>數據中心化處理。求D中所有樣本的均值xaverage ,並將D中每個樣本減去xaverage 得到數據集A

  <2>求得A的協方差矩陣C

  <3>求取矩陣C的特征值以及對應的特征向量

  <4>對特征值按照由大到小順序排列,選取其中前k大的,然后將其對應的k個特征向量分別作為列向量組成特征向量矩陣E

  <5>將樣本點投影到目標空間上,Target=ET * A      ;ET便是要求的轉換矩陣

  關於為什么PCA要這樣操作,為什么這樣操作有效,可以參考以下三個理論:最大方差理論、最小錯誤理論和坐標軸相關度理論。

  討論與總結:

  PCA技術一大優點與特色是:它完全沒有參數限制。在PCA的計算過程中完全不需要人為的設定參數或是根據任何經驗模型對計算進行干預,最后的結果只與數據相關。

  PCA可以用來進行數據壓縮,例如100維的向量最后可以用10維來表示,那么壓縮率為90%。另外圖像處理領域的KL變換使用PCA做圖像壓縮,人臉檢測和匹配。有一個基於PCA實現的特征人臉分析算法,感興趣的朋友可以查查看。

2.獨立成分分析(ICA)

  獨立成分分析並不算嚴格意義上的降維算法,但它和PCA有着千絲萬縷的聯系,所以將它放在了PCA后面簡單介紹一下。

  首先看一個經典的雞尾酒宴會問題(cocktail party problem)。假設在party中有n個人,他們可以同時說話,我們也在房間中一些角落里共放置了n個microphone用來記錄聲音。宴會過后,我們從n個麥克風中得到了一組數據clip_image002,i表示采樣的時間順序,也就是說共采集到了m組n維的樣本。我們的目標是單單從這m組采樣數據中分辨出每個人說話的信號。

  細化一下,有n個信號源clip_image004clip_image006,每一維都是一個人的聲音信號,每個人發出的聲音信號獨立。A是一個未知的混合矩陣(mixing matrix),用來組合疊加信號s,那么        clip_image008   ,其中x 和s均是矩陣而非向量。表示成圖就是:

  

   clip_image035的每個分量都由clip_image037的分量線性表示。A和s都是未知的,x是已知的,我們要根據x來推出s。也就是進行盲信號分離。

   令clip_image039,那么clip_image041

       將W表示成

       clip_image042

       其中clip_image044,其實就是將clip_image046寫成行向量形式。那么得到:

       clip_image048

  迭代求出W,便可得到clip_image114來還原出原始信號。

 

 下面是一個實例:

 

    信號還原結果:

 

3.奇異值分解(SVD)

  

4.t-分布領域嵌入式算法(t-SNE)

  第一次見到是在斯坦福cs231的課上,當時那位前輩語速奇快,跟《社交網絡》里扎克伯格語速有得一拼。。。。

  t-SNE的前身是2002年提出的SNE算法,2008年Laurens van der Maaten 和 Geoffrey Hinton在SNE基礎上又提出t-SNE算法。作為一種非線性降維算法,非常適用於高維數據降到2-3維,進行可視化。日常工作中,涉及到數據可視化的時候一般都會想到去使用這個工具,因此在圖像領域應用較多。另外在NLP,基因組數據和語音處理領域也應用廣泛。   t-SNE太強了QAQ(再次手動滑稽) 。時間復雜度為O(N^2)。

  t-SNE首先將距離轉換為條件概率來表達點與點之間的相似度,距離通過歐式距離算得,S( x^i , x^j )表示求 x^i,x^j 之間的歐式距離。計算高維原始數據與降維后數據的公式如下

 

  計算完X數據之間的的概率P( x^j|x^i )和Z數據之間的概率Q( z^j | z^i )之后,接下來就是我們 的目的就是P和Q連個分布盡可能的接近,也就是要是如下公式的KL散度盡可能小:

 

  t-SNE和PCA的簡單比較:(以下摘自gaotihong的文章)

from sklearn.manifold import TSNE
from sklearn.datasets import load_iris,load_digits
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import os
 
digits = load_digits()
X_tsne = TSNE(n_components=2,random_state=33).fit_transform(digits.data)
X_pca = PCA(n_components=2).fit_transform(digits.data)
 
ckpt_dir="images"
if not os.path.exists(ckpt_dir):
    os.makedirs(ckpt_dir)
 
plt.figure(figsize=(10, 5))
plt.subplot(121)
plt.scatter(X_tsne[:, 0], X_tsne[:, 1], c=digits.target,label="t-SNE")
plt.legend()
plt.subplot(122)
plt.scatter(X_pca[:, 0], X_pca[:, 1], c=digits.target,label="PCA")
plt.legend()
plt.savefig('images/digits_tsne-pca.png', dpi=120)
plt.show()

  實驗結果:

 

  若想進一步研究t-SNE,可參考:

  (1)http://www.datakit.cn/blog/2017/02/05/t_sne_full.html#11%E5%9F%BA%E6%9C%AC%E5%8E%9F%E7%90%86

  (2)Visualizing data using t-SNE, by Van Der Maaten L,Hinton G

 

  

  

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM