1. 程式人生 > >一篇文章透徹解讀聚類分析及案例實操

一篇文章透徹解讀聚類分析及案例實操

1  聚類分析介紹

1.1 基本概念

聚類就是一種尋找資料之間一種內在結構的技術。聚類把全體資料例項組織成一些相似組,而這些相似組被稱作聚類。處於相同聚類中的資料例項彼此相同,處於不同聚類中的例項彼此不同。聚類技術通常又被稱為無監督學習,因為與監督學習不同,在聚類中那些表示資料類別的分類或者分組資訊是沒有的。

通過上述表述,我們可以把聚類定義為將資料集中在某些方面具有相似性的資料成員進行分類組織的過程。因此,聚類就是一些資料例項的集合,這個集合中的元素彼此相似,但是它們都與其他聚類中的元素不同。在聚類的相關文獻中,一個數據實例有時又被稱為物件,因為現實世界中的一個物件可以用資料例項來描述。同時,它有時也被稱作資料點(Data Point),因為我們可以用r 維空間的一個點來表示資料例項,其中r 表示資料的屬性個數。下圖顯示了一個二維資料集聚類過程,從該圖中可以清楚地看到資料聚類過程。雖然通過目測可以十分清晰地發現隱藏在二維或者三維的資料集中的聚類,但是隨著資料集維數的不斷增加,就很難通過目測來觀察甚至是不可能。

1.2 演算法概述

目前在存在大量的聚類演算法,演算法的選擇取決於資料的型別、聚類的目的和具體應用。大體上,主要的聚類演算法分為幾大類。

聚類演算法的目的是將資料物件自動的歸入到相應的有意義的聚類中。追求較高的類內相似度和較低的類間相似度是聚類演算法的指導原則。一個聚類演算法的優劣可以從以下幾個方面來衡量:

(1)可伸縮性:好的聚類演算法可以處理包含大到幾百萬個物件的資料集;

(2)處理不同型別屬性的能力:許多演算法是針對基於區間的數值屬性而設計的,但是有些應用需要針對其它資料型別(如符號型別、二值型別等)進行處理;

(3)發現任意形狀的聚類:一個聚類可能是任意形狀的,聚類演算法不能侷限於規則形狀的聚類;

(4)輸入引數的最小化:要求使用者輸入重要的引數不僅加重了使用者的負擔,也使聚類的質量

難以控制;

(5)對輸入順序的不敏感:不能因為有不同的資料提交順序而使聚類的結果不同;

(6)高維性:一個數據集可能包含若干維或屬性,一個好的聚類演算法不能僅侷限於處理二維

或三維資料,而需要在高維空間中發現有意義的聚類;

(7)基於約束的聚類:在實際應用中要考慮很多約束條件,設計能夠滿足特定約束條件且具

有較好聚類質量的演算法也是一項重要的任務;

(8)可解釋性:聚類的結果應該是可理解的、可解釋的,以及可用的。

1.3 聚類應用

在商業上,聚類分析被用來發現不同的客戶群,並且通過購買模式刻畫不同的客戶群的特徵。聚類分析是細分市場的有效工具,同時也可用於研究消費者行為,尋找新的潛在市場、選擇實驗的市場,並作為多元分析的預處理。在生物上,聚類分析被用來動植物分類和對基因進行分類,獲取對種群固有結構的認識。在地理上,聚類能夠幫助在地球中被觀察的資料庫商趨於的相似性。在保險行業上,聚類分析通過一個高的平均消費來鑑定汽車保險單持有者的分組,同時根據住宅型別,價值,地理位置來鑑定一個城市的房產分組。在因特網應用上,聚類分析被用來在網上進行文件歸類來修復資訊。在電子商務上,聚類分析在電子商務中網站建設

資料探勘中也是很重要的一個方面,通過分組聚類出具有相似瀏覽行為的客戶,並分析客戶的共同特徵,可以更好的幫助電子商務的使用者瞭解自己的客戶,向客戶提供更合適的服務。

2  kmeans 演算法

2.1 基本思想

