【資料分析】python機器學習-常用非監督式學習的聚類算法

更新於 發佈於 閱讀時間約 1 分鐘
raw-image

在數據科學和機器學習中,聚類算法是一種常用的非監督學習方法,旨在將數據分組,使同一組中的數據點之間的相似性最大化,而不同組之間的相似性最小化。根據不同的應用場景和數據特性,不同的聚類算法適合不同的數據集。


# 可使用目錄功能快速確認要閱覽的主題


方法選擇參考

  • K-means:當知道群集數量,並且數據呈現較為規則的球形結構時,選擇 K-means。
  • DBSCAN:當數據包含噪音或異常值,且群集形狀不規則或密度不均時,選擇 DBSCAN。
  • 層次聚類:當你想要探索數據的層次結構或進行小規模數據的聚類分析時,選擇層次聚類。



K-means

K-means 是一種基於劃分的聚類算法,它的核心思想是將數據集分成 K 個群集,使得每個數據點與其最近的群集中心的距離最小。

工作原理

  1. 初始化:隨機選擇 K 個初始群集中心(centroids)。
  2. 分配數據點:根據每個數據點與群集中心的距離,將每個數據點分配給最近的群集中心。
  3. 更新群集中心:重新計算每個群集的中心位置(即所有群集內數據點的均值)。
  4. 重複步驟 2 和 3:直到群集中心不再變動或變化非常小,達到收斂。


應用場景

  • 市場細分:根據消費者行為和購買記錄,將客戶群體劃分成不同的細分市場。
  • 文件分類:將大量文檔分成不同主題的群集。
  • 圖像分割:根據圖像的顏色特徵,將圖像像素劃分為不同的區域。


程式碼範例

from sklearn.cluster import KMeans
from sklearn.datasets import load_iris
import pandas as pd

# 加載數據集(以 iris 為例)
data = load_iris()
X = data.data

# K-means 聚類,設置 K=3
kmeans = KMeans(n_clusters=3, random_state=42)
kmeans_labels = kmeans.fit_predict(X)

# 將結果轉換為 DataFrame 便於查看
df = pd.DataFrame(X, columns=data.feature_names)
df['Cluster'] = kmeans_labels

print(df.head()) # 顯示前幾個樣本和它們的群集標籤

"""
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) \
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
3 4.6 3.1 1.5 0.2
4 5.0 3.6 1.4 0.2

Cluster
0 1
1 1
2 1
3 1
4 1
"""


K-means 優點與缺點


優點

  • 簡單高效:計算效率高,特別適合大規模數據集。
  • 易於理解和實現:K-means 的工作流程相對簡單,且廣泛應用於各個領域。
  • 可擴展:可以使用 Mini-batch K-means 進行擴展,適合在線學習和即時處理。

缺點

  • 需要事先指定 K 值:必須提前指定群集數量 K,而且群集數的選擇可能需要多次嘗試。
  • 對異常值敏感:異常值會顯著影響群集中心的位置,導致聚類效果不佳。
  • 只能檢測球形群集:K-means 假設群集是球形的,對於形狀不規則的群集效果不佳。
  • 依賴初始群集中心:K-means 的結果依賴於初始中心位置,不同的初始值可能導致不同的結果。



DBSCAN(Density-Based Spatial Clustering of Applications with Noise)

DBSCAN 是一種基於密度的聚類算法,它通過識別密度較高的區域來形成群集,同時能夠標識出噪音點。


工作原理

  1. 定義鄰域:給定一個鄰域半徑 eps 和最小點數 min_samples,算法會檢查每個數據點周圍有多少個點在 eps 距離範圍內。
  2. 核心點、邊界點和噪音點2-1 核心點:如果一個數據點周圍有超過 min_samples 個點在 eps 範圍內,則該點是核心點。2-2 邊界點:不滿足核心點條件,但在其他核心點的 eps 鄰域內的點。2-3 噪音點:既不是核心點,也不在任何核心點的鄰域內的點,標記為噪音點(label = -1)。
  3. 形成群集:從一個核心點開始,將所有相連的點(包括邊界點)歸入同一群集,直到不再有新的點可以加入該群集為止。
  4. 重複步驟:繼續檢查其他未被歸入群集的點,直到所有點都被處理。


