聚類算法

日萌社

人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度學習實戰(不定時更新)


 

6.1 聚類算法簡介

1 認識聚類算法

使用不同的聚類準則,產生的聚類結果不同

1.1 聚類算法在現實中的應用

  • 用戶畫像,廣告推薦,Data Segmentation,搜索引擎的流量推薦,惡意流量識別

  • 基於位置信息的商業推送,新聞聚類,篩選排序

  • 圖像分割,降維,識別;離羣點檢測;信用卡異常消費;發掘相同功能的基因片段

1.2 聚類算法的概念

聚類算法

一種典型的無監督學習算法,主要用於將相似的樣本自動歸到一個類別中。

在聚類算法中根據樣本之間的相似性,將樣本劃分到不同的類別中,對於不同的相似度計算方法,會得到不同的聚類結果,常用的相似度計算方法有歐式距離法。

1.3 聚類算法與分類算法最大的區別

聚類算法是無監督的學習算法,而分類算法屬於監督的學習算法。

2 小結

  • 聚類算法分類【瞭解】
    • 粗聚類
    • 細聚類
  • 聚類的定義【瞭解】
    • 一種典型的無監督學習算法,
    • 主要用於將相似的樣本自動歸到一個類別中
    • 計算樣本和樣本之間的相似性,一般使用歐式距離

6.2 聚類算法api初步使用

1 api介紹

  • sklearn.cluster.KMeans(n_clusters=8)
    • 參數:
      • n_clusters:開始的聚類中心數量
        • 整型,缺省值=8,生成的聚類數,即產生的質心(centroids)數。
    • 方法:
      • estimator.fit(x)
      • estimator.predict(x)
      • estimator.fit_predict(x)
        • 計算聚類中心並預測每個樣本屬於哪個類別,相當於先調用fit(x),然後再調用predict(x)

2 案例

隨機創建不同二維數據集作爲訓練集,並結合k-means算法將其聚類,你可以嘗試分別聚類不同數量的簇,並觀察聚類效果:

聚類參數n_cluster傳值不同,得到的聚類結果不同

2.1流程分析

2.2 代碼實現

1.創建數據集

import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_blobs
from sklearn.cluster import KMeans
from sklearn.metrics import calinski_harabaz_score

# 創建數據集
# X爲樣本特徵,Y爲樣本簇類別, 共1000個樣本,每個樣本2個特徵,共4個簇,
# 簇中心在[-1,-1], [0,0],[1,1], [2,2], 簇方差分別爲[0.4, 0.2, 0.2, 0.2]
X, y = make_blobs(n_samples=1000, n_features=2, centers=[[-1, -1], [0, 0], [1, 1], [2, 2]],
                  cluster_std=[0.4, 0.2, 0.2, 0.2],
                  random_state=9)

# 數據集可視化
plt.scatter(X[:, 0], X[:, 1], marker='o')
plt.show()

2.使用k-means進行聚類,並使用CH方法評估

y_pred = KMeans(n_clusters=2, random_state=9).fit_predict(X)
# 分別嘗試n_cluses=2\3\4,然後查看聚類效果
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.show()

# 用Calinski-Harabasz Index評估的聚類分數
print(calinski_harabaz_score(X, y_pred))

3 小結

  • api:sklearn.cluster.KMeans(n_clusters=8)【知道】
    • 參數:
      • n_clusters:開始的聚類中心數量
    • 方法:
      • estimator.fit_predict(x)
        • 計算聚類中心並預測每個樣本屬於哪個類別,相當於先調用fit(x),然後再調用predict(x)

In [1]:

import matplotlib.pyplot as plt
from sklearn.datasets.samples_generator import make_blobs
from sklearn.cluster import KMeans
from sklearn.metrics import calinski_harabaz_score

In [2]:

# 創建數據
X, y = make_blobs(n_samples=1000, n_features=2, centers=[
                  [-1, -1], [0, 0], [1, 1], [2, 2]], cluster_std=[0.4, 0.2, 0.2, 0.2], random_state=9)

