1. 程式人生 > >【機器學習】層次聚類

【機器學習】層次聚類

寫在篇前

  層次聚類(hierarchical clustering)是一種通用的聚類演算法之一,它通過自下而上合併或自上而下拆分來構建巢狀聚類。這種簇的層次結構表示為樹(或樹狀圖),樹的根匯聚所有樣本,樹的葉子是各個樣本。本篇部落格會簡述層次聚類的原理,重點是使用sklearn、scipy、seaborn等實現層次聚類並可視化結果。

原理簡述

  看到一篇詳細講層次聚類原理的文章層次聚類演算法的原理及實現Hierarchical Clustering,講的通俗易懂,一看便知,這裡主要講一下Metrics(請保證sklearn >=0.20):

  1. Ward:minimizes所有聚類中的平方差和,它是一種方差最小化方法,在這個意義上類似於

    kmeans
    E=i=1kxCixμi22 E = \sum\limits_{i=1}^k\sum\limits_{x \in C_i} ||x-\mu_i||_2^2

  2. complete linkage:minimizes兩個簇的樣本對之間距離的最小值
    dmin(Ci,Cj)=minxiCi,xjCjdistance(xi,xj) d_{min}(C_i,C_j)=\min_{\vec{x}_i\in C_i,\vec{x}_j\in C_j}distance(\vec{x}_i,\vec{x}_j)

  3. Average linkage:minimizes兩個簇的樣本對之間距離的平均值
    davg(Ci,Cj)=1CiCjxiCixjCjdistance(xi,xj) d_{avg}(C_i,C_j)=\frac{1}{|C_i||C_j|}\sum_{\vec{x}_i\in C_i}\sum_{\vec{x}_j\in C_j}distance(\vec{x}_i,\vec{x}_j)

    Cjdistance(xi,xj)

  4. Single linkage: minimizes兩個簇的樣本對之間距離的最大值
    dmax(Ci,Cj)=maxxiCi,xjCjdistance(xi,xj) d_{max}(C_i,C_j)=\max_{\vec{x}_i\in C_i,\vec{x}_j\in C_j}distance(\vec{x}_i,\vec{x}_j)

演算法實現

  sklearn中實現的層次聚類實際上是自下而上合併的方式,通過from sklearn.cluster import AgglomerativeClustering匯入層次聚類的封裝類。

from sklearn.cluster import AgglomerativeClustering

clu = AgglomerativeClustering(n_clusters=2,
                              affinity='euclidean',
                              linkage='ward', compute_full_tree=False)
# --------------------------屬性--------------------------

#   基礎(類)屬性
print('n_clusters:', clu.n_clusters)
print('affinity:', clu.affinity)
print('memory:', clu.memory)
print('connectivity:', clu.connectivity)
print('compute_full_tree:', clu.compute_full_tree)
print('linkage:', clu.linkage)
print('pooling_func:', clu.pooling_func)

#   重要屬性
print('labels_:', clu.labels_)  # 樣本聚類結果標籤
print('children_:', clu.children_)  # 每一個非葉子結點的孩子數
print('n_components_:', clu.n_components_)  # 連線圖中連通分量的估計值
print('n_leaves_:', clu.n_leaves_)  # 層次聚類樹中葉子數目

# --------------------------函式--------------------------
print('get_params:', clu.get_params())  # 與set_params()相對應

# fit()、fit_predict()函式放到案例裡面講解

案例

基礎案例

   官方給了一個很好的案例,我們可以看一下(scikit-learn 0.20 or later):

#! /usr/bin/python
# _*_ coding: utf-8 _*_
__author__ = 'Jeffery'
__date__ = '2018/11/12 17:45'


import time
import warnings
import numpy as np
import matplotlib.pyplot as plt

from sklearn import cluster, datasets
from sklearn.preprocessing import StandardScaler
from itertools import cycle, islice

np.random.seed(0)

######################################################################
# Generate datasets. We choose the size big enough to see the scalability
# of the algorithms, but not too big to avoid too long running times