應用場景

  • 異常檢測:在信用卡欺詐檢測中,DBSCAN 能夠識別不規則行為並標記為異常點。
  • 地理數據分析:分析地理分佈數據,識別密度較高的區域。
  • 噪音數據處理:處理有噪音或異常值的數據集,例如感應器數據。


程式碼範例

from sklearn.cluster import DBSCAN
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
import pandas as pd

# 加載數據集(以 iris 為例)
data = load_iris()
X = data.data

# 標準化數據
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

# DBSCAN 聚類
dbscan = DBSCAN(eps=0.5, min_samples=5)
dbscan_labels = dbscan.fit_predict(X_scaled)

# 將結果轉換為 DataFrame 便於查看
df = pd.DataFrame(X, columns=data.feature_names)
df['Cluster'] = dbscan_labels

print(df.head()) # 顯示前幾個樣本和它們的群集標籤

"""
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) \
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
3 4.6 3.1 1.5 0.2
4 5.0 3.6 1.4 0.2

Cluster
0 0
1 0
2 0
3 0
4 0
"""


DBSCAN 優點與缺點


優點

  • 不需要指定群集數:DBSCAN 不需要提前設定群集數,它會根據數據的密度自動形成群集。
  • 能夠檢測任意形狀的群集:DBSCAN 可以識別不規則形狀的群集,而不僅僅是球形群集。
  • 處理噪音點:DBSCAN 會自動將密度較低的點標記為噪音點,這對處理有異常值的數據非常有用。

缺點

  • 對不同密度的群集效果不佳:如果數據中的群集密度差異過大,DBSCAN 可能無法有效分辨不同群集。
  • 參數敏感性:DBSCAN 的效果高度依賴於 epsmin_samples 參數的選擇,選擇不當可能導致糟糕的聚類結果。
  • 計算複雜度較高:DBSCAN 在高維數據集上的運行速度較慢。



層次聚類(Hierarchical Clustering)

層次聚類 是一種基於層次結構的聚類算法,它可以將數據從小群集逐步合併為大群集,也可以從大群集逐步分裂為小群集。層次聚類可以分為兩種類型:

  • 凝聚型(Agglomerative Clustering):從每個數據點開始,逐步將最近的群集合併,直到只剩下一個群集。
  • 分裂型(Divisive Clustering):從一個大群集開始,逐步將群集分裂成更小的群集。


凝聚型聚類(Agglomerative Clustering)

凝聚型聚類是從每個數據點開始,將最近的兩個群集合併,逐步形成較大的群集,最終所有數據點合併成一個群集。它是一種自底向上的方法。


工作原理

  1. 每個數據點是一個群集:初始時,每個數據點被視為一個單獨的群集。
  2. 計算群集之間的距離:計算每個群集與其他群集之間的距離,可以選擇不同的距離度量方法,如:2-1 最小距離法(Single Linkage):計算兩群集之間最近的兩個點的距離。2-2 最大距離法(Complete Linkage):計算兩群集之間最遠的兩個點的距離。2-3 平均距離法(Average Linkage):計算兩群集內所有點之間距離的平均值。2-4 質心法(Centroid Linkage):計算兩群集中心之間的距離。
  3. 合併最近的兩個群集:找到距離最近的兩個群集,將它們合併為一個新的群集。
  4. 更新距離矩陣:重新計算新合併的群集與其他群集之間的距離。
  5. 重複步驟:不斷合併最近的群集,直到所有數據點合併為一個群集,或達到預定的群集數。


應用場景

  • 基因表達數據分析:用於基因的相似性聚類,研究不同基因之間的層次結構關係。
  • 文檔分類:分析不同文檔之間的主題關聯性,進行層次分組。
  • 客戶群分析:將不同特徵的客戶進行分組,展示客戶之間的層次關係。


程式碼範例

from sklearn.cluster import AgglomerativeClustering
from sklearn.datasets import load_iris
import pandas as pd

# 加載數據集(以 iris 為例)
data = load_iris()
X = data.data

# 凝聚型聚類
agg_clustering = AgglomerativeClustering(n_clusters=3)
agg_labels = agg_clustering.fit_predict(X)

# 將結果轉換為 DataFrame 便於查看
df = pd.DataFrame(X, columns=data.feature_names)
df['Cluster'] = agg_labels

print(df.head()) # 顯示前幾個樣本和它們的群集標籤


