【问题标题】:Get distance from a data point to its centroid with Accord.net使用 Accord.net 获取从数据点到其质心的距离
【发布时间】:2016-12-14 01:05:18
【问题描述】:

我正在使用Accord.net library 进行一些聚类工作。最终,我试图找到与the elbow method 一起使用的最佳集群数量,这需要一些相对简单的计算。但是,我很难获得所需的值,以确定在我的KMeans 建模中使用的最佳 K 数量。

我有一些示例数据/代码:

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))

返回

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 中列出的简单算法。 请注意,我不反对使用链接到顶部答案底部的“差距统计”。

【问题讨论】:

  • 您应该能够使用 Scores() 方法而不是 Decide() 计算到其最近集群的距离。

标签: f# cluster-analysis accord.net


【解决方案1】:

原来我没有正确计算距离,但我已经接近了。

进行更多挖掘后,我看到了this similar question, but for the R language,并在我自己的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 将值转换为浮点数,以便它可以平方(即x**y

|> sqrt) 求值的平方根。

可能有一个内置的方法可以做到这一点,但我还没有找到。目前,这对我有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-12
    • 1970-01-01
    • 1970-01-01
    • 2014-03-06
    • 2017-03-22
    • 2016-06-11
    • 1970-01-01
    • 2021-06-10
    相关资源
    最近更新 更多