n_samples = 1500
noisy_circles = datasets.make_circles(n_samples=n_samples, factor=.5, noise=.05)
noisy_moons = datasets.make_moons(n_samples=n_samples, noise=.05)
blobs = datasets.make_blobs(n_samples=n_samples, random_state=8)
no_structure = np.random.rand(n_samples, 2), None
# Anisotropicly distributed data
random_state = 170
X, y = datasets.make_blobs(n_samples=n_samples, random_state=random_state)
transformation = [[0.6, -0.6], [-0.4, 0.8]]
X_aniso = np.dot(X, transformation)
aniso = (X_aniso, y)
# blobs with varied variances
varied = datasets.make_blobs(n_samples=n_samples,
                             cluster_std=[1.0, 2.5, 0.5],
                             random_state=random_state)
# data shape:
# noisy_circles:(1500, 2)
# noisy_moons: (1500, 2)
# varied(blobs): (1500, 2)
# blobs: (1500, 2)
# aniso: (1500, 2)
# no_structure:(1500, 2)  no labels

######################################################################
# Run the clustering and plot

# Set up cluster parameters
plt.figure(figsize=(9 * 1.3 + 2, 14.5))
plt.subplots_adjust(left=.02, right=.98, bottom=.001, top=.96, wspace=.05,
                    hspace=.01)

plot_num = 1
default_base = {'n_clusters': 3}
datasets = [
    (noisy_circles, {'n_clusters': 2}),
    (noisy_moons, {'n_clusters': 2}),
    (varied, {}),
    (aniso, {}),
    (blobs, {}),
    (no_structure, {})]


for i_dataset, (dataset, algo_params) in enumerate(datasets):
    # update parameters with dataset-specific values
    params = default_base.copy()
    params.update(algo_params)

    X, y = dataset

    # normalize dataset for easier parameter selection
    X = StandardScaler().fit_transform(X)

    # ============
    # Create cluster objects
    # ============
    ward = cluster.AgglomerativeClustering(
        n_clusters=params['n_clusters'], linkage='ward')
    complete = cluster.AgglomerativeClustering(
        n_clusters=params['n_clusters'], linkage='complete')
    average = cluster.AgglomerativeClustering(
        n_clusters=params['n_clusters'], linkage='average')
    single = cluster.AgglomerativeClustering(
        n_clusters=params['n_clusters'], linkage='single')

    clustering_algorithms = (
        ('Single Linkage', single),
        ('Average Linkage', average),
        ('Complete Linkage', complete),
        ('Ward Linkage', ward),
    )

    for name, algorithm in clustering_algorithms:
        t0 = time.time()
        algorithm.fit(X)

        t1 = time.time()
        if hasattr(algorithm, 'labels_'):
            y_pred = algorithm.labels_.astype(np.int)
        else:
            y_pred = algorithm.predict(X)

        plt.subplot(len(datasets), len(clustering_algorithms), plot_num)
        if i_dataset == 0:
            plt.title(name, size=18)

        colors = np.array(list(islice(cycle(['#377eb8', '#ff7f00', '#4daf4a',
                                             '#f781bf', '#a65628', '#984ea3',
                                             '#999999', '#e41a1c', '#dede00']),
                                      int(max(y_pred) + 1))))

        plt.scatter(X[:, 0], X[:, 1], s=10, color=colors[y_pred])
        plt.xlim(-2.5, 2.5)
        plt.ylim(-2.5, 2.5)
        plt.xticks(())
        plt.yticks(())
        plt.text(.99, .01, ('%.2fs' % (t1 - t0)).lstrip('0'),
                 transform=plt.gca().transAxes, size=15,
                 horizontalalignment='right')
        plot_num += 1

plt.show()

在這裡插入圖片描述
通過以上案例我們應該學習到:

  • single linkage速度快,並且可以在非球狀資料上表現良好,但是在存在噪聲的情況下它表現不佳;
  • average linkage和complete linkage在‘乾淨’的球狀資料上表現良好;
  • Ward是應對噪聲資料最有效的方法;
  • 層次聚類一般不能直接適用於高維資料

進階案例

樹狀圖

  對於層次聚類,我們一般還會構建聚類樹或生成熱圖,這就是我們下面要探討的問題。但是其中還會牽涉一些原理,包括natural divisions、dissimilarity(cophenetic correlation coefficient.)、disconsistency等,請參考層次聚類原理解析

import pandas as pd
from scipy.cluster import hierarchy
import matplotlib.pyplot as plt
import numpy as np

