在R中按距离聚类

时间:2013-06-21 06:11:06

标签: r cluster-analysis

我有一个整数向量,我希望将其分成簇,以便任意两个簇之间的距离大于下限,并且在任何簇中,两个元素之间的距离小于上限。

例如,假设我们有以下向量:

1,4,5,6,9,29,32,36

并将上述下限和上限分别设置为19和9,下面的两个向量应该是可能的结果:

1,4,5,6,9

29,32,36


感谢@flodel的评论,我意识到这种聚类可能是不可能的。所以我想稍微修改一下这些问题:

如果我只将强加到群集距离下限,那么可能的聚类方法是什么? 如果我只将强加在群集距离上限内,那么可能的聚类方法是什么?

2 个答案:

答案 0 :(得分:6)

如果我只强制在群集距离下限之间,那么可能的聚类方法是什么?

使用单一链接进行分层聚类:

x <- c(1, 4, 5, 6, 9, 29, 32, 46, 55)
tree <- hclust(dist(x), method = "single")
split(x, cutree(tree, h = 19))

# $`1`
# [1] 1 4 5 6 9
# 
# $`2`
# [1] 29 32 46 55

如果我只在集群距离上限内施加了什么可能的聚类方法?

使用完整链接进行分层聚类:

x <- c(1, 4, 5, 6, 9, 20, 26, 29, 32)
tree <- hclust(dist(x), method = "complete")
split(x, cutree(tree, h = 9))

# $`1`
# [1] 1 4 5 6 9
# 
# $`2`
# [1] 20
# 
# $`3`
# [1] 26 29 32

答案 1 :(得分:3)

这是一个简单的算法,在概念上解释(省略了实现细节):

  1. 确保您的列表已排序。
  2. 在每对超过lower_bound的连续元素之间放置一个“标记”。这些标记了所有可能的集群边界。
  3. 在列表开头之前和结束之后加入标记。
  4. 按顺序浏览成对标记,并为每对left_markerright_marker检查紧靠left_marker右侧的元素与元素之间的距离是否为right_marker的左侧小于upper_bound
  5. 如果上一步返回false,则无法进行群集。
  6. 否则,标记会形成所需聚类的边界。
  7. 将此应用于您的示例,我们得到:

    1. 分类:1,4,5,6,9,26,29,32
    2. 标记:1,4,5,6,9 | 26,29,32
    3. 其他开始/结束标记:| 1,4,5,6,9 | 26,29,32 |
    4. 检查“上限”约束:(9-1)= 8&lt; 9:是的; (32-26)= 6&lt; 9:TRUE
    5. 没有比较返回false
    6. 所需的聚类:(1,4,5,6,9),(26,29,32)

    7. 编辑:原创海报放宽了问题的条件。

      如果您只想满足下限条件:

      1. 确保您的列表已排序。
      2. 在每对超过lower_bound的连续元素之间放置一个标记。
      3. 在开始之前和结束之后加入标记。
      4. 这些标记构成了所需聚类的边界。
      5. 如果您的矢量已经排序,以下内容将为您提供第2步:

        # Given
        vec <- c(1, 4, 5, 6, 9, 29, 32, 26)
        lower_bound <- 19
        
        f <- function(x) {
          return(vec[x+1] - vec[x] > lower_bound);
        }
        indices <- seq(length(vec)-1)
        marker_positions <- Position(f, indices)