In [3]:

plt.scatter(X[:, 0], X[:, 1], marker="o")
plt.show()

In [7]:

# kmeans訓練,且可視化 聚類=2
y_pre = KMeans(n_clusters=2, random_state=9).fit_predict(X)

# 可視化展示
plt.scatter(X[:, 0], X[:, 1], c=y_pre)
plt.show()

# 用ch_scole查看最後效果
print(calinski_harabaz_score(X, y_pre))

3116.1706763322227

In [8]:

# kmeans訓練,且可視化 聚類=3
y_pre = KMeans(n_clusters=3, random_state=9).fit_predict(X)

# 可視化展示
plt.scatter(X[:, 0], X[:, 1], c=y_pre)
plt.show()

# 用ch_scole查看最後效果
print(calinski_harabaz_score(X, y_pre))

2931.625030199556

In [9]:

# kmeans訓練,且可視化 聚類=4
y_pre = KMeans(n_clusters=4, random_state=9).fit_predict(X)

# 可視化展示
plt.scatter(X[:, 0], X[:, 1], c=y_pre)
plt.show()

# 用ch_scole查看最後效果
print(calinski_harabaz_score(X, y_pre))

5924.050613480169

6.3 聚類算法實現流程

  • k-means其實包含兩層內容:
    • ​ K : 初始中心點個數(計劃聚類數)
    • ​ means:求中心點到其他數據點距離的平均值

1 k-means聚類步驟

  • 1、隨機設置K個特徵空間內的點作爲初始的聚類中心
  • 2、對於其他每個點計算到K箇中心的距離,未知的點選擇最近的一個聚類中心點作爲標記類別
  • 3、接着對着標記的聚類中心之後,重新計算出每個聚類的新中心點(平均值)
  • 4、如果計算得出的新中心點與原中心點一樣(質心不再移動),那麼結束,否則重新進行第二步過程

通過下圖解釋實現流程:

k聚類動態效果圖

2 案例練習

  • 案例:

  • 1、隨機設置K個特徵空間內的點作爲初始的聚類中心(本案例中設置p1和p2)

2、對於其他每個點計算到K箇中心的距離,未知的點選擇最近的一個聚類中心點作爲標記類別

3、接着對着標記的聚類中心之後,重新計算出每個聚類的新中心點(平均值)

4、如果計算得出的新中心點與原中心點一樣(質心不再移動),那麼結束,否則重新進行第二步過程【經過判斷,需要重複上述步驟,開始新一輪迭代】

5、當每次迭代結果不變時,認爲算法收斂,聚類完成,K-Means一定會停下,不可能陷入一直選質心的過程。

3 小結

  • K-means聚類實現流程【掌握】
    • 事先確定常數K,常數K意味着最終的聚類類別數;
    • 隨機選定初始點爲質心,並通過計算每一個樣本與質心之間的相似度(這裏爲歐式距離),將樣本點歸到最相似的類中,
    • 接着,重新計算每個類的質心(即爲類中心),重複這樣的過程,直到質心不再改變
    • 最終就確定了每個樣本所屬的類別以及每個類的質心。
    • 注意:
      • 由於每次都要計算所有的樣本與每一個質心之間的相似度,故在大規模的數據集上,K-Means算法的收斂速度比較慢。

6.4 模型評估

1 誤差平方和(SSE \The sum of squares due to error):

舉例:(下圖中數據-0.2, 0.4, -0.8, 1.3, -0.7, 均爲真實值和預測值的差)

在k-means中的應用:

上圖中: k=2

  • SSE圖最終的結果,對圖鬆散度的衡量.(eg: SSE(左圖)<SSE(右圖))
  • SSE隨着聚類迭代,其值會越來越小,直到最後趨於穩定:

  • 如果質心的初始值選擇不好,SSE只會達到一個不怎麼好的局部最優解.

“肘”方法 (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],係數越大,聚類效果越好。

簇內樣本的距離越近,簇間樣本距離越遠

案例:

