Infi-chu:
http://www.cnblogs.com/Infi-chu/
一、簡介
1.聚類算法的應用領域
- 用戶畫像,廣告推薦,Data Segmentation,搜索引擎的流量推薦,惡意流量識別
- 基於位置信息的商業推送,新聞聚類,篩選排序
- 圖像分割,降維,識別;離群點檢測;信用卡異常消費;發掘相同功能的基因片段
2.聚類算法
一種典型的無監督學習算法,主要用於將相似的樣本自動歸到一個類別中。
在聚類算法中根據樣本之間的相似性,將樣本規划到不同的類別中,對於不同的相似度計算方法,會得到不同的聚類結果。
3.聚類算法與分類算法的區別
聚類算法是無監督學習算法,
分類算法屬於監督學習算法。
二、聚類算法api
1.api
sklearn.cluster.KMeans(n_clusters=8)
- 參數:
- n_clusters:開始的聚類中心數量
- 整型,缺省值=8,生成的聚類數,即產生的質心(centroids)數。
- n_clusters:開始的聚類中心數量
- 方法:
- estimator.fit(x)
- estimator.predict(x)
- estimator.fit_predict(x)
- 計算聚類中心並預測每個樣本屬於哪個類別,相當於先調用fit(x),然后再調用predict(x)
三、聚類算法實現流程
1.步驟
- 隨機設置K個特征空間內的點作為初始的聚類中心
- 對於其他每個點計算到K個中心的距離,未知的點選擇最近的一個聚類中心點作為標記類別
- 重新計算每個聚類的新中心(平均值)
- 如果計算得出的新中心與原點中心一樣(質心不在移動),則結束,否則重新進行第二步的過程
2.總結
流程:
- 事先確定常數K,常數K意味着最終的聚類類別數;
- 首先隨機選定初始點為質心,並通過計算每一個樣本與質心之間的相似度(這里為歐式距離),將樣本點歸到最相似的類中,
- 接着,重新計算每個類的質心(即為類中心),重復這樣的過程,直到質心不再改變,
- 最終就確定了每個樣本所屬的類別以及每個類的質心。
注意:
- 由於每次都要計算所有的樣本與每一個質心之間的相似度,故在大規模的數據集上,K-Means算法的收斂速度比較慢。
四、模型評估
1.誤差平方和(SSE\The sum of squares due to error)
eg.
如圖中數據(-0.2,0.4,-0.8,1.3-0.7,均為真實值和預測值的差)
在K-means中的應用:
公式各部分內容:
【注】
上圖中: k=2
- SSE圖最終的結果,對圖松散度的衡量.(eg: SSE(左圖)<SSE(右圖))
- SSE隨着聚類迭代,其值會越來越小,直到最后趨於穩定
- 如果質心的初始值選擇不好,SSE只會達到一個不怎么好的局部最優解.
2.“肘”方法(Elbow method)——K值確定
(1)對於n個點的數據集,迭代計算k from 1 to n,每次聚類完成后計算每個點到其所屬的簇中心的距離的平方和;
(2)平方和是會逐漸變小的,直到k==n時平方和為0,因為每個點都是它所在的簇中心本身。
(3)在這個平方和變化過程中,會出現一個拐點也即“肘”點,下降率突然變緩時即認為是最佳的k值。
在決定什么時候停止訓練時,肘形判據同樣有效,數據通常有更多的噪音,在增加分類無法帶來更多回報時,我們停止增加類別。
3.輪廓系數法(Silhouette Coefficient)
結合了聚類的凝聚度(Cohesion)和分離度(Separation),用於評估聚類的效果:
目的:
內部距離最小化,外部距離最大化
計算樣本i到同簇其他樣本的平均距離ai,ai 越小樣本i的簇內不相似度越小,說明樣本i越應該被聚類到該簇。
計算樣本i到最近簇Cj 的所有樣本的平均距離bij,稱樣本i與最近簇Cj 的不相似度,定義為樣本i的簇間不相似度:bi =min{bi1, bi2, ..., bik},bi越大,說明樣本i越不屬於其他簇。
求出所有樣本的輪廓系數后再求平均值就得到了平均輪廓系數。
平均輪廓系數的取值范圍為[-1,1],系數越大,聚類效果越好。
簇內樣本的距離越近,簇間樣本距離越遠
eg.
下圖是500個樣本含有2個feature的數據分布情況,我們對它進行SC系數效果衡量:
n_clusters = 2 The average silhouette_score is : 0.7049787496083262
n_clusters = 3 The average silhouette_score is : 0.5882004012129721
n_clusters = 4 The average silhouette_score is : 0.6505186632729437
n_clusters = 5 The average silhouette_score is : 0.56376469026194
n_clusters = 6 The average silhouette_score is : 0.4504666294372765
n_clusters 分別為 2,3,4,5,6時,SC系數如下,是介於[-1,1]之間的度量指標:
每次聚類后,每個樣本都會得到一個輪廓系數,當它為1時,說明這個點與周圍簇距離較遠,結果非常好,當它為0,說明這個點可能處在兩個簇的邊界上,當值為負時,暗含該點可能被誤分了。
從平均SC系數結果來看,K取3,5,6是不好的,那么2和4呢?
k=2的情況:
k=4的情況:
n_clusters = 2時,第0簇的寬度遠寬於第1簇;
n_clusters = 4時,所聚的簇寬度相差不大,因此選擇K=4,作為最終聚類個數。
4.CH系數(Calinski-Harabasz Index)
Calinski-Harabasz:
類別內部數據的協方差越小越好,類別之間的協方差越大越好(換句話說:類別內部數據的距離平方和越小越好,類別之間的距離平方和越大越好),
這樣的Calinski-Harabasz分數s會高,分數s高則聚類效果越好。
tr為矩陣的跡, Bk為類別之間的協方差矩陣,Wk為類別內部數據的協方差矩陣;
m為訓練集樣本數,k為類別數。
使用矩陣的跡進行求解的理解:
矩陣的對角線可以表示一個物體的相似性
在機器學習里,主要為了獲取數據的特征值,那么就是說,在任何一個矩陣計算出來之后,都可以簡單化,只要獲取矩陣的跡,就可以表示這一塊數據的最重要的特征了,這樣就可以把很多無關緊要的數據刪除掉,達到簡化數據,提高處理速度。
CH需要達到的目的:
用盡量少的類別聚類盡量多的樣本,同時獲得較好的聚類效果。
5.總結
1. 肘部法
下降率突然變緩時即認為是最佳的k值
2. SC系數
取值為[-1, 1],其值越大越好
3. CH系數
分數s高則聚類效果越好
五、算法優化
1.k-means算法優點
1.原理簡單(靠近中心點),實現容易
2.聚類效果中上(依賴K的選擇)
3.空間復雜度o(N),時間復雜度o(IKN)
【注】
N個樣本點個數,K個中心點個數,I為迭代次數
2.k-means算法缺點
1.對離群點,噪聲敏感 (中心點易偏移)
2.很難發現大小差別很大的簇及進行增量計算
3.結果不一定是全局最優,只能保證局部最優(與K的個數及初值選取有關)
3.Canopy算法配合初始聚類
(1)流程
(2)Canopy優缺點
優點:
1.Kmeans對噪聲抗干擾較弱,通過Canopy對比,將較小的NumPoint的Cluster直接去掉有利於抗干擾。
2.Canopy選擇出來的每個Canopy的centerPoint作為K會更精確。
3.只是針對每個Canopy的內做Kmeans聚類,減少相似計算的數量。
缺點:
1.算法中 T1、T2的確定問題 ,依舊可能落入局部最優解
4.K-means++
kmeans++目的,讓選擇的質心盡可能的分散
如下圖中,如果第一個質心選擇在圓心,那么最優可能選擇到的下一個點在P(A)這個區域(根據顏色進行划分)
5.二分K-means
實現流程:
-
1.所有點作為一個簇
-
2.將該簇一分為二
-
3.選擇能最大限度降低聚類代價函數(也就是誤差平方和)的簇划分為兩個簇。
-
4.以此進行下去,直到簇的數目等於用戶給定的數目k為止。
隱含的一個原則
因為聚類的誤差平方和能夠衡量聚類性能,該值越小表示數據點越接近於他們的質心,聚類效果就越好。所以需要對誤差平方和最大的簇進行再一次划分,因為誤差平方和越大,表示該簇聚類效果越不好,越有可能是多個簇被當成了一個簇,所以我們首先需要對這個簇進行划分。
二分K均值算法可以加速K-means算法的執行速度,因為它的相似度計算少了並且不受初始化問題的影響,因為這里不存在隨機點的選取,且每一步都保證了誤差最小
6.K-medoids(k-中心聚類算法)
K-medoids和K-means是有區別的,不一樣的地方在於中心點的選取
-
K-means中,將中心點取為當前cluster中所有數據點的平均值,對異常點很敏感!
-
K-medoids中,將從當前cluster 中選取到其他所有(當前cluster中的)點的距離之和最小的點作為中心點。
算法流程:
( 1 )總體n個樣本點中任意選取k個點作為medoids
( 2 )按照與medoids最近的原則,將剩余的n-k個點分配到當前最佳的medoids代表的類中
( 3 )對於第i個類中除對應medoids點外的所有其他點,按順序計算當其為新的medoids時,代價函數的值,遍歷所有可能,選取代價函數最小時對應的點作為新的medoids
( 4 )重復2-3的過程,直到所有的medoids點不再發生變化或已達到設定的最大迭代次數
( 5 )產出最終確定的k個類
k-medoids對噪聲魯棒性好。
例:當一個cluster樣本點只有少數幾個,如(1,1)(1,2)(2,1)(1000,1000)。其中(1000,1000)是噪聲。如果按照k-means質心大致會處在(1,1)(1000,1000)中間,這顯然不是我們想要的。這時k-medoids就可以避免這種情況,他會在(1,1)(1,2)(2,1)(1000,1000)中選出一個樣本點使cluster的絕對誤差最小,計算可知一定會在前三個點中選取。
k-medoids只能對小樣本起作用,樣本大,速度就太慢了,當樣本多的時候,少數幾個噪音對k-means的質心影響也沒有想象中的那么重,所以k-means的應用明顯比k-medoids多。
7.Kernel K-means
kernel k-means實際上,就是將每個樣本進行一個投射到高維空間的處理,然后再將處理后的數據使用普通的k-means算法思想進行聚類。
8.ISODATA
類別數目隨着聚類過程而變化;
對類別數會進行合並,分裂,
“合並”:(當聚類結果某一類中樣本數太少,或兩個類間的距離太近時)
“分裂”(當聚類結果中某一類的類內方差太大,將該類進行分裂)
9.Mini Batch K-means
適合大數據的聚類算法
大數據量是什么量級?通常當樣本量大於1萬做聚類時,就需要考慮選用Mini Batch K-Means算法。
Mini Batch KMeans使用了Mini Batch(分批處理)的方法對數據點之間的距離進行計算。
Mini Batch計算過程中不必使用所有的數據樣本,而是從不同類別的樣本中抽取一部分樣本來代表各自類型進行計算。由於計算樣本量少,所以會相應的減少運行時間,但另一方面抽樣也必然會帶來准確度的下降。
該算法的迭代步驟有兩步:
(1)從數據集中隨機抽取一些數據形成小批量,把他們分配給最近的質心
(2)更新質心
與Kmeans相比,數據的更新在每一個小的樣本集上。對於每一個小批量,通過計算平均值得到更新質心,並把小批量里的數據分配給該質心,隨着迭代次數的增加,這些質心的變化是逐漸減小的,直到質心穩定或者達到指定的迭代次數,停止計算。
10.總結
優化方法 | 思路 |
---|---|
Canopy+kmeans | Canopy粗聚類配合kmeans |
kmeans++ | 距離越遠越容易成為新的質心 |
二分k-means | 拆除SSE最大的簇 |
k-medoids | 和kmeans選取中心點的方式不同 |
kernel kmeans | 映射到高維空間 |
ISODATA | 動態聚類 |
Mini-batch K-Means | 大數據集分批聚類 |
六、特征工程——特征降維
1.降維
降維是指在某些限定條件下,降低隨機變量(特征)個數,得到一組“不相關”主變量的過程
- 降低隨機變量的個數
- 相關特征(correlated feature)
- 相對濕度與降雨量之間的相關
2.降維的兩種方式
- 特征選擇
- 主成分分析(可以理解一種特征提取的方式)
3.特征選擇
數據中包含冗余或無關變量(或稱特征、屬性、指標等),旨在從原有特征中找出主要特征。
4.特征選擇方法
- Filter(過濾式):主要探究特征本身特點、特征與特征和目標值之間關聯
- 方差選擇法:低方差特征過濾
- 相關系數
- Embedded (嵌入式):算法自動選擇特征(特征與目標值之間的關聯)
- 決策樹:信息熵、信息增益
- 正則化:L1、L2
- 深度學習:卷積等
5.低方差特征過濾
刪除低方差的一些特征,前面講過方差的意義。再結合方差的大小來考慮這個方式的角度。
- 特征方差小:某個特征大多樣本的值比較相近
- 特征方差大:某個特征很多樣本的值都有差別
API:
sklearn.feature_selection.VarianceThreshold(threshold = 0.0)
- 刪除所有低方差特征
- Variance.fit_transform(X)
- X:numpy array格式的數據[n_samples,n_features]
- 返回值:訓練集差異低於threshold的特征將被刪除。默認值是保留所有非零方差特征,即刪除所有樣本中具有相同值的特征。
eg.
# 有如下特征 pe_ratio,pb_ratio,market_cap,return_on_asset_net_profit,du_return_on_equity,ev,earnings_per_share,revenue,total_expense index,pe_ratio,pb_ratio,market_cap,return_on_asset_net_profit,du_return_on_equity,ev,earnings_per_share,revenue,total_expense,date,return 0,000001.XSHE,5.9572,1.1818,85252550922.0,0.8008,14.9403,1211444855670.0,2.01,20701401000.0,10882540000.0,2012-01-31,0.027657228229937388 1,000002.XSHE,7.0289,1.588,84113358168.0,1.6463,7.8656,300252061695.0,0.326,29308369223.2,23783476901.2,2012-01-31,0.08235182370820669 2,000008.XSHE,-262.7461,7.0003,517045520.0,-0.5678,-0.5943,770517752.56,-0.006,11679829.03,12030080.04,2012-01-31,0.09978900335112327 3,000060.XSHE,16.476,3.7146,19680455995.0,5.6036,14.617,28009159184.6,0.35,9189386877.65,7935542726.05,2012-01-31,0.12159482758620697 4,000069.XSHE,12.5878,2.5616,41727214853.0,2.8729,10.9097,81247380359.0,0.271,8951453490.28,7091397989.13,2012-01-31,-0.0026808154146886697
分析:
- 初始化VarianceThreshold,指定閥值方差
- 調用fit_transform
def variance_demo(): """ 刪除低方差特征——特征選擇 :return: None """ data = pd.read_csv("factor_returns.csv") print(data) # 1、實例化一個轉換器類 transfer = VarianceThreshold(threshold=1) # 2、調用fit_transform data = transfer.fit_transform(data.iloc[:, 1:10]) print("刪除低方差特征的結果:\n", data) print("形狀:\n", data.shape) return None # 返回結果 index pe_ratio pb_ratio market_cap \ 0 000001.XSHE 5.9572 1.1818 8.525255e+10 1 000002.XSHE 7.0289 1.5880 8.411336e+10 ... ... ... ... ... 2316 601958.XSHG 52.5408 2.4646 3.287910e+10 2317 601989.XSHG 14.2203 1.4103 5.911086e+10 return_on_asset_net_profit du_return_on_equity ev \ 0 0.8008 14.9403 1.211445e+12 1 1.6463 7.8656 3.002521e+11 ... ... ... ... 2316 2.7444 2.9202 3.883803e+10 2317 2.0383 8.6179 2.020661e+11 earnings_per_share revenue total_expense date return 0 2.0100 2.070140e+10 1.088254e+10 2012-01-31 0.027657 1 0.3260 2.930837e+10 2.378348e+10 2012-01-31 0.082352 2 -0.0060 1.167983e+07 1.203008e+07 2012-01-31 0.099789 ... ... ... ... ... ... 2315 0.2200 1.789082e+10 1.749295e+10 2012-11-30 0.137134 2316 0.1210 6.465392e+09 6.009007e+09 2012-11-30 0.149167 2317 0.2470 4.509872e+10 4.132842e+10 2012-11-30 0.183629 [2318 rows x 12 columns] 刪除低方差特征的結果: [[ 5.95720000e+00 1.18180000e+00 8.52525509e+10 ..., 1.21144486e+12 2.07014010e+10 1.08825400e+10] [ 7.02890000e+00 1.58800000e+00 8.41133582e+10 ..., 3.00252062e+11 2.93083692e+10 2.37834769e+10] [ -2.62746100e+02 7.00030000e+00 5.17045520e+08 ..., 7.70517753e+08 1.16798290e+07 1.20300800e+07] ..., [ 3.95523000e+01 4.00520000e+00 1.70243430e+10 ..., 2.42081699e+10 1.78908166e+10 1.74929478e+10] [ 5.25408000e+01 2.46460000e+00 3.28790988e+10 ..., 3.88380258e+10 6.46539204e+09 6.00900728e+09] [ 1.42203000e+01 1.41030000e+00 5.91108572e+10 ..., 2.02066110e+11 4.50987171e+10 4.13284212e+10]] 形狀: (2318, 8)
6.相關系數
主要實現方式:
- 皮爾遜相關系數
- 斯皮爾曼相關系數
7.皮爾遜相關系數(Pearson Correlation Coefficient)
作用:
反應變量之間相關關系密切程度的統計指標
公式:
特點:
相關系數的值介於–1與+1之間,即–1≤ r ≤+1。其性質如下:
- 當r>0時,表示兩變量正相關,r<0時,兩變量為負相關
- 當|r|=1時,表示兩變量為完全相關,當r=0時,表示兩變量間無相關關系
- 當0<|r|<1時,表示兩變量存在一定程度的相關。且|r|越接近1,兩變量間線性關系越密切;|r|越接近於0,表示兩變量的線性相關越弱
- 一般可按三級划分:|r|<0.4為低度相關;0.4≤|r|<0.7為顯著性相關;0.7≤|r|<1為高度線性相關
API:
from scipy.stats import pearsonr
- x : (N,) array_like
- y : (N,) array_like Returns: (Pearson’s correlation coefficient, p-value)
8.斯皮爾曼相關系數(Rank IC)
作用:
反應變量之間相關關系密切程度的統計指標
公式:
特點:
- 斯皮爾曼相關系數表明 X (自變量) 和 Y (因變量)的相關方向。 如果當X增加時, Y 趨向於增加, 斯皮爾曼相關系數則為正
- 與之前的皮爾遜相關系數大小性質一樣,取值 [-1, 1]之間
【注】
斯皮爾曼相關系數比皮爾遜相關系數應用更加廣泛
API:
from scipy.stats import spearmanr
eg.
from scipy.stats import spearmanr x1 = [12.5, 15.3, 23.2, 26.4, 33.5, 34.4, 39.4, 45.2, 55.4, 60.9] x2 = [21.2, 23.9, 32.9, 34.1, 42.5, 43.2, 49.0, 52.8, 59.4, 63.5] spearmanr(x1, x2) # 結果 SpearmanrResult(correlation=0.9999999999999999, pvalue=6.646897422032013e-64)
9.主成分分析
- 定義:高維數據轉化為低維數據的過程,在此過程中可能會舍棄原有數據、創造新的變量
- 作用:是數據維數壓縮,盡可能降低原數據的維數(復雜度),損失少量信息。
- 應用:回歸分析或者聚類分析當中
API:
sklearn.decomposition.PCA(n_components=None)
- 將數據分解為較低維數空間
- n_components:
- 小數:表示保留百分之多少的信息
- 整數:減少到多少特征
- PCA.fit_transform(X) X:numpy array格式的數據[n_samples,n_features]
- 返回值:轉換后指定維度的array
eg.
[[2,8,4,5], [6,3,0,8], [5,4,9,1]] from sklearn.decomposition import PCA def pca_demo(): """ 對數據進行PCA降維 :return: None """ data = [[2,8,4,5], [6,3,0,8], [5,4,9,1]] # 1、實例化PCA, 小數——保留多少信息 transfer = PCA(n_components=0.9) # 2、調用fit_transform data1 = transfer.fit_transform(data) print("保留90%的信息,降維結果為:\n", data1) # 1、實例化PCA, 整數——指定降維到的維數 transfer2 = PCA(n_components=3) # 2、調用fit_transform data2 = transfer2.fit_transform(data) print("降維到3維的結果:\n", data2) return None # 結果 保留90%的信息,降維結果為: [[ -3.13587302e-16 3.82970843e+00] [ -5.74456265e+00 -1.91485422e+00] [ 5.74456265e+00 -1.91485422e+00]] 降維到3維的結果: [[ -3.13587302e-16 3.82970843e+00 4.59544715e-16] [ -5.74456265e+00 -1.91485422e+00 4.59544715e-16] [ 5.74456265e+00 -1.91485422e+00 4.59544715e-16]]