"""
sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) \
0 5.1 3.5 1.4 0.2
1 4.9 3.0 1.4 0.2
2 4.7 3.2 1.3 0.2
3 4.6 3.1 1.5 0.2
4 5.0 3.6 1.4 0.2

Cluster
0 1
1 1
2 1
3 1
4 1
"""


凝聚型聚類 優點與缺點


優點

  • 不需要提前指定群集數:凝聚型聚類不需要事先指定群集數量,可以通過樹狀圖觀察群集數目。
  • 生成層次結構:可以可視化整個聚類過程,清晰地展示數據點之間的層次關係,便於分析不同層級的聚類結果。
  • 可以應用不同的距離度量方法:允許根據需求選擇不同的距離計算方法,靈活性高。

缺點

  • 計算複雜度高:凝聚型聚類的時間複雜度較高,對於大規模數據集不夠高效,通常為 O(n3)。
  • 對異常值敏感:異常值會影響距離的計算,從而影響聚類結果。
  • 無法回溯:一旦合併兩個群集,就無法撤回決策,這可能導致次優解。


分裂型聚類(Divisive Clustering)

分裂型聚類是從整個數據集作為一個群集開始,然後逐步將其分裂成更小的群集,直到每個數據點成為單獨的群集或達到預定的群集數量。它是一種自頂向下的方法。


工作原理

  1. 將所有數據點視為一個群集:初始時,所有數據點被視為一個大的群集。
  2. 選擇一個群集進行分裂:根據某種規則,選擇一個現有群集進行分裂。
  3. 分裂群集:將該群集分裂成兩個或多個子群集。這通常通過一些分裂標準(例如:K-means、二分法等)來實現。
  4. 更新群集結構:重新計算各子群集之間的距離關係。
  5. 重複步驟:不斷選擇群集進行分裂,直到達到所需的群集數或每個數據點都成為單獨的群集。


應用場景

  • 社交網絡分析:用於分析社交網絡中的用戶層次結構,逐步將整個網絡分成更小的社群。
  • 組織結構分析:分析企業或團隊內部的組織結構,逐步劃分不同的工作小組。
  • 大型數據集分析:當數據量較大且整體結構較為復雜時,分裂型聚類有助於將數據逐步簡化成更小的部分。


程式碼範例

scikit-learn 並不直接支持分裂型聚類。常見的分裂型聚類可以通過 自頂向下 的策略來模擬,比如使用 K-means二分法 進行每步的分裂。

這裡我們用二分法(通過 K-means)來模擬分裂型聚類:

from sklearn.cluster import KMeans
from sklearn.datasets import load_iris
import pandas as pd

# 自定義一個分裂型聚類函數,遞歸進行 K-means 分裂
def divisive_clustering(X, max_clusters=3):
# 初始情況,將所有數據視為一個群集
df = pd.DataFrame(X)
df['Cluster'] = 0 # 所有數據點都標記為群集 0

current_cluster = 0
while current_cluster < max_clusters:
# 對當前群集進行 K-means 分裂成 2 個子群集
cluster_data = df[df['Cluster'] == current_cluster].drop(columns=['Cluster'])
if len(cluster_data) > 1: # 當群集內有多於1個點時才進行分裂
kmeans = KMeans(n_clusters=2, random_state=42)
sub_clusters = kmeans.fit_predict(cluster_data)

# 更新群集標籤
df.loc[df['Cluster'] == current_cluster, 'Cluster'] = sub_clusters + current_cluster + 1

current_cluster += 1

return df

# 加載數據集(以 iris 為例)
data = load_iris()
X = data.data

# 執行分裂型聚類
df = divisive_clustering(X, max_clusters=3)
print(df.head()) # 顯示前幾個樣本和它們的群集標籤

"""
0 1 2 3 Cluster
0 5.1 3.5 1.4 0.2 3
1 4.9 3.0 1.4 0.2 3
2 4.7 3.2 1.3 0.2 3
3 4.6 3.1 1.5 0.2 3
4 5.0 3.6 1.4 0.2 3
"""


分裂型聚類 優點與缺點

優點

  • 層次結構明確:自頂向下的聚類方式能清晰展示數據如何逐步分裂成更小的群集。
  • 靈活的分裂策略:可以使用不同的分裂策略來實現群集的劃分,根據需求進行調整。
  • 適合全局性數據結構分析:適合分析數據的整體結構,尤其是當你對數據整體的結構感興趣時。