下圖是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高則聚類效果越好。

使用矩陣的跡進行求解的理解:

矩陣的對角線可以表示一個物體的相似性

在機器學習裏,主要爲了獲取數據的特徵值,那麼就是說,在任何一個矩陣計算出來之後,都可以簡單化,只要獲取矩陣的跡,就可以表示這一塊數據的最重要的特徵了,這樣就可以把很多無關緊要的數據刪除掉,達到簡化數據,提高處理速度。

CH需要達到的目的:

​ 用盡量少的類別聚類儘量多的樣本,同時獲得較好的聚類效果。

5 小結

  • sse【知道】
    • 誤差平方和的值越小越好
  • 肘部法【知道】
    • 下降率突然變緩時即認爲是最佳的k值
  • SC係數【知道】
    • 取值爲[-1, 1],其值越大越好
  • CH係數【知道】
    • 分數s高則聚類效果越好
    • CH需要達到的目的:用盡量少的類別聚類儘量多的樣本,同時獲得較好的聚類效果。

6.5 算法優化

k-means算法小結

優點:

​ 1.原理簡單(靠近中心點),實現容易

​ 2.聚類效果中上(依賴K的選擇)

​ 3.空間複雜度o(N),時間複雜度o(IKN)

N爲樣本點個數,K爲中心點個數,I爲迭代次數

缺點:

​ 1.對離羣點,噪聲敏感 (中心點易偏移)

​ 2.很難發現大小差別很大的簇及進行增量計算

​ 3.結果不一定是全局最優,只能保證局部最優(與K的個數及初值選取有關)

1 Canopy算法配合初始聚類

1.1 Canopy算法配合初始聚類實現流程

1.2 Canopy算法的優缺點

優點:

​ 1.Kmeans對噪聲抗干擾較弱,通過Canopy對比,將較小的NumPoint的Cluster直接去掉有利於抗干擾。

​ 2.Canopy選擇出來的每個Canopy的centerPoint作爲K會更精確。

​ 3.只是針對每個Canopy的內做Kmeans聚類,減少相似計算的數量。

缺點:

​ 1.算法中 T1、T2的確定問題 ,依舊可能落入局部最優解

2 K-means++

質心爲2時例子如下:
分子(D(x)^2):質心2到其他距離點的平方,比如質心2到1爲1^2,質心2到8爲6^2,質心2到15爲13^2,以此類推
分母(∑D(x)^2):質心2到1爲1^2,2到0爲2^2,2到3爲1^2,2到4爲2^2,以此類推,對質心2到所有距離點的平方和

kmeans++目的,讓選擇的質心儘可能的分散

如下圖中,如果第一個質心選擇在圓心,那麼最優可能選擇到的下一個點在P(A)這個區域(根據顏色進行劃分)

3 二分k-means

實現流程:

  • 1.所有點作爲一個簇

  • 2.將該簇一分爲二

  • 3.選擇能最大限度降低聚類代價函數(也就是誤差平方和)的簇劃分爲兩個簇。

  • 4.以此進行下去,直到簇的數目等於用戶給定的數目k爲止。

隱含的一個原則

因爲聚類的誤差平方和能夠衡量聚類性能,該值越小表示數據點越接近於他們的質心,聚類效果就越好。所以需要對誤差平方和最大的簇進行再一次劃分,因爲誤差平方和越大,表示該簇聚類效果越不好,越有可能是多個簇被當成了一個簇,所以我們首先需要對這個簇進行劃分。

二分K均值算法可以加速K-means算法的執行速度,因爲它的相似度計算少了並且不受初始化問題的影響,因爲這裏不存在隨機點的選取,且每一步都保證了誤差最小

4 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多。

5 Kernel k-means(瞭解)

kernel k-means實際上,就是將每個樣本進行一個投射到高維空間的處理,然後再將處理後的數據使用普通的k-means算法思想進行聚類。

6 ISODATA(瞭解)

類別數目隨着聚類過程而變化;

對類別數會進行合併,分裂,

