使用 Accord.net 获取数据点到其质心的距离
Get distance from a data point to its centroid with Accord.net
我正在使用 Accord.net library. Ultimately, I'm trying to find the optimal number of clusters to use with the elbow method 进行一些聚类工作,这需要一些相对简单的计算。但是,我很难获得我需要的值以确定 K 的最佳数量以用于我的 KMeans
建模。
我有一些例子data/code:
open Accord
open Accord.Math
open Accord.MachineLearning
open Accord.Statistics
open Accord.Statistics.Analysis
let x = [|
[|4.0; 1.0; 1.0; 2.0|];
[|2.0; 4.0; 1.0; 2.0|];
[|2.0; 3.0; 1.0; 1.0|];
[|3.0; 6.0; 2.0; 1.0|];
[|4.0; 4.0; 1.0; 1.0|];
[|5.0; 10.0; 1.0; 2.0|];
[|7.0; 8.0; 1.0; 2.0|];
[|6.0; 5.0; 1.0; 1.0|];
[|7.0; 7.0; 2.0; 1.0|];
[|5.0; 8.0; 1.0; 1.0|];
[|4.0; 1.0; 1.0; 2.0|];
[|3.0; 5.0; 0.0; 3.0|];
[|1.0; 2.0; 0.0; 0.0|];
[|4.0; 7.0; 1.0; 2.0|];
[|5.0; 3.0; 2.0; 0.0|];
[|4.0; 11.0; 0.0; 3.0|];
[|8.0; 7.0; 2.0; 1.0|];
[|5.0; 6.0; 0.0; 2.0|];
[|8.0; 6.0; 3.0; 0.0|];
[|4.0; 9.0; 0.0; 2.0|]
|]
我可以使用
轻松生成集群
let kmeans = new KMeans 5
let kmeansMod = kmeans.Learn x
let clusters = kmeansMod.Decide x
但是我如何计算任何给定数据点 x
到它分配的集群的距离?我在 KMeans
Cluster Collection class documentation 中没有看到任何表明已经针对此问题实施的方法。
这个距离的计算好像应该比较简单,但是我很茫然。会像
这样的事情一样简单吗
let dataAndClusters = Array.zip clusters x
let getCentroid (m: KMeansClusterCollection) (i: int) =
m.Centroids.[i]
dataAndClusters
|> Array.map (fun (c, d) -> (c, (getCentroid kmeansMod c)
|> Array.map2 (-) d
|> Array.sum))
哪个returns
val it : (int * float) [] =
[|(1, 0.8); (0, -1.5); (1, -0.2); (0, 1.5); (0, -0.5); (4, 0.0); (2, 1.4);
(2, -3.6); (2, 0.4); (3, 0.75); (1, 0.8); (0, 0.5); (1, -4.2); (3, -0.25);
(1, 2.8); (4, 0.0); (2, 1.4); (3, -1.25); (2, 0.4); (3, 0.75)|]
我计算的距离是否正确?我怀疑不是。
正如我提到的,我希望确定要在 KMeans
集群中使用的 K
的正确数量。我只是想我会使用 the second paragraph of this Stats.StackExchange.com answer 中列出的简单算法。 请注意,我不反对使用顶部答案底部的 "Gap Statistic" 链接。
原来我没有正确计算距离,但我很接近。
进行更多挖掘后,我看到 并在我自己的 R
会话中分解了该已接受答案中概述的过程。
步骤似乎很简单:
1. From each data value, subtract the centroid values
2. Sum the differences for a given data/centroid pair
3. Square the differences
4. Find the square root of the differences.
对于我上面的示例数据,它将分解为:
let distances =
dataAndClusters
|> Array.map (fun (c, d) -> (c, ((getCentroid kmeansMod c)
|> Array.map2 (-) d
|> Array.sum
|> float) ** 2.0
|> sqrt))
注意添加两行,
|> float) ** 2.0
converts the value to a float so that it can be squared (i.e., x**y
)
和
|> sqrt)
which finds the square root of the value.
可能有内置方法可以执行此操作,但我还没有找到。现在,这对我有用。
我正在使用 Accord.net library. Ultimately, I'm trying to find the optimal number of clusters to use with the elbow method 进行一些聚类工作,这需要一些相对简单的计算。但是,我很难获得我需要的值以确定 K 的最佳数量以用于我的 KMeans
建模。
我有一些例子data/code:
open Accord
open Accord.Math
open Accord.MachineLearning
open Accord.Statistics
open Accord.Statistics.Analysis
let x = [|
[|4.0; 1.0; 1.0; 2.0|];
[|2.0; 4.0; 1.0; 2.0|];
[|2.0; 3.0; 1.0; 1.0|];
[|3.0; 6.0; 2.0; 1.0|];
[|4.0; 4.0; 1.0; 1.0|];
[|5.0; 10.0; 1.0; 2.0|];
[|7.0; 8.0; 1.0; 2.0|];
[|6.0; 5.0; 1.0; 1.0|];
[|7.0; 7.0; 2.0; 1.0|];
[|5.0; 8.0; 1.0; 1.0|];
[|4.0; 1.0; 1.0; 2.0|];
[|3.0; 5.0; 0.0; 3.0|];
[|1.0; 2.0; 0.0; 0.0|];
[|4.0; 7.0; 1.0; 2.0|];
[|5.0; 3.0; 2.0; 0.0|];
[|4.0; 11.0; 0.0; 3.0|];
[|8.0; 7.0; 2.0; 1.0|];
[|5.0; 6.0; 0.0; 2.0|];
[|8.0; 6.0; 3.0; 0.0|];
[|4.0; 9.0; 0.0; 2.0|]
|]
我可以使用
轻松生成集群let kmeans = new KMeans 5
let kmeansMod = kmeans.Learn x
let clusters = kmeansMod.Decide x
但是我如何计算任何给定数据点 x
到它分配的集群的距离?我在 KMeans
Cluster Collection class documentation 中没有看到任何表明已经针对此问题实施的方法。
这个距离的计算好像应该比较简单,但是我很茫然。会像
这样的事情一样简单吗let dataAndClusters = Array.zip clusters x
let getCentroid (m: KMeansClusterCollection) (i: int) =
m.Centroids.[i]
dataAndClusters
|> Array.map (fun (c, d) -> (c, (getCentroid kmeansMod c)
|> Array.map2 (-) d
|> Array.sum))
哪个returns
val it : (int * float) [] =
[|(1, 0.8); (0, -1.5); (1, -0.2); (0, 1.5); (0, -0.5); (4, 0.0); (2, 1.4);
(2, -3.6); (2, 0.4); (3, 0.75); (1, 0.8); (0, 0.5); (1, -4.2); (3, -0.25);
(1, 2.8); (4, 0.0); (2, 1.4); (3, -1.25); (2, 0.4); (3, 0.75)|]
我计算的距离是否正确?我怀疑不是。
正如我提到的,我希望确定要在 KMeans
集群中使用的 K
的正确数量。我只是想我会使用 the second paragraph of this Stats.StackExchange.com answer 中列出的简单算法。 请注意,我不反对使用顶部答案底部的 "Gap Statistic" 链接。
原来我没有正确计算距离,但我很接近。
进行更多挖掘后,我看到 R
会话中分解了该已接受答案中概述的过程。
步骤似乎很简单:
1. From each data value, subtract the centroid values
2. Sum the differences for a given data/centroid pair
3. Square the differences
4. Find the square root of the differences.
对于我上面的示例数据,它将分解为:
let distances =
dataAndClusters
|> Array.map (fun (c, d) -> (c, ((getCentroid kmeansMod c)
|> Array.map2 (-) d
|> Array.sum
|> float) ** 2.0
|> sqrt))
注意添加两行,
|> float) ** 2.0
converts the value to a float so that it can be squared (i.e.,x**y
)
和
|> sqrt)
which finds the square root of the value.
可能有内置方法可以执行此操作,但我还没有找到。现在,这对我有用。