使用 KMeans 聚类算法查找部分成员资格
Find partial membership with KMeans clustering algorithm
我可以很容易地用 KMeans
计算集群成员:
open System
open System.IO
open Utils
open Accord
open Accord.Math
open Accord.MachineLearning
let vals = [|
[|1.0; 2.0; 3.0; 2.0|]
[|1.1; 1.9; 3.1; 4.0|]
[|2.0; 3.0; 4.0; 4.0|]
[|3.0; 3.1; 2.0; 3.0|]
[|2.0; 4.0; 3.0; 6.0|]
[|1.0; 5.0; 5.0; 7.0|]
[|4.0; 3.0; 6.0; 8.0|]
[|5.0; 4.0; 3.0; 6.0|]
[|6.0; 4.0; 8.0; 7.0|]
[|5.0; 6.0; 5.0; 9.0|]
[|4.0; 2.0; 7.0; 8.0|]
[|8.0; 9.0; 3.1; 2.2|]
[|8.0; 9.0; 2.0; 2.0|]
[|10.0; 2.0; 3.0; 2.0|]
[|10.1; 1.9; 3.1; 4.0|]
[|20.0; 3.0; 4.0; 4.0|]
[|22.0; 7.0; 2.0; 3.0|]
[|21.0; 4.0; 3.0; 6.0|]
|]
let kmeans = new KMeans 5
let clusterModel = kmeans.Learn vals
let clusters = clusterModel.Decide vals
我可以使用标准 KMeans
算法计算部分成员资格吗?一位同事建议使用集群成员的均值和方差来确定比例成员,今天我一直在研究 F#
的模糊集及其实现。例如,here is some documentation for the Accord.net implementation for fuzzy sets. 我可以 translate/run F#
的示例,但乍一看,我没有看到从我的 Kmeans
[=43] 获取数据的简单方法=] 以适应分配部分成员资格的格式。
问题:
如何使用集群成员的 mean/variance 来计算部分成员资格?
是否有一种简单的方法可以使用 Accord.net 库计算 KMeans
聚类的部分成员资格?
Accord.net中的KMeans算法实现简单;我应该花一些时间尝试学习 clustering/membership 的这种方法来解决我的问题,而不是尝试强制 Kmeans 聚类来满足我的需要吗?
您应该能够使用 Accord.NET 来获取 K-means 算法找到的 "centroids" 个聚类。这些本质上是各个集群的中心。然后,您应该能够计算新数据点与每个质心之间的距离,以查看哪个质心最接近您的点。 (Decide
方法 returns 只是第一个。)
我没试过,但似乎 KMeans
公开了 Clusters
,这是一个 KMeansClusterCollection
并且有 Centroids
属性(见the docs)。它还公开了 Distance
属性 其中 returns 用于计算数据点之间距离的函数。
使用这些,您应该能够比较数据点与所有集群的质心的距离,并确定该点与各个集群的距离。
从头开始实施 k-means 并不难(这里有一个 nice post from Mathias Brandewinder),但似乎 Accord.NET 公开了您在这种特殊情况下需要的所有信息 - 所以也许这就是您所需要的(在自定义实现中正确获取所有细节始终是最困难的部分...)。
正如 Tomas 所提到的,Accord.NET 已经为您提供了许多构建基块。特别是,调用 clusterModel.Scores
会给你到集群质心的(负)距离,see source code
根据负距离,您可以通过取指数来计算近似的 class 成员分数,类似于您计算高斯 PDF 的方法。在 F# 中,它看起来像:
// Scores returns the negative distances between each point
// and the cluster centroid
let negDistances = clusterModel.Scores vals
// Compute an estimated cluster assigment score
let clusterMembership =
negDistances
|> Array.map (fun distances ->
// Take the Exponential of the (negative) distances,
// as in computing a Gaussian pdf
let expDist = distances |> Array.map Math.Exp
let total = Array.sum expDist
expDist
|> Array.map (fun d -> d/total)
)
这里有几个注意事项:
- Accord 中的标准 KMeans 使用欧氏距离,这意味着每个方向具有相同的权重。根据数据的性质,这可能不会产生合理的结果(图 2 个簇,每个簇的形状都像一根长雪茄)
- 上面的 class 成员计算也没有考虑聚类协方差。为了更接近真相,您必须计算 Bhattacharyya 距离、求幂,然后按协方差矩阵的逆 det 进行缩放。这对于单例集群会失败。
关于你的第三个问题:我不会重新实现。一开始看起来很容易,但通常会有很多极端情况和稳定性问题,一段时间后您才 运行 进入。
我可以很容易地用 KMeans
计算集群成员:
open System
open System.IO
open Utils
open Accord
open Accord.Math
open Accord.MachineLearning
let vals = [|
[|1.0; 2.0; 3.0; 2.0|]
[|1.1; 1.9; 3.1; 4.0|]
[|2.0; 3.0; 4.0; 4.0|]
[|3.0; 3.1; 2.0; 3.0|]
[|2.0; 4.0; 3.0; 6.0|]
[|1.0; 5.0; 5.0; 7.0|]
[|4.0; 3.0; 6.0; 8.0|]
[|5.0; 4.0; 3.0; 6.0|]
[|6.0; 4.0; 8.0; 7.0|]
[|5.0; 6.0; 5.0; 9.0|]
[|4.0; 2.0; 7.0; 8.0|]
[|8.0; 9.0; 3.1; 2.2|]
[|8.0; 9.0; 2.0; 2.0|]
[|10.0; 2.0; 3.0; 2.0|]
[|10.1; 1.9; 3.1; 4.0|]
[|20.0; 3.0; 4.0; 4.0|]
[|22.0; 7.0; 2.0; 3.0|]
[|21.0; 4.0; 3.0; 6.0|]
|]
let kmeans = new KMeans 5
let clusterModel = kmeans.Learn vals
let clusters = clusterModel.Decide vals
我可以使用标准 KMeans
算法计算部分成员资格吗?一位同事建议使用集群成员的均值和方差来确定比例成员,今天我一直在研究 F#
的模糊集及其实现。例如,here is some documentation for the Accord.net implementation for fuzzy sets. 我可以 translate/run F#
的示例,但乍一看,我没有看到从我的 Kmeans
[=43] 获取数据的简单方法=] 以适应分配部分成员资格的格式。
问题:
如何使用集群成员的 mean/variance 来计算部分成员资格?
是否有一种简单的方法可以使用 Accord.net 库计算
KMeans
聚类的部分成员资格?Accord.net中的KMeans算法实现简单;我应该花一些时间尝试学习 clustering/membership 的这种方法来解决我的问题,而不是尝试强制 Kmeans 聚类来满足我的需要吗?
您应该能够使用 Accord.NET 来获取 K-means 算法找到的 "centroids" 个聚类。这些本质上是各个集群的中心。然后,您应该能够计算新数据点与每个质心之间的距离,以查看哪个质心最接近您的点。 (Decide
方法 returns 只是第一个。)
我没试过,但似乎 KMeans
公开了 Clusters
,这是一个 KMeansClusterCollection
并且有 Centroids
属性(见the docs)。它还公开了 Distance
属性 其中 returns 用于计算数据点之间距离的函数。
使用这些,您应该能够比较数据点与所有集群的质心的距离,并确定该点与各个集群的距离。
从头开始实施 k-means 并不难(这里有一个 nice post from Mathias Brandewinder),但似乎 Accord.NET 公开了您在这种特殊情况下需要的所有信息 - 所以也许这就是您所需要的(在自定义实现中正确获取所有细节始终是最困难的部分...)。
正如 Tomas 所提到的,Accord.NET 已经为您提供了许多构建基块。特别是,调用 clusterModel.Scores
会给你到集群质心的(负)距离,see source code
根据负距离,您可以通过取指数来计算近似的 class 成员分数,类似于您计算高斯 PDF 的方法。在 F# 中,它看起来像:
// Scores returns the negative distances between each point
// and the cluster centroid
let negDistances = clusterModel.Scores vals
// Compute an estimated cluster assigment score
let clusterMembership =
negDistances
|> Array.map (fun distances ->
// Take the Exponential of the (negative) distances,
// as in computing a Gaussian pdf
let expDist = distances |> Array.map Math.Exp
let total = Array.sum expDist
expDist
|> Array.map (fun d -> d/total)
)
这里有几个注意事项:
- Accord 中的标准 KMeans 使用欧氏距离,这意味着每个方向具有相同的权重。根据数据的性质,这可能不会产生合理的结果(图 2 个簇,每个簇的形状都像一根长雪茄)
- 上面的 class 成员计算也没有考虑聚类协方差。为了更接近真相,您必须计算 Bhattacharyya 距离、求幂,然后按协方差矩阵的逆 det 进行缩放。这对于单例集群会失败。
关于你的第三个问题:我不会重新实现。一开始看起来很容易,但通常会有很多极端情况和稳定性问题,一段时间后您才 运行 进入。