“合併”:(當聚類結果某一類中樣本數太少,或兩個類間的距離太近時)

“分裂”:(當聚類結果中某一類的類內方差太大,將該類進行分裂)

7 Mini Batch K-Means(瞭解)

適合大數據的聚類算法

大數據量是什麼量級?通常當樣本量大於1萬做聚類時,就需要考慮選用Mini Batch K-Means算法。

Mini Batch KMeans使用了Mini Batch(分批處理)的方法對數據點之間的距離進行計算。

Mini Batch計算過程中不必使用所有的數據樣本,而是從不同類別的樣本中抽取一部分樣本來代表各自類型進行計算。由於計算樣本量少,所以會相應的減少運行時間,但另一方面抽樣也必然會帶來準確度的下降。

該算法的迭代步驟有兩步:

(1)從數據集中隨機抽取一些數據形成小批量,把他們分配給最近的質心

(2)更新質心

​ 與Kmeans相比,數據的更新在每一個小的樣本集上。對於每一個小批量,通過計算平均值得到更新質心,並把小批量裏的數據分配給該質心,隨着迭代次數的增加,這些質心的變化是逐漸減小的,直到質心穩定或者達到指定的迭代次數,停止計算。

8 小結

  • k-means算法優缺點總結【知道】
    • 優點:
      • ​ 1.原理簡單(靠近中心點),實現容易
      • ​ 2.聚類效果中上(依賴K的選擇)
      • ​ 3.空間複雜度o(N),時間複雜度o(IKN)
    • 缺點:
      • ​ 1.對離羣點,噪聲敏感 (中心點易偏移)
      • ​ 2.很難發現大小差別很大的簇及進行增量計算
      • ​ 3.結果不一定是全局最優,只能保證局部最優(與K的個數及初值選取有關)
  • 優化方法【知道】
優化方法 思路
Canopy+kmeans Canopy粗聚類配合kmeans
kmeans++ 距離越遠越容易成爲新的質心
二分k-means 拆除SSE最大的簇
k-medoids 和kmeans選取中心點的方式不同
kernel kmeans 映射到高維空間
ISODATA 動態聚類,可以更改K值大小
Mini-batch K-Means 大數據集分批聚類

6.6 特徵降維

1 降維

1.1 定義

降維是指在某些限定條件下,降低隨機變量(特徵)個數,得到一組“不相關”主變量的過程

  • 降低隨機變量的個數

  • 相關特徵(correlated feature)
    • 相對溼度與降雨量之間的相關
    • 等等

正是因爲在進行訓練的時候,我們都是使用特徵進行學習。如果特徵本身存在問題或者特徵之間相關性較強,對於算法學習預測會影響較大

1.2 降維的兩種方式

  • 特徵選擇
  • 主成分分析(可以理解一種特徵提取的方式)

2 特徵選擇

2.1 定義

數據中包含冗餘或無關變量(或稱特徵、屬性、指標等),旨在從原有特徵中找出主要特徵

2.2 方法

  • Filter(過濾式):主要探究特徵本身特點、特徵與特徵和目標值之間關聯
    • 方差選擇法:低方差特徵過濾
    • 相關係數
  • Embedded (嵌入式):算法自動選擇特徵(特徵與目標值之間的關聯)
    • 決策樹:信息熵、信息增益
    • 正則化:L1、L2
    • 深度學習:卷積等

2.3 低方差特徵過濾

刪除低方差的一些特徵,前面講過方差的意義。再結合方差的大小來考慮這個方式的角度。

  • 特徵方差小:某個特徵大多樣本的值比較相近
  • 特徵方差大:某個特徵很多樣本的值都有差別

2.3.1 API

  • sklearn.feature_selection.VarianceThreshold(threshold = 0.0)
    • 刪除所有低方差特徵
    • Variance.fit_transform(X)
      • X:numpy array格式的數據[n_samples,n_features]
      • 返回值:訓練集差異低於threshold的特徵將被刪除。默認值是保留所有非零方差特徵,即刪除所有樣本中具有相同值的特徵。