劃分聚類演算法是根據給定的n 個物件或者元組的資料集,構建k 個劃分聚類的方法。每個劃分即為一個聚簇,並且k  n。該方法將資料劃分為k 個組,每個組至少有一個物件,每個物件必須屬於而且只能屬於一個組。1該方法的劃分採用按照給定的k 個劃分要求,先給出一個初始的劃分,然後用迭代重定位技術,通過物件在劃分之間的移動來改進劃分。

為達到劃分的全域性最優,劃分的聚類可能會窮舉所有可能的劃分。但在實際操作中,往往採用比較流行的k-means 演算法或者k-median 演算法。

2.2 演算法步驟

k-means 演算法最為簡單,實現比較容易。每個簇都是使用物件的平均值來表示。

步驟一:將所有物件隨機分配到k 個非空的簇中。

步驟二:計算每個簇的平均值,並用該平均值代表相應的值。

步驟三:根據每個物件與各個簇中心的距離,分配給最近的簇。

步驟四:轉到步驟二,重新計算每個簇的平均值。這個過程不斷重複直到滿足某個準則函式或者終止條件。終止(收斂)條件可以是以下任何一個:沒有(或者最小數目)資料點被重新分配給不同的聚類;沒有(或者最小數目)聚類中心再發生變化;誤差平方和(SSE)區域性最小。

其中, k 表示需要聚集的類的數目, Cj表示第j 個聚類,mj表示聚類Cj的聚類中心,

dist表示資料點x 和聚類中心mj之間的距離。利用該準則可以使所生成的簇儘可能

的緊湊和獨立。

SAS kmeans 實現主要是通過proc fastclus 過程實現,示例如下:

proc import datafile=”E:\SAS\cars.txt” out=cars dbms=dlm replace;

delimiter=’09’x;

getnames=yes;

run;

proc print data=cars;

run;

proc standard data=cars out=stdcars mean=0 std=1;

var Mpg Weight Drive_Ratio Horsepower Displacement;

run;

proc fastclus data=stdcars summary maxc=5 maxiter=99

outseed=clusterseed out=clusterresult cluster=cluster least=2;

id Car;

var Mpg Weight Drive_Ratio Horsepower Displacement;

run;

2.3 演算法分析

k-means 演算法對於大型的資料庫是相對高效的,一般情況下結束於區域性最優解。但是,k-means 演算法必須在平均值有意義的情況下才能使用,對分類變數不適用,事先還要給定生成聚類的數目,對異常資料和資料噪聲比較敏感,不能對非凸面形狀的資料進行處理。另外,k-means 演算法在聚類過程中可能有的聚類中心沒有被分配任何資料而使得某些聚類變為空,這些聚類通常被稱為空聚類。為了解決空聚類問題,我們可以選擇一個數據點作為替代的聚類中心。例如,某一個含有大量資料的聚類的聚簇中心最遠的資料點。如果演算法的終止條件取決於誤差平方和,具有最大誤差平方和的聚類可以被用來尋找另外的聚類中心。

3  層次聚類演算法

3.1 基本思想

層次聚類主要有兩種型別:合併的層次聚類和分裂的層次聚類。前者是一種自底向上的層次聚類演算法,從最底層開始,每一次通過合併最相似的聚類來形成上一層次中的聚類,整個當全部資料點都合併到一個聚類的時候停止或者達到某個終止條件而結束,大部分層次聚類都是採用這種方法處理。後者是採用自頂向下的方法,從一個包含全部資料點的聚類開始,然後把根節點分裂為一些子聚類,每個子聚類再遞迴地繼續往下分裂,直到出現只包含一個數據點的單節點聚類出現,即每個聚類中僅包含一個數據點。

層次聚類技術是一種無監督學習的技術,因此可能沒有確定的、一致的正確答案。正是由於這個原因,並且在聚類的特定應用的基礎之上,可以設計出較少或較多數量的簇。定義了一個聚類層次,就可以選擇希望數量的簇。在極端的情況下,所有的物件都自成一簇。在這樣的情形下,聚類的物件之間非常相似,並且不同於其他的聚類。當然,這種聚類技術就失去了實際意義,因為聚類的目的是尋找資料集中的有意義的模式,方便使用者理解,而任何聚類的數目和資料物件一樣多的聚類演算法都不能幫助使用者更好地理解資料,挖掘資料隱藏的真實含義。這樣,關於聚類的很重要的一點就是應該比原先的資料的數目更少的簇。到底要形成多少個聚類數目,要根據實際業務的理解,這是如何解釋實際專案的事情。層次聚類演算法的好處是它可以讓使用者從這些簇中選擇所感興趣的簇,這樣更具有靈活性。

