DIISSive ANAlysis(DIANA)分层聚类

时间:2015-08-26 14:12:16

标签: python algorithm cluster-analysis hierarchical-clustering

(这篇文章是关于分裂层次聚类算法的previous问题的延续。)

问题是如何用Python(或任何其他语言)实现这个算法。

算法说明

分裂聚类通过一系列连续分裂进行。在步骤0,所有对象在一个集群中。在每个步骤中,分割一个簇,直到步骤n - 1所有数据对象分开(形成n个簇,每个簇都有一个对象)。

每个步骤划分一个群集,让我们将其称为R分为两个群集AB。最初,A等于RB为空。在第一阶段,我们必须将一个对象从A移动到B。对于i的每个对象A,我们计算A的所有其他对象的平均差异:

enter image description here

上面的等式达到其最大值的对象i'将被移动,所以我们把

enter image description here

在接下来的阶段,我们会寻找其他要点从A移至B。只要A仍然包含多个对象,我们就会计算

enter image description here

对于i的每个对象A,我们会考虑最大化此数量的对象i''。当上面等式的最大值严格为正时,我们将i''A移动到B,然后在新A中查找可能被移动的另一个对象。另一方面,当差异的最大值为负或0时,我们停止该过程,R分为AB已完成。

在分裂算法的每一步,我们还必须决定要分割哪个群集。为此,我们计算直径

enter image description here

对于上一步之后可用的每个群集Q,并选择直径最大的群集。

我的起始代码粘贴在下面。实际上脚本会返回ValueError: list.remove(x): x not in list

# Dissimilarity matrix
dm = [
[ 0, 2, 6, 10, 9],
[ 2, 0, 5,  9, 8],
[ 6, 5, 0,  4, 5],
[10, 9, 4,  0, 3],
[ 9, 8, 5,  3 ,0]]

# Create splinter and remaining group
splinter = []
remaining = range(len(dm))

# Find record ra that has the greatest average distance from the rest of the records
ra = 0
dMax = -999
for i in range(len(dm)):
  dSum = 0
  for j in range(len(dm)):
    if i == j:
      continue
    dSum += dm[i][j]
  if dMax < dSum:
    dMax = dSum
    ra = i

splinter.append(ra)
remaining.remove(ra)

# Check every record in remaining  and moves the record if record is closer to splinter
bChanged = True
while bChanged:
  bChanged = False
  for i in range(len(remaining)):
    d1 = 0.0
    for j in range(len(splinter)):
      d1 += dm[i][j]
    d1 /= float(len(splinter))
    d2 = 0.0
    for k in range(len(remaining)):
      if i == k:
        continue
      d2 += dm[i][k]
    if len(remaining) > 1:
      d2 /= (len(remaining) - 1.0)
    if d1 < d2:
      bChanged = True
      splinter.append(i)
      remaining.remove(i)
      break

0 个答案:

没有答案