2.3.2 數據計算

我們對某些股票的指標特徵之間進行一個篩選,除去'index,'date','return'列不考慮(這些類型不匹配,也不是所需要指標)

一共這些特徵

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
  • 分析

1、初始化VarianceThreshold,指定閥值方差

2、調用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)

2.4 相關係數

  • 主要實現方式:
    • 皮爾遜相關係數
    • 斯皮爾曼相關係數

2.4.1 皮爾遜相關係數(Pearson Correlation Coefficient)

1.作用

反映變量之間相關關係密切程度的統計指標

2.公式計算案例(瞭解,不用記憶)

所以我們最終得出結論是廣告投入費與月平均銷售額之間有高度的正相關關係。

3.特點

相關係數的值介於–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爲高度線性相關

4.api

  • from scipy.stats import pearsonr
    • x : (N,) array_like
    • y : (N,) array_like Returns: (Pearson’s correlation coefficient, p-value)

5.案例

from scipy.stats import pearsonr

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]

pearsonr(x1, x2)

結果

(0.9941983762371883, 4.9220899554573455e-09)

2.4.2 斯皮爾曼相關係數(Rank IC)

1.作用:

反映變量之間相關關係密切程度的統計指標

2.公式計算案例(瞭解,不用記憶)

3.特點

  • 斯皮爾曼相關係數表明 X (自變量) 和 Y (因變量)的相關方向。 如果當X增加時, Y 趨向於增加, 斯皮爾曼相關係數則爲正
  • 與之前的皮爾遜相關係數大小性質一樣,取值 [-1, 1]之間

斯皮爾曼相關係數比皮爾遜相關係數應用更加廣泛

4.api

  • from scipy.stats import spearmanr

5.案例

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)

3 主成分分析

3.1 什麼是主成分分析(PCA)

  • 定義:高維數據轉化爲低維數據的過程,在此過程中可能會捨棄原有數據、創造新的變量
  • 作用:是數據維數壓縮,儘可能降低原數據的維數(複雜度),損失少量信息。
  • 應用:迴歸分析或者聚類分析當中

對於信息一詞,在決策樹中會進行介紹

那麼更好的理解這個過程呢?我們來看一張圖

3.2 API

  • sklearn.decomposition.PCA(n_components=None)
    • 將數據分解爲較低維數空間
    • n_components:
      • 小數:表示保留百分之多少的信息
      • 整數:減少到多少特徵
    • PCA.fit_transform(X) X:numpy array格式的數據[n_samples,n_features]
    • 返回值:轉換後指定維度的array

3.3 數據計算

先拿個簡單的數據計算一下

[[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]]

4 小結

  • 降維的定義【瞭解】
    • 就是改變特徵值,選擇哪列保留,哪列刪除
    • 目標是得到一組”不相關“的主變量
  • 降維的兩種方式【瞭解】
    • 特徵選擇
    • 主成分分析(可以理解一種特徵提取的方式)
  • 特徵選擇【知道】
    • 定義:提出數據中的冗餘變量
    • 方法:
      • Filter(過濾式):主要探究特徵本身特點、特徵與特徵和目標值之間關聯
        • 方差選擇法:低方差特徵過濾
        • 相關係數
      • Embedded (嵌入式):算法自動選擇特徵(特徵與目標值之間的關聯)
        • 決策樹:信息熵、信息增益
        • 正則化:L1、L2
  • 低方差特徵過濾【知道】
    • 把方差比較小的某一列進行剔除
    • api:sklearn.feature_selection.VarianceThreshold(threshold = 0.0)
      • 刪除所有低方差特徵
      • 注意,參數threshold一定要進行值的指定
  • 相關係數【掌握】
    • 主要實現方式:
      • 皮爾遜相關係數
      • 斯皮爾曼相關係數
    • 皮爾遜相關係數
      • 通過具體值的大小進行計算
      • 相對複雜
      • api:from scipy.stats import pearsonr
        • 返回值,越接近|1|,相關性越強;越接近0,相關性越弱
    • 斯皮爾曼相關係數
      • 通過等級差進行計算
      • 比上一個簡單
      • api:from scipy.stats import spearmanr
      • 返回值,越接近|1|,相關性越強;越接近0,相關性越弱
  • pca【知道】
    • 定義:高維數據轉換爲低維數據,然後產生了新的變量
    • api:sklearn.decomposition.PCA(n_components=None)
      • n_components
        • 整數 -- 表示降低到幾維
        • 小數 -- 保留百分之多少的信息