層次聚類通常被看做成一棵樹,其中最小的簇合並在一起建立下一個較高層次的簇,這一層次的簇再合併在一起就建立了再下一層次的簇。通過這樣的過程,就可以生成一系列的聚類樹來完成聚類。單點聚類處在樹的最底層,在樹的底層有一個根節點聚類。根節點聚類覆蓋了全部資料節點,兄弟節點聚類則劃分了它們共同的父節點中的所有的資料點。圖1-5是採用統計分析軟體SAS對Cars2資料集進行層次聚類的層次聚類結果圖。通過該層次聚類樹,使用者可以選擇檢視在樹的各個層次上的聚類情況。

基於層次的聚類演算法方法比較簡單,但是缺乏伸縮性,一旦一個合併或者分裂被執行,就不能撤銷。為了改進層次聚類的效果,可以將層次聚類演算法和其他聚類演算法結合使用,形成多階段的聚類演算法。

3.2 演算法步驟

層次聚類(hierarchical clustering)演算法遞迴的對物件進行合併或者分裂,直到滿足某一終止條件為止。層次聚類分為兩種,按自底向上層次分解稱為聚合的層次聚類,反之,稱為分解的層次聚類。層次聚類演算法的計算複雜度為O(n2),適合小型資料集的分類。

CURE、ROCK、BIRCH和CHAMELEON是聚合層次聚類中最具代表性的方法。CURE(Clustering Using REpresentatives)演算法採用了抽樣和分割槽的技術,選擇資料空間中固定數目的、具有代表性的一些點來代表相應的類,這樣就可以識別具有複雜形狀和不同大小的聚類,從而很好的過濾孤立點。ROCK(RObust Clustering using linKs)演算法是對CURE演算法的改進,除了具有CURE演算法的一些優良特性外,還適用於類別屬性的資料。BIRCH(Balanced Iterative Reducing and Clustering using Hierarchy)演算法首次提出了通過區域性聚類對資料庫進行預處理的思想。CHAMELEON是Karypis等人1999年提出的,它在聚合聚類的過程中利用了動態建模技術。

SAS例項

options nocenter nodate pageno=1 linesize=132;

title h = 1 j = l ‘File: cluster.mammalsteeth.sas’;

title2 h = 1 j = l ‘Cluster Analysis of Mammals” teeth data’;

data teeth;

input mammal $ 1-16

@wf0007 (v1-v8) (1.);

label v1=’Top incisors’

v2=’Bottom incisors’

v3=’Top canines’

v4=’Bottom canines’

v5=’Top premolars’

v6=’Bottom premolars’

v7=’Top molars’

v8=’Bottom molars’;

cards;

BROWN BAT 23113333

MOLE 32103333

SILVER HAIR BAT 23112333

PIGMY BAT 23112233

HOUSE BAT 23111233

RED BAT 13112233

PIKA 21002233

RABBIT 21003233

BEAVER 11002133

GROUNDHOG 11002133

GRAY SQUIRREL 11001133

HOUSE MOUSE 11000033

PORCUPINE 11001133

WOLF 33114423

BEAR 33114423

RACCOON 33114432

MARTEN 33114412

WEASEL 33113312

WOLVERINE 33114412

BADGER 33113312

RIVER OTTER 33114312

SEA OTTER 32113312

JAGUAR 33113211

COUGAR 33113211

FUR SEAL 32114411

SEA LION 32114411

GREY SEAL 32113322

ELEPHANT SEAL 21114411

REINDEER 04103333

ELK 04103333

DEER 04003333

MOOSE 04003333

;

proc princomp data=teeth out=teeth2;

var v1-v8;

run;

proc cluster data=teeth2 method=average outtree=ttree

ccc pseudo rsquare;

var v1-v8;

id mammal;

run;

proc tree data=ttree out=ttree2 nclusters=4;

id mammal;

run;

proc sort data=teeth2;

by mammal;

run;

proc sort data=ttree2;

by mammal;

run;

