2013-06-21 35 views
3

我有一個整數向量,我希望將其分成多個簇,以便任意兩個簇之間的距離大於下限,並且在任何簇內,兩個元素之間的距離小於上限。R中的距離聚類

例如,假設我們有以下矢量:

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

,並設置上述下限和上限至19和9分別低於兩個向量應該是一個可能的結果:

1,4,5,6,9

29,32,36


感謝@ flodel的評論,我意識到這種聚類可能是不可能的。所以我想稍微修改這些問題:

如果我只在之間施加簇距離下界,可能的聚類方法是什麼? 如果我只在範圍內強加簇距離上限,可能的聚類方法是什麼?

+0

如果邊界之間的距離會發生什麼? – alexwhan

+0

如果我將「20」添加到您的矢量中,您的問題變得不可行嗎?你不能同時擁有兩個條件。換句話說,你是在尋找一種算法來告訴你何時無法滿足這兩個條件,或者你沒有意識到這種可能性?在這種情況下,您可能不得不重新考慮您的問題。 – flodel

回答

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 
3

這裏有一個簡單的算法,將工作,解釋概念(略實施細則):

  1. 確保您的列表進行排序。
  2. 在每對超過lower_bound的連續元素之間放置一個「標記」。這些標記了所有可能的羣集邊界。
  3. 在列表開始之前和結束之後加入標記。
  4. 通過對標記物的去以便,並且對於每對left_markerright_marker,檢查是否立即向left_marker的右側並立即向right_marker左側的元件中的元件之間的距離小於upper_bound開。
  5. 如果前面的步驟返回false,則不可能進行聚類。
  6. 否則,標記形成所需簇的邊界。

將此應用於您的例子中,我們得到:

  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 < 9:TRUE; (32 - 26)= 6 < 9:TRUE
  5. 無比較的返回false
  6. 期望聚類:(1,4,5,6,9),(26,29,32)

編輯:原創海報放寬了問題的條件。

如果你只是想滿足下界條件:

  1. 確保您的列表進行排序。
  2. 在間隔超過lower_bound的每對連續元素之間放置一個標記。
  3. 在開始之前和結束之後加入一個標記。
  4. 這些標記形成了所需聚類的邊界。

下讓你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) 
+0

謝謝。我已經提出了你的答案,它非常明確和有幫助,但問題是在R中尋找一種實用的方法,如果現有的功能或包已經可以做到,建議將非常感激。另外,因爲在某些情況下,在兩個邊界條件下的聚類可能是不可能的,所以我已經編輯了一些問題,請你看看?謝謝!:) – qed

+0

其實,也許我不明白你原來的問題。 9和26之間的距離只有17,小於19,這應該是一個正確的聚類? –

+0

對不起,它應該是36,我已經糾正它。謝謝! – qed