# coding:utf-8

import pandas as pd
from sklearn.feature_selection import VarianceThreshold
from scipy.stats import pearsonr, spearmanr
from sklearn.decomposition import PCA


def var_thr():
    """
    特徵選擇:低方差特徵過濾
    :return:
    """
    data = pd.read_csv("./data/factor_returns.csv")
    # print(data)
    print(data.shape)

    # 實例化一個對象
    transfer = VarianceThreshold(threshold=10)
    # 轉換
    transfer_data = transfer.fit_transform(data.iloc[:, 1:10])
    print(transfer_data)
    print(data.iloc[:, 1:10].shape)
    print(transfer_data.shape)


def pea_demo():
    """
    皮爾遜相關係數
    :return:
    """
    # 準備數據
    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]

    # 判斷
    ret = pearsonr(x1, x2)
    print("皮爾遜相關係數的結果是:\n", ret)


def spea_demo():
    """
    斯皮爾曼相關係數
    :return:
    """
    # 準備數據
    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]

    # 判斷
    ret = spearmanr(x1, x2)
    print("斯皮爾曼相關係數的結果是:\n", ret)


def pca_demo():
    """
    pca降維
    :return:
    """
    data = [[2, 8, 4, 5], [6, 3, 0, 8], [5, 4, 9, 1]]

    # pca小數保留百分比
    transfer = PCA(n_components=0.9)
    trans_data = transfer.fit_transform(data)
    print("保留0.9的數據最後維度爲:\n", trans_data)

    # pca小數保留百分比
    transfer = PCA(n_components=3)
    trans_data = transfer.fit_transform(data)
    print("保留三列數據:\n", trans_data)


if __name__ == '__main__':
    # var_thr()
    # pea_demo()
    # spea_demo()
    pca_demo()

In [ ]:

# 1.獲取數據
# 2.數據基本處理
# 2.1 合併表格
# 2.2 交叉表合併
# 2.3 數據截取
# 3.特徵工程 — pca
# 4.機器學習(k-means)
# 5.模型評估

In [7]:

import pandas as pd
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score

In [2]:

# 1.獲取數據
order_product = pd.read_csv("./data/instacart/order_products__prior.csv")
products = pd.read_csv("./data/instacart/products.csv")
orders = pd.read_csv("./data/instacart/orders.csv")
aisles = pd.read_csv("./data/instacart/aisles.csv")

In [3]:

order_product.head()

Out[3]:

  order_id product_id add_to_cart_order reordered
0 2 33120 1 1
1 2 28985 2 1
2 2 9327 3 0
3 2 45918 4 1
4 2 30035 5 0

In [4]:

products.head()

Out[4]:

  product_id product_name aisle_id department_id
0 1 Chocolate Sandwich Cookies 61 19
1 2 All-Seasons Salt 104 13
2 3 Robust Golden Unsweetened Oolong Tea 94 7
3 4 Smart Ones Classic Favorites Mini Rigatoni Wit... 38 1
4 5 Green Chile Anytime Sauce 5 13

In [5]:

orders.head()

Out[5]:

  order_id user_id eval_set order_number order_dow order_hour_of_day days_since_prior_order
0 2539329 1 prior 1 2 8 NaN
1 2398795 1 prior 2 3 7 15.0
2 473747 1 prior 3 3 12 21.0
3 2254736 1 prior 4 4 7 29.0
4 431534 1 prior 5 4 15 28.0

In [6]:

aisles.head()