data teeth3;

merge teeth2 ttree2;

by mammal;

run;

symbol1 c=black f=, v=’1′;

symbol2 c=black f=, v=’2′;

symbol3 c=black f=, v=’3′;

symbol4 c=black f=, v=’4′;

proc gplot;

plot prin2*prin1=cluster;

run;

proc sort;

by cluster;

run;

proc print;

by cluster;

var mammal prin1 prin2;

run;

4  SAS聚類分析案例

1 問題背景

考慮下面案例,一個棒球管理員希望根據隊員們的興趣相似性將他們進行分組。顯然,在該例子中,沒有響應變數。管理者希望能夠方便地識別出隊員的分組情況。同時,他也希望瞭解不同組之間隊員之間的差異性。

該案例的資料集是在SAMPSIO庫中的DMABASE資料集。下面是資料集中的主要的變數的描述資訊:

在這個案例中,設定TEAM,POSITION,LEAGUE,DIVISION和SALARY變數的模型角色為rejected,設定SALARY變數的模型角色為rejected是由於它的資訊已經儲存在LOGSALAR中。在聚類分析和自組織對映圖中是不需要目標變數的。如果需要在一個目標變數上識別分組,可以考慮預測建模技術或者定義一個分類目標。

2 聚類方法概述

聚類分析經常和有監督分類相混淆,有監督分類是為定義的分類響應變數預測分組或者類別關係。而聚類分析,從另一方面考慮,它是一種無監督分類技術。它能夠在所有輸入變數的基礎上識別出資料集中的分組和類別資訊。這些組、簇,賦予不同的數字。然而,聚類數目不能用來評價類別之間的近似關係。自組織對映圖嘗試建立聚類,並且在一個圖上用圖形化的方式繪製出聚類資訊,在此處我們並沒有考慮。

1) 建立初始資料流

2) 設定輸入資料來源結點

開啟輸入資料來源結點

從SAMPSIO庫中選擇DMABASE資料集

設定NAME變數的模型角色為id,TEAM,POSIOTION,LEAGUE,DIVISION和SALARY變數的模型角色為rejected

探索變數的分佈和描述性統計資訊

選擇區間變數選項卡,可以觀察到只有LOGSALAR和SALARY變數有缺失值。選擇類別變數選項卡,可以觀察到沒有缺失值。在本例中,沒有涉及到任何類別變數。

關閉輸入資料來源結點,並儲存資訊。

3) 設定替代結點

雖然並不是總是要處理缺失值,但是有時候缺失值的數量會影響聚類結點產生的聚類解決方案。為了產生初始聚類,聚類結點往往需要一些完整的觀測值。當缺失值太多的時候,需要用替代結點來處理。雖然這並不是必須的,但是在本例中使用到了。

4) 設定聚類結點

開啟聚類結點,啟用變數選項卡。K-means聚類對輸入資料是敏感的。一般情況下,考慮對資料集進行標準化處理。

在變數選項卡,選擇標準偏差單選框

選擇聚類選項卡

觀察到預設選擇聚類數目的方法是自動的

關閉聚類結點

5) 聚類結果

在聚類結點處執行流程圖,檢視聚類結果。

6) 限定聚類數目

開啟聚類結點

選擇聚類選項卡

在聚類數目選擇部分,點選選擇標準按鈕

輸入最大聚類數目為10

點選ok,關閉聚類結點

7)結果解釋

我們可以定義每個類別的資訊,結合背景識別每個型別的特徵。選擇箭頭按鈕,

選擇三維聚類圖的某一類別,
在工具欄選擇重新整理輸入均值圖圖示,
點選該圖示,可以檢視該類別的規範化均值圖

同理,可以根據該方法對其他類別進行解釋。

8)運用Insight結點

Insight結點可以用來比較不同屬性之間的異常。開啟insight結點,選擇整個資料集,關閉結點。

從insight結點處執行。

變數_SEGMNT_標識類別,distance標識觀測值到所在類別中心的距離。運用insight視窗的analyze工具評估和比較聚類結果。

首先把_SEGMNT_的度量方式從interval轉換成nominal。

R語言篇

以R基礎包自帶的鳶尾花(Iris)資料進行聚類分析。分析程式碼如下:

###### 程式碼清單 #######

data(iris); attach(iris)

iris.hc <- hclust( dist(iris[,1:4]))

# plot( iris.hc, hang = -1)

plclust( iris.hc, labels = FALSE, hang = -1)

re <- rect.hclust(iris.hc, k = 3)

iris.id <- cutree(iris.hc, 3)

table(iris.id, Species)

###### 執行結果 #######

> table(iris.id,Species)

Species

iris.id setosa versicolor virginica

1 50 0 0

2 0 23 49

3 0 27 1

聚類分析生成的圖形如下:

結果表明,函式cuttree()將資料iris分類結果iris.hc編為三組分別以1,2, 3表示,儲存在iris.id中。將iris.id與iris中Species作比較發現:1應該是setosa類,2應該是virginica類(因為virginica的個數明顯多於versicolor),3是versicolor。

仍以R基礎包自帶的鳶尾花(Iris)資料進行K-均值聚類分析,分析程式碼如下:

###### 程式碼清單 #######

library(fpc)

data(iris)

df<-iris[,c(1:4)]

set.seed(252964) # 設定隨機值,為了得到一致結果。

(kmeans <- kmeans(na.omit(df), 3)) # 顯示K-均值聚類結果

plotcluster(na.omit(df), kmeans$cluster) # 生成聚類圖

生成的圖如下:

Python篇

Python執行條件:

1.Python執行環境與編輯環境;

2.Matplotlib.pyplot圖形庫,可用於快速繪製2D圖表,與matlab中的plot命令類似,而且用法也基本相同。

# coding=utf-8

##

作者:Chan

程式:kmeans演算法

##

import matplotlib.pyplot as plt

import math

import numpy

import random

#dotOringalNum為各個分類最初的大小

dotOringalNum=100

#dotAddNum最後測試點的數目

dotAddNum=1000

fig = plt.figure()

ax = fig.add_subplot(111)

sets=

colors=[‘b’,’g’,’r’,’y’]

#第一個分類,顏色為藍色,在左下角

a=

txx=0.0

tyy=0.0

for i in range(0,dotOringalNum):

tx=float(random.randint(1000,3000))/100

ty=float(random.randint(1000,3000))/100

a.append([tx,ty])

txx+=tx

tyy+=ty

#ax.plot([tx],[ty],color=colors[0],linestyle=”,marker=’.’)

#a的第一個元素為a的各個元素xy值之合

a.insert(0,[txx,tyy])

sets.append(a)

#第二個分類,顏色為綠色,在右上角

b=

txx=0.0

tyy=0.0

for i in range(0,dotOringalNum):

tx=float(random.randint(4000,6000))/100

ty=float(random.randint(4000,6000))/100

b.append([tx,ty])

txx+=tx

tyy+=ty

#ax.plot([tx],[ty],color=colors[1],linestyle=”,marker=’.’)

b.insert(0,[txx,tyy])

sets.append(b)

#第三個分類,顏色為紅色,在左上角

c=

txx=0.0

tyy=0.0

for i in range(0,dotOringalNum):

tx=float(random.randint(1000,3000))/100

ty=float(random.randint(4000,6000))/100

c.append([tx,ty])

txx+=tx

tyy+=ty

#ax.plot([tx],[ty],color=colors[2],linestyle=”,marker=’.’)

c.insert(0,[txx,tyy])

sets.append(c)

#第四個分類,顏色為黃色,在右下角

d=

txx=0

tyy=0

for i in range(0,dotOringalNum):

tx=float(random.randint(4000,6000))/100

ty=float(random.randint(1000,3000))/100

d.append([tx,ty])

txx+=tx

tyy+=ty

#ax.plot([tx],[ty],color=colors[3],linestyle=”,marker=’.’)

d.insert(0,[txx,tyy])

sets.append(d)

#測試

for i in range(0,dotAddNum):

tx=float(random.randint(0,7000))/100

ty=float(random.randint(0,7000))/100

dist=9000.0

setBelong=0

for j in range(0,4):

length=len(sets[j])-1

centX=sets[j][0][0]/length

centY=sets[j][0][1]/length

if (centX-tx)*(centX-tx)+(centY-ty)*(centY-ty)

執行效果:

來源:天善問答社群