缺點

  • 計算複雜度高:與凝聚型聚類一樣,分裂型聚類的時間複雜度較高,尤其是當數據集規模較大時,分裂操作需要更多計算。
  • 對初始分裂點敏感:初始選擇的分裂點對最終結果影響很大,次優的初始分裂可能導致整體分裂結果不佳。
  • 不常用:分裂型聚類相對凝聚型聚類來說,應用較少,因為它在每一步需要進行整體分裂,計算代價更高。


凝聚型聚類 vs 分裂型聚類 對比

raw-image


留言
avatar-img
留言分享你的想法!
avatar-img
JayRay 的沙龍
11會員
23內容數
JayRay 的沙龍的其他內容
2025/01/21
本文章提供深度學習(Deep Learning)、深度神經網絡(DNN)、卷積神經網絡(CNN)和遞歸神經網絡(RNN)的簡介,並包含它們的定義、應用場景、基本結構、工作原理、優缺點和Python範例。
Thumbnail
2025/01/21
本文章提供深度學習(Deep Learning)、深度神經網絡(DNN)、卷積神經網絡(CNN)和遞歸神經網絡(RNN)的簡介,並包含它們的定義、應用場景、基本結構、工作原理、優缺點和Python範例。
Thumbnail
2025/01/05
本篇文章提供描述性統計的完整指南,涵蓋集中趨勢、離散趨勢和數據分佈等重要概念,並附上豐富的實務應用案例與 Python 資料視覺化參考連結,協助讀者快速瞭解數據分析的基礎知識。
Thumbnail
2025/01/05
本篇文章提供描述性統計的完整指南,涵蓋集中趨勢、離散趨勢和數據分佈等重要概念,並附上豐富的實務應用案例與 Python 資料視覺化參考連結,協助讀者快速瞭解數據分析的基礎知識。
Thumbnail
2024/12/25
Naive Bayes是一種基於貝葉斯定理的機器學習分類演算法,適用於文本分類、垃圾郵件檢測及情感分析等任務。雖然假設特徵之間相互獨立,這在現實中不常成立,但其高效計算與穩定性使得在小數據集及高維度特徵空間中表現良好。
Thumbnail
2024/12/25
Naive Bayes是一種基於貝葉斯定理的機器學習分類演算法,適用於文本分類、垃圾郵件檢測及情感分析等任務。雖然假設特徵之間相互獨立,這在現實中不常成立,但其高效計算與穩定性使得在小數據集及高維度特徵空間中表現良好。
Thumbnail
看更多
你可能也想看
Thumbnail
TOMICA第一波推出吉伊卡哇聯名小車車的時候馬上就被搶購一空,一直很扼腕當時沒有趕緊入手。前陣子閒來無事逛蝦皮,突然發現幾家商場都又開始重新上架,價格也都回到正常水準,估計是官方又再補了一批貨,想都沒想就立刻下單! 同文也跟大家分享近期蝦皮購物紀錄、好用推薦、蝦皮分潤計畫的聯盟行銷!
Thumbnail
TOMICA第一波推出吉伊卡哇聯名小車車的時候馬上就被搶購一空,一直很扼腕當時沒有趕緊入手。前陣子閒來無事逛蝦皮,突然發現幾家商場都又開始重新上架,價格也都回到正常水準,估計是官方又再補了一批貨,想都沒想就立刻下單! 同文也跟大家分享近期蝦皮購物紀錄、好用推薦、蝦皮分潤計畫的聯盟行銷!
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
每年4月、5月都是最多稅要繳的月份,當然大部份的人都是有機會繳到「綜合所得稅」,只是相當相當多人還不知道,原來繳給政府的稅!可以透過一些有活動的銀行信用卡或電子支付來繳,從繳費中賺一點點小確幸!就是賺個1%~2%大家也是很開心的,因為你們把沒回饋變成有回饋,就是用卡的最高境界 所得稅線上申報
Thumbnail
Array可以說是各種語言除了基本型別之外,最常用的資料型別與容器之一了。 Array 這種連續格子狀的資料結構,在Python要怎麼表達呢? 建立一個空的陣列 最簡單也最直接的寫法就是 array = [] # Python list [] 就對應到大家熟知的array 陣列型態的資料結
Thumbnail
Array可以說是各種語言除了基本型別之外,最常用的資料型別與容器之一了。 Array 這種連續格子狀的資料結構,在Python要怎麼表達呢? 建立一個空的陣列 最簡單也最直接的寫法就是 array = [] # Python list [] 就對應到大家熟知的array 陣列型態的資料結
Thumbnail
題目敘述 Subarray Sums Divisible by K 給定一個整數陣列,請計算有幾個區間和能夠整除k的連續區間? 測試範例 Input: nums = [4,5,0,-2,-3,1], k = 5 Output: 7
Thumbnail
題目敘述 Subarray Sums Divisible by K 給定一個整數陣列,請計算有幾個區間和能夠整除k的連續區間? 測試範例 Input: nums = [4,5,0,-2,-3,1], k = 5 Output: 7
Thumbnail
給定一個輸入非負整樹陣列nums,請找出k值,使得陣列中恰好有k個元素大於等於 k。如果無解,回傳-1。尋找k值的方法包括排序法和二分搜尋法,時間複雜度都為O(n log n),空間複雜度為O(1)。關鍵知識點是當解空間具有遞增或遞減的性質時,可以用二分搜尋法加快搜尋效率。
Thumbnail
給定一個輸入非負整樹陣列nums,請找出k值,使得陣列中恰好有k個元素大於等於 k。如果無解,回傳-1。尋找k值的方法包括排序法和二分搜尋法,時間複雜度都為O(n log n),空間複雜度為O(1)。關鍵知識點是當解空間具有遞增或遞減的性質時,可以用二分搜尋法加快搜尋效率。
Thumbnail
子集合生成是一道經典的組合類上機考和面試題目。本篇文章介紹多個不同的解決方案,以及相關演算法框架。主要目標是給定n個相異的元素,產生所有的子集合。
Thumbnail
子集合生成是一道經典的組合類上機考和面試題目。本篇文章介紹多個不同的解決方案,以及相關演算法框架。主要目標是給定n個相異的元素,產生所有的子集合。
Thumbnail
題目敘述 題目會給我們一張Courses資料表,裡面分別有student、class等欄位。其中(student, class) 是這張資料表的複合主鍵Primary key pair。 要求我們,以課程做分群,列出至少有五位同學的課程。 輸出的順序不拘。 Table: Courses
Thumbnail
題目敘述 題目會給我們一張Courses資料表,裡面分別有student、class等欄位。其中(student, class) 是這張資料表的複合主鍵Primary key pair。 要求我們,以課程做分群,列出至少有五位同學的課程。 輸出的順序不拘。 Table: Courses
Thumbnail
複習一下: 我們學習了關於撰寫程式的相關觀念 條件分支(if/else) : 藉由條件分支讓程式執行相對應的功能。 迴圈(while loop ) :程式利用迴圈反覆執行某個區塊的程式碼。 字串處理 (string) : 每個程式都在處理資料,而字串是一種非常重要且常用的資料。 函式(fu
Thumbnail
複習一下: 我們學習了關於撰寫程式的相關觀念 條件分支(if/else) : 藉由條件分支讓程式執行相對應的功能。 迴圈(while loop ) :程式利用迴圈反覆執行某個區塊的程式碼。 字串處理 (string) : 每個程式都在處理資料,而字串是一種非常重要且常用的資料。 函式(fu
Thumbnail
How to utilize batch input and multi-processing techniques to accelerate feature engineering? 問題 在進行特徵工程的過程中,我們通常需要處理各種各樣的數據,並轉換它們成有意義的特徵,以供後續的模型訓練
Thumbnail
How to utilize batch input and multi-processing techniques to accelerate feature engineering? 問題 在進行特徵工程的過程中,我們通常需要處理各種各樣的數據,並轉換它們成有意義的特徵,以供後續的模型訓練
Thumbnail
陣列是Python語言的最基礎也最容易實作的資料結構,主要可以透過兩種方式在Python上實踐陣列,其中一種是靜態結構 - 串列(List),另一種則是動態結構 - 鏈結串列(Linked List)。 我們會依序介紹這兩種作法如何在Python上執行陣列的相關功能,並比較兩種方法之間的差異。
Thumbnail
陣列是Python語言的最基礎也最容易實作的資料結構,主要可以透過兩種方式在Python上實踐陣列,其中一種是靜態結構 - 串列(List),另一種則是動態結構 - 鏈結串列(Linked List)。 我們會依序介紹這兩種作法如何在Python上執行陣列的相關功能,並比較兩種方法之間的差異。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News