Out[6]:

  aisle_id aisle
0 1 prepared soups salads
1 2 specialty cheeses
2 3 energy granola bars
3 4 instant foods
4 5 marinades meat preparation

In [8]:

# 2.數據基本處理
# 2.1 合併表格
table1 = pd.merge(order_product, products, on=["product_id", "product_id"])

In [9]:

table2 = pd.merge(table1, orders, on=["order_id", "order_id"])

In [10]:

table = pd.merge(table2, aisles, on=["aisle_id", "aisle_id"])

In [11]:

table.shape

Out[11]:

(32434489, 14)

In [12]:

table.head()

Out[12]:

  order_id product_id add_to_cart_order reordered product_name aisle_id department_id user_id eval_set order_number order_dow order_hour_of_day days_since_prior_order aisle
0 2 33120 1 1 Organic Egg Whites 86 16 202279 prior 3 5 9 8.0 eggs
1 26 33120 5 0 Organic Egg Whites 86 16 153404 prior 2 0 16 7.0 eggs
2 120 33120 13 0 Organic Egg Whites 86 16 23750 prior 11 6 8 10.0 eggs
3 327 33120 5 1 Organic Egg Whites 86 16 58707 prior 21 6 9 8.0 eggs
4 390 33120 28 1 Organic Egg Whites 86 16 166654 prior 48 0 12 9.0 eggs

In [13]:

# 2.2 交叉表合併
data = pd.crosstab(table["user_id"], table["aisle"])

In [14]:

data.shape

Out[14]:

(206209, 134)

In [15]:

data.head()

Out[15]:

aisle air fresheners candles asian foods baby accessories baby bath body care baby food formula bakery desserts baking ingredients baking supplies decor beauty beers coolers ... spreads tea tofu meat alternatives tortillas flat bread trail mix snack mix trash bags liners vitamins supplements water seltzer sparkling water white wines yogurt
user_id                                          
1 0 0 0 0 0 0 0 0 0 0 ... 1 0 0 0 0 0 0 0 0 1
2 0 3 0 0 0 0 2 0 0 0 ... 3 1 1 0 0 0 0 2 0 42
3 0 0 0 0 0 0 0 0 0 0 ... 4 1 0 0 0 0 0 2 0 0
4 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 1 0 0 0 1 0 0
5 0 2 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 3

5 rows × 134 columns

In [16]:

# 2.3 數據截取
new_data = data[:1000]

In [17]:

# 3.特徵工程 — pca
transfer = PCA(n_components=0.9)
trans_data = transfer.fit_transform(new_data)

In [18]:

trans_data.shape

Out[18]:

(1000, 22)

In [20]:

# 4.機器學習(k-means)
estimator = KMeans(n_clusters=5)
y_pre = estimator.fit_predict(trans_data)

In [21]:

y_pre

Out[21]:

