【问题标题】:Altering the DBSCAN Algorithm更改 DBSCAN 算法
【发布时间】:2015-12-14 18:43:21
【问题描述】:

我正在尝试自定义 DBSCAN 算法,以便如果仅在 x 方向 上的两点之间的距离大于某个数字,或者仅在 y 方向 上的两点之间的距离大于某个数字。但是,我在执行此操作时遇到了一些麻烦。

到目前为止,这是我的代码:

     public void ComputeClusterDbscan(DatasetItem[] allPoints, double epsilon, int minPts, double[] currentpt, double[] nextpt, out HashSet<DatasetItem[]> clusters)
     {
        var allPointsDbscan = allPoints.Select(x => new DbscanPoint(x)).ToArray();

        int clusterId = 0;
        for (int i = 0; i < allPointsDbscan.Length - 1 ; i++)
        {
            int j = i + 1;
            DbscanPoint p = allPointsDbscan[i];
            if (p.IsVisited)
                continue;
            p.IsVisited = true;
            DbscanPoint[] neighborPts = null;
            RegionQuery(allPointsDbscan, p.ClusterPoint, epsilon, out neighborPts);

            //calculate distance between points in x and y directions
            double xDirection = Math.Abs(allPointsDbscan[j].ClusterPoint.X - allPointsDbscan[i].ClusterPoint.X);
            double yDirection = Math.Abs(allPointsDbscan[j].ClusterPoint.Y - allPointsDbscan[i].ClusterPoint.Y);
            if (xDirection > 0.299 | yDirection > 0.199)
            {
                //begin new cluster
            }

            if (neighborPts.Length < minPts)
                p.ClusterId = (int)ClusterIds.Noise;
            else
            {
                clusterId++;
                ExpandCluster(allPointsDbscan, p, neighborPts, clusterId, epsilon, minPts);
            }
        }
        clusters = new HashSet<DatasetItem[]>(
            allPointsDbscan
                .Where(x => x.ClusterId > 0)
                .GroupBy(x => x.ClusterId)
                .Select(x => x.Select(y => y.ClusterPoint).ToArray())
            );
    }

【问题讨论】:

  • 这个问题很老,所以你希望能解决这个问题。但是您需要在 RegionQuery 函数中添加 dx 和 dy 比较,而不是在 ComputeClusterDbScan 函数中。 RegionQuery 确定任何给定点是否可以属于传入点的集群。它通过在满足所有被视为邻居的标准时将每个点添加到邻居列表中来做到这一点。在您的情况下,除了需要在指定的 epsilon 距离内之外,您还将进一步检查每个点是否在投影 x/y 距离内。如果没有,请不要添加到邻居列表中。

标签: c# algorithm dbscan


【解决方案1】:

您无需修改​​ DBSCAN 即可执行此操作。

三种解决方案:

  1. 缩放您的数据集,使 x 和 y 阈值可相互比较,然后使用最大范数。 IE。如果您有 eps_x 和 eps_y,请将 x 坐标乘以 1/eps_x,将 y 坐标乘以 1/eps_y,然后使用 eps=1 和最大范数。
  2. 使用加权最大范数
  3. 使用通用 DBSCAN。例如。在 ELKI 实现中,很容易添加一个具有两个 epsilon 参数的新邻居谓词。以 Intersection(neighbors_x,neighbors_y) 为邻域。

所有这些方法都有效地改变了“regionQuery”的结果。

【讨论】:

  • 这些解决方案都不能解决我的问题。缩放肯定不起作用,因为我正在检查距离;缩小数据只会给我“误报”。
  • 您必须精确地缩放数据以匹配您所需的阈值。我不是在谈论将它们标准化为 [0;1]。相信我,只要做得好,它们三个都会起作用。
  • 对不起,我不明白你的意思;请给我看。
  • 要将权重 w 放在 x 轴上,将 x 与 w 相乘。要将权重 u 放在 y 轴上,请将 y 与 u 相乘!
  • 大声笑我完全理解如何使用标量乘数,但这对我的数据集没有帮助。请记住,我想知道距离(仅在 x 方向上,是否大于我选择的某个数字……例如 0.5)或距离(仅在 y 方向上大于 1.5)。如果它更大,在任何一个方向,然后开始一个新的集群。在这种情况下,缩放将无济于事......它只会在我试图计算距离时使我的数据不成比例。
猜你喜欢
  • 2021-04-19
  • 2020-02-14
  • 2017-03-05
  • 2019-04-18
  • 2014-09-11
  • 2014-07-11
  • 2012-04-26
  • 2018-10-09
  • 2016-06-28
相关资源
最近更新 更多