資料探勘之 層次聚類

ckxllf發表於2021-03-16

  1.概要:

  層次聚類方法將資料物件組成一顆聚類樹

  根據層次分解是以自底向上(合併)還是自頂向下(分裂)方式,層次聚類方法可以進一步分為凝聚和分裂的

  2.層次聚類方法:

  凝聚層次聚類:採用自底向上策略,首先將每個物件作為單獨的一個原子簇,然後合併這些原子簇形成越來越大的簇,直到所有的物件都在一個簇中(層次的最上層),或者達到某個終止條件。絕大多數層次聚類方法屬於這一類

  分裂層次聚類:採用自頂向下策略,首先將所有物件置於一個簇中,然後逐漸細分為越來越小的簇,直到每一個物件自成一個簇,或者達到某個終止條件,例如達到了某個希望的簇的數目,或者兩個最近的簇之間的距離超過了某個閾值

  下圖描述了一種凝聚層次聚類演算法AGENS和一種分裂層次聚類演算法DIANA對一個包含五個物件的資料集合{a,b,c,d,e}的處理過程

  初始,AGENS將每個物件自為一簇,然後這些簇根據某種準則逐步合併,直到所有的物件最終合併成一個簇

  例如,如果簇C1中的一個物件和簇C2中的一個物件之間的距離是所有屬於不同簇的物件間歐式距離最小的,則C1和C2 合併

  在DIANA中,所有的物件用於形成一個初始簇。根據某種原則(如,簇中最近的相鄰物件的最大歐式距離),將該簇分裂。簇的分裂過程反覆進行,直到最終每個新簇只包含一個物件

  在凝聚或者分裂層次聚類方法中,使用者可以定義希望得到的簇數目作為一個終止條件

  四個廣泛採用的簇間距離度量方法

  當演算法使用最小距離度量簇間距離時,有時稱它為最近鄰聚演算法。此外,如果當最近的簇之間的距離超過某個任意的閾值時聚類過程就會終止,則稱其為單連線演算法

  當一個演算法使用最大距離度量簇間距離時,有時稱為最遠鄰聚演算法。如果當最近簇之間的最大距離超過某個任意的閾值時聚類過程便終止,則稱其為全連線演算法

  3.例項:

  五個樣本如下所示,先將五個樣本都分別看成是一個簇,計算兩兩之間距離

  最靠近的兩個簇是3和4,合併得到新簇集合1,2,(3,4),5

  說明,當計算1和(3,4)距離時,取1分別和3,4距離的最小值

  接下來依次類推

  實驗原始碼:

  import math

  import numpy as np

  import pandas as pd

  import matplotlib.pyplot as plt

  from scipy.cluster.hierarchy import linkage,dendrogram

  # 從excel中讀取資料

  def load_data(path):

  # 從excel中讀取資料,並用dataframe儲存

  global df

  df = pd.read_excel(path)

  # 將dataframe中的資料值轉換為列表

  df_li = df.values.tolist()

  # 將儲存好資料的列表轉換為陣列

  dataSet = []

  for i in df_li:

  tmp = []

  tmp.append(i)

  dataSet.append(tmp)

  # 返回

  return dataSet

  # 計算歐式距離

  def distance(pointA,pointB):

  dis = 0

  for i in range(len(pointA)):

  dis += (pointA[i]-pointB[i])**2

  return math.sqrt(dis)

  # 尋找最小距離

  def Matrix_min(pointsA,pointsB,indexA,indexB,result):

  for pointA in pointsA:

  tmp_min_dis = 10000

  for pointB in pointsB:

  dis = distance(pointA,pointB)

  if dis < tmp_min_dis:

  tmp_min_dis = dis

  result.append({'indexA':indexA,'indexB':indexB,'dist':tmp_min_dis})

  # 利用最小簇間距離度量聚類

  def search_mindis(result):

  tmp_min_dis = 10000

  tmp_min_list = []

  for i in result:

  if i['dist'] < tmp_min_dis:

  tmp_min_dis = i['dist']

  tmp_min_list = [] 大連做人流哪裡好

  tmp_min_list.extend([i['indexA'],i['indexB']])

  elif i['dist'] == tmp_min_dis:

  tmp_min_list.extend([i['indexA'],i['indexB']])

  return list(set(tmp_min_list))

  # 層次聚類,合併樣本,並原資料集中刪除元素

  def mergeGroup(array, mergeIndexs):

  mergeIndexs.sort()

  rangeLen = len(mergeIndexs) - 1;

  for i in range(rangeLen):

  array[mergeIndexs[0]].extend(array[mergeIndexs[i+1]])

  mergeIndexs.reverse()

  for i in range(rangeLen):

  del array[mergeIndexs[i]]

  if __name__ == '__main__':

  # 載入資料

  data = []

  path = input(r'請輸入檔案路徑:')

  dataSet = load_data(path)

  print(dataSet)

  # 進行層次聚類

  k = int(input('請輸入聚類次數:'))

  while k-1 > 0:

  result = []

  for indexA,pointsA in enumerate(dataSet):

  for indexB,pointsB in enumerate(dataSet):

  if indexB > indexA:

  Matrix_min(pointsA,pointsB,indexA,indexB,result)

  mergeIndexs = search_mindis(result)

  mergeGroup(dataSet,mergeIndexs)

  k -= 1

  for item in dataSet:

  print(item)

  ## 視覺化

  z=linkage(df,method='ward',metric='euclidean')

  p = dendrogram(z,0)

  plt.show()

  符合理想效果

  資料集就是那五個樣本點

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69945560/viewspace-2763173/,如需轉載,請註明出處,否則將追究法律責任。

相關文章