array([0, 3, 0, 0, 0, 0, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 3, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0,
       0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 3, 0, 0, 3, 0, 0, 0, 0, 0, 4, 3, 0,
       3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4,
       0, 3, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0,
       3, 0, 0, 0, 0, 0, 0, 2, 0, 3, 3, 0, 0, 3, 0, 0, 3, 0, 3, 2, 4, 3,
       3, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 0,
       0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 4, 0,
       0, 0, 0, 3, 0, 4, 0, 3, 0, 0, 3, 1, 0, 0, 0, 4, 0, 3, 0, 0, 3, 3,
       3, 3, 2, 0, 0, 3, 4, 0, 3, 0, 0, 4, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0,
       4, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 3, 0, 2,
       0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 2, 4, 0, 0, 3, 0, 0,
       0, 0, 1, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0,
       4, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, 4, 3, 2, 0, 0, 0, 2, 0, 0, 0,
       0, 3, 0, 4, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3,
       0, 0, 3, 0, 3, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0,
       0, 0, 0, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 3, 3, 0, 3,
       0, 4, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 2, 3, 0, 0, 3, 0, 0, 0, 0, 3,
       0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 3, 0, 0,
       0, 0, 0, 1, 0, 0, 0, 3, 0, 3, 3, 4, 0, 3, 0, 0, 0, 0, 0, 0, 0, 2,
       0, 4, 3, 4, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 0, 0, 0, 4, 0, 0, 0,
       0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0,
       0, 3, 3, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4,
       3, 0, 0, 0, 0, 0, 3, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, 3,
       0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 4, 0, 0, 0, 3, 4, 0, 0, 2, 3, 0, 3, 3, 0, 2, 0, 3, 2, 0, 0,
       0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 3, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0,
       0, 0, 0, 0, 3, 3, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 3, 0, 3, 0, 0, 0,
       3, 3, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 0, 0, 4, 0, 0, 0, 0, 3, 3, 0, 0,
       0, 0, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, 0,
       0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 0, 0, 0,
       0, 0, 4, 0, 3, 3, 0, 0, 3, 0, 4, 3, 0, 0, 0, 4, 0, 4, 3, 0, 3, 0,
       0, 3, 0, 0, 3, 3, 0, 3, 0, 4, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 4, 4,
       3, 0, 0, 0, 0, 0, 0, 3, 0, 3, 3, 0, 0, 2, 0, 4, 0, 3, 0, 3, 0, 0,
       0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 3, 0, 0, 3, 0, 3, 0, 0, 0, 0, 3,
       0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
       4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 0, 0, 3, 3, 0, 2, 0, 0, 0, 2,
       3, 0, 0, 3, 4, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 3, 0, 0, 3, 2, 0], dtype=int32)

In [22]:

# 5.模型評估
silhouette_score(trans_data, y_pre)

Out[22]:

0.4769176054106921

6.7 案例:探究用戶對物品類別的喜好細分

  • 應用pca和K-means實現用戶對物品類別的喜好細分劃分

數據如下:

  • order_products__prior.csv:訂單與商品信息
    • 字段:order_idproduct_id, add_to_cart_order, reordered
  • products.csv:商品信息
    • 字段:product_id, product_name, aisle_id, department_id
  • orders.csv:用戶的訂單信息
    • 字段:order_id,user_id,eval_set,order_number,….
  • aisles.csv:商品所屬具體物品類別
    • 字段: aisle_idaisle

1 需求

2 分析

  • 1.獲取數據
  • 2.數據基本處理
    • 2.1 合併表格
    • 2.2 交叉表合併
    • 2.3 數據截取
  • 3.特徵工程 — pca
  • 4.機器學習(k-means)
  • 5.模型評估
    • sklearn.metrics.silhouette_score(X, labels)
      • 計算所有樣本的平均輪廓係數
      • X:特徵值
      • labels:被聚類標記的目標值

3 完整代碼

import pandas as pd
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
  • 1.獲取數據
order_product = pd.read_csv("./data/instacart/order_products__prior.csv")
products = pd.read_csv("./data/instacart/products.csv")
orders = pd.read_csv("./data/instacart/orders.csv")
aisles = pd.read_csv("./data/instacart/aisles.csv")
  • 2.數據基本處理

    • 2.1 合併表格
    # 2.1 合併表格
    table1 = pd.merge(order_product, products, on=["product_id", "product_id"])
    table2 = pd.merge(table1, orders, on=["order_id", "order_id"])
    table = pd.merge(table2, aisles, on=["aisle_id", "aisle_id"])
    
    • 2.2 交叉表合併
    table = pd.crosstab(table["user_id"], table["aisle"])
    
    • 2.3 數據截取
    table = table[:1000]
    
  • 3.特徵工程 — pca

transfer = PCA(n_components=0.9)
data = transfer.fit_transform(table)
  • 4.機器學習(k-means)
estimator = KMeans(n_clusters=8, random_state=22)
estimator.fit_predict(data)
  • 5.模型評估
silhouette_score(data, y_predict)

 


6.8 算法選擇指導

關於在計算的過程中,如何選擇合適的算法進行計算,可以參考scikit learn官方給的指導意見:

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章