my_data = np.random.random(size=[10, 4])
my_data = pd.DataFrame(my_data, index=(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
                       columns='A B C D'.split())

Z = hierarchy.linkage(my_data,
                      method='ward',
                      metric='euclidean',
                      optimal_ordering=False)
print(type(Z), '\n', Z)  # 這個有必要解釋一下
hierarchy.dendrogram(Z)
plt.show()

在這裡插入圖片描述
在這裡插入圖片描述

# 可以繼續對樹進行剪枝
# n_clusters和height只能二選其一
label = cluster.hierarchy.cut_tree(Z, n_clusters=2, height=None) 

# label:(可以對比上圖驗證結果的正確性)
[[0]
 [1]
 [0]
 [0]
 [1]
 [1]
 [1]
 [0]
 [1]
 [0]]

  分割聚類樹,將其生成多個不同的cluster還有一種方式:

# 分割cluster
labels = fcluster(Z, t=0.7, criterion='inconsistent')
print(labels)

引數說明:

  1. 當criterion為’inconsistent’時,t值應該在0-1之間波動,t越接近1代表兩個資料之間的相關性越大,t越趨於0表明兩個資料的相關性越小。
  2. 當criterion為’distance’時,t值代表了絕對的差值,如果小於這個差值,兩個資料將會被合併,當大於這個差值,兩個資料將會被分開。
  3. 當criterion為’maxclust’時,t代表了最大的聚類的個數。
  4. 當criterion為’monocrit’時,t的選擇不是固定的,而是根據一個函式monocrit[j]來確定。
熱圖

  上面的圖呢,形式比較簡單,有時候我們更希望我們能夠畫出更加炫酷的聚類圖,這個時候我們就會想到繪製clustermap,這是我們可以用到

相關推薦

機器學習層次

寫在篇前   層次聚類(hierarchical clustering)是一種通用的聚類演算法之一,它通過自下而上合併或自上而下拆分來構建巢狀聚類。這種簇的層次結構表示為樹(或樹狀圖),樹的根匯聚所有樣本,樹的葉子是各個樣本。本篇部落格會簡述層次聚類的原理,重點

機器學習---密度從初識到應用

max 一個 eight log div 指定 聚類 空間 mar 一.前述 密度聚類是一種能降噪的算法。 二.相關概念 先看些抽象的概念(官方定義): 1.:對象O的是與O為中心,為半徑的空間,參數,是用戶指定每個對象的領域半徑值。 2.MinPts(領域密度閥值):對象

機器學習Kmeans

寫在篇前   Kmeans演算法是一種經典的聚類演算法,屬於無監督學習的範疇。所謂聚類,即指對於給定的一個樣本集,按照樣本之間的距離大小,將樣本集劃分為K個簇,且讓簇內的點儘量緊密的連在一起,而讓簇間的距離儘量的大。 優點: 原理簡單 速度快 對大資料集有比較

機器學習常用演算法原型

1. 聚類簡介 在機器學習中,分為監督學習、無監督學習和半監督學習。前一篇部落格中提到的迴歸和分類都屬於監督學習,本文著重探討無監督學習中的聚類演算法。 博主之前看過一些資料,這兩天也翻閱了網上的各大部落格後,也想總結一下,寫一寫聚類相關的知識點,對

Python機器學習——Agglomerative層次

條件 分享圖片 n-2 mov unique ber and 兩個 its 層次聚類(hierarchical clustering)可在不同層次上對數據集進行劃分,形成樹狀的聚類結構。AggregativeClustering是一種常用的層次聚類算法。 ??其原理是:最初

機器學習層次及程式碼示例

一、層次聚類 層次聚類是無監督學習方法,可對給定的N個待聚類的樣本進行層次的分類,直到某種條件(類的個數、類間的距離超過某個閾值)滿足為止。 1、層次聚類的劃分 對於層次聚類,可具體分為: a. 凝聚的(agglomerative)層次聚類: 採用

機器學習(4)--層次(hierarchical clustering)基本原理及實現簡單圖片分類

關於層次聚類(hierarchical clustering)的基本步驟: 1、假設每個樣本為一類,計算每個類的距離,也就是相似度 2、把最近的兩個合為一新類,這樣類別數量就少了一個 3、重新新類與各個舊類(去了那兩個合併的類)之間的相似度; 4、迴圈重複2和3直到所有樣本

機器學習層次演算法

        層次聚類(Hierarchical Clustering)是對給定資料集在不同層次進行劃分,形成樹形的聚類結構,直到滿足某種停止條件為止。資料集的劃分可採用自底向上或自頂向下的劃分策略。1、凝聚的層次聚類演算法AGNES        AGNES(AGglom

機器學習層次演算法-1HCA(Hierarchical Clustering Alg)的原理講解 + 示例展示數學求解過程

層次聚類(Hierarchical Clustering)是聚類演算法的一種,通過計算不同類別資料點間的相似度來建立一棵有層次的巢狀聚類樹。在聚類樹中,不同類別的原始資料點是樹的最低層,樹的頂層是一個聚類的根節點。建立聚類樹有自下而上合併和自上而下分裂兩種方法,本篇文章介紹合併方法。層次聚類的合併演算法層次聚

機器學習演算法:層次

本文是“漫談 Clustering 系列”中的第 8 篇,參見本系列的其他文章。 系列不小心又拖了好久,其實正兒八經的 blog 也好久沒有寫了,因為比較忙嘛,不過覺得 Hierarchical Clustering 這個話題我能說的東西應該不多,所以還是先寫了吧(我準

機器學習演算法:層次、K-means

     所謂聚類,就是將相似的事物聚集在一 起,而將不相似的事物劃分到不同的類別的過程,是資料分析之中十分重要的一種手段。比如古典生物學之中,人們通過物種的形貌特徵將其分門別類,可以說就是 一種樸素的人工聚類。如此,我們就可以將世界上紛繁複雜的資訊,簡化為少數方便人們理解的類別,可以說是人類認知這個

機器學習筆記之Cluster—— 層次 Hierarchical clustering

什麼是層次聚類Hierarchical clustering? 平面聚類是高效且概念上簡單的,但它有許多缺點。 演算法返回平坦的非結構化簇集合,需要預先指定的簇數目作為輸入並且這個數目是不確定的。 分層聚類(或分層聚類)輸出層次結構,這種結構比平面聚類返回的非結構化聚類

機器學習DBSCAN Algorithms基於密度的算法

多次 使用 缺點 有效 結束 基於 需要 att 共享 一、算法思想: DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一個比較有代表性的基於密度的聚

機器學習接地氣地解釋K-means演算法

       俗話說“物以類聚,人以群分”,這句話在K-means聚類演算法裡面得到了充分的繼承。而K-means演算法的實際應用範圍可謂是大到無法估量,基本可以說,只要你想不到,沒有聚類聚不起來的東西!       &nbs

機器學習K-means演算法初探

資料聚類是對於靜態資料分析的一門技術,在許多領域內都被廣泛地應用,包括機器學習、資料探勘、模式識別、影象分析、資訊檢索以及生物資訊等。聚類是把相似的物件通過靜態分類的方法分成不同的組別或者更多的子集,這樣讓在同一個子集中的成員物件都有相似的一些屬性,常見的包括在座標系中

機器學習人像識別(三)——K-Means

簡介   K-Means聚類是一種非監督的聚類方式,原理參看資料探勘十大演算法 | k-means。    程式碼 import sys import random import numpy as np from sklearn.decomposit

王小草機器學習筆記--無監督演算法之

標籤(空格分隔): 王小草機器學習筆記 1. 聚類的概述 存在大量未標註的資料集,即只有特徵,沒有標籤的資料。 根據這些特徵資料計算樣本點之間的相似性。 根據相似性將資料劃分到多個類別中。 使得,同一個類別內的資料相似度大,類別之間的資料相似度小。

機器學習

1. 距離計算   當對一些沒有 Label 的資料進行分類的時候,需要滿足一些的基本性質: 非負性:dist(xi,xj)≥0dist(xi,xj)≥0; 同一性:dist(xi,xj)=0dist(xi,xj)=0,當且僅當 xi=xjxi=xj; 對

機器學習:Kmeans均值演算法原理(附帶Python程式碼實現)

這個演算法中文名為k均值聚類演算法,首先我們在二維的特殊條件下討論其實現的過程,方便大家理解。 第一步.隨機生成質心 由於這是一個無監督學習的演算法,因此我們首先在一個二維的座標軸下隨機給定一堆點,並隨即給定兩個質心,我們這個演算法的目的就是將這一堆點根據它們自身的座標特徵分為兩類,因此選取了兩個質心,什麼時

Matlab層次並繪製氣泡圖

%% 層次聚類 Ncluster=5; %聚類個數 %% data xx=[0.7480 0.3852 1.6347; 0.0232 0.4712 1.5317; 0.5345 1.2082 1.6758; 1.4