在 netlogo 中使用 dbscan 确定簇间距离
Determining the Inter-cluster distance using dbscan in netlogo
假设您有以下代码(由@Nicolas-Payette 提供),您将如何使用 netlog 中的 dbscan 查找平均集群间距离:
extensions [ dbscan ]
to setup
clear-all
ask patches [ set pcolor white ]
create-turtles 1000 [
set color black
set label-color blue
setxy random-xcor random-ycor
]
ask n-of 5 turtles [
ask turtles in-radius 3 [
set color one-of [red grey]
]
]
end
to find-clusters
let red-grey-turtles turtles with [ member? color [red grey] ]
let clusters dbscan:cluster-by-location red-grey-turtles 3 3
(foreach clusters range length clusters [ [c i] ->
foreach c [ t ->
ask t [ set label i ]
]
])
end
让我们将被测距离的端点作为海龟群的中心。
这取决于您如何定义簇间距离。有多种方法可以做到这一点。
Let us take a the endpoints of the distances being measured to be the centers of the clusters of turtles.
虽然这对于 K 均值聚类来说是一种很好的技术,但对于 DBSCAN 来说效果不佳,因为聚类可能是凹的。因此,中心可能在集群之外!无论如何,我会作为一个选项包括在内。
首先,让我们定义距离度量:
簇中点之间的平均距离:
to-report cluster-distance [ cluster1 cluster2 ]
report mean [ mean [ distance myself ] of cluster2 ] of cluster1
end
簇中点之间的最小距离:
to-report cluster-distance [ cluster1 cluster2 ]
report min [ min [ distance myself ] of cluster2 ] of cluster1
end
质心之间的距离
假设世界环绕关闭:
to-report cluster-distance [ cluster1 cluster2 ]
let x1 mean [ xcor ] of cluster1
let y1 mean [ ycor ] of cluster1
let x2 mean [ xcor ] of cluster2
let y2 mean [ ycor ] of cluster2
report sqrt ((x1 - x2) ^ 2 + (y1 - y2) ^ 2)
end
如果世界环绕开启
; This is super complicated because, with wrapping on, xcor and ycor are
; more like angles rather than cartesian coordinates. So, this converts
; them to angles, gets the mean of those angles, and converts them back.
; Related SO question:
to-report xcor-mean [ xcors ]
let angles map [ x -> 360 * (x - (min-pxcor - 0.5)) / world-width ] xcors
let mean-x mean map cos angles
let mean-y mean map sin angles
report (atan mean-y mean-x) / 360 * world-width + (min-pxcor - 0.5)
end
to-report ycor-mean [ ycors ]
let angles map [ y -> 360 * (y - (min-pycor - 0.5)) / world-height ] ycors
let mean-x mean map cos angles
let mean-y mean map sin angles
report (atan mean-y mean-x) / 360 * world-height + (min-pycor - 0.5)
end
to-report cluster-distance [ cluster1 cluster2 ]
let x1 xcor-mean [ xcor ] of cluster1
let y1 ycor-mean [ ycor ] of cluster1
let x2 xcor-mean [ xcor ] of cluster2
let y2 ycor-mean [ ycor ] of cluster2
report sqrt ((x1 - x2) ^ 2 + (y1 - y2) ^ 2)
end
平均距离
一旦我们有了距离度量,使用 map
获得平均距离就相对简单了。请注意,下面的 remove
是必需的,因为我们不想在均值中包括集群到自身的距离。另请注意,这段代码效率有点低,因为它计算了所有距离两次,但这也大大简化了它:
...
; This line is modified so that we get a list of turtle sets rather than
; a list of lists.
let clusters map turtle-set dbscan:cluster-by-location red-grey-turtles 3 3
let avg-distance mean map [ c1 ->
mean map [ c2 ->
cluster-distance c1 c2
] remove c1 clusters ; Get distance to all other clusters but c1
] clusters
假设您有以下代码(由@Nicolas-Payette 提供),您将如何使用 netlog 中的 dbscan 查找平均集群间距离:
extensions [ dbscan ]
to setup
clear-all
ask patches [ set pcolor white ]
create-turtles 1000 [
set color black
set label-color blue
setxy random-xcor random-ycor
]
ask n-of 5 turtles [
ask turtles in-radius 3 [
set color one-of [red grey]
]
]
end
to find-clusters
let red-grey-turtles turtles with [ member? color [red grey] ]
let clusters dbscan:cluster-by-location red-grey-turtles 3 3
(foreach clusters range length clusters [ [c i] ->
foreach c [ t ->
ask t [ set label i ]
]
])
end
让我们将被测距离的端点作为海龟群的中心。
这取决于您如何定义簇间距离。有多种方法可以做到这一点。
Let us take a the endpoints of the distances being measured to be the centers of the clusters of turtles.
虽然这对于 K 均值聚类来说是一种很好的技术,但对于 DBSCAN 来说效果不佳,因为聚类可能是凹的。因此,中心可能在集群之外!无论如何,我会作为一个选项包括在内。
首先,让我们定义距离度量:
簇中点之间的平均距离:
to-report cluster-distance [ cluster1 cluster2 ]
report mean [ mean [ distance myself ] of cluster2 ] of cluster1
end
簇中点之间的最小距离:
to-report cluster-distance [ cluster1 cluster2 ]
report min [ min [ distance myself ] of cluster2 ] of cluster1
end
质心之间的距离
假设世界环绕关闭:
to-report cluster-distance [ cluster1 cluster2 ]
let x1 mean [ xcor ] of cluster1
let y1 mean [ ycor ] of cluster1
let x2 mean [ xcor ] of cluster2
let y2 mean [ ycor ] of cluster2
report sqrt ((x1 - x2) ^ 2 + (y1 - y2) ^ 2)
end
如果世界环绕开启
; This is super complicated because, with wrapping on, xcor and ycor are
; more like angles rather than cartesian coordinates. So, this converts
; them to angles, gets the mean of those angles, and converts them back.
; Related SO question:
to-report xcor-mean [ xcors ]
let angles map [ x -> 360 * (x - (min-pxcor - 0.5)) / world-width ] xcors
let mean-x mean map cos angles
let mean-y mean map sin angles
report (atan mean-y mean-x) / 360 * world-width + (min-pxcor - 0.5)
end
to-report ycor-mean [ ycors ]
let angles map [ y -> 360 * (y - (min-pycor - 0.5)) / world-height ] ycors
let mean-x mean map cos angles
let mean-y mean map sin angles
report (atan mean-y mean-x) / 360 * world-height + (min-pycor - 0.5)
end
to-report cluster-distance [ cluster1 cluster2 ]
let x1 xcor-mean [ xcor ] of cluster1
let y1 ycor-mean [ ycor ] of cluster1
let x2 xcor-mean [ xcor ] of cluster2
let y2 ycor-mean [ ycor ] of cluster2
report sqrt ((x1 - x2) ^ 2 + (y1 - y2) ^ 2)
end
平均距离
一旦我们有了距离度量,使用 map
获得平均距离就相对简单了。请注意,下面的 remove
是必需的,因为我们不想在均值中包括集群到自身的距离。另请注意,这段代码效率有点低,因为它计算了所有距离两次,但这也大大简化了它:
...
; This line is modified so that we get a list of turtle sets rather than
; a list of lists.
let clusters map turtle-set dbscan:cluster-by-location red-grey-turtles 3 3
let avg-distance mean map [ c1 ->
mean map [ c2 ->
cluster-distance c1 c2
] remove c1 clusters ; Get distance to all other clusters but c1
] clusters