PHP Geolocation 将用户聚集到世界区域

Posted

技术标签:

【中文标题】PHP Geolocation 将用户聚集到世界区域【英文标题】:PHP Geolocation clustering users into world zones 【发布时间】:2013-07-30 13:02:05 【问题描述】:

这个想法是用网格将整个世界划分为多个区域。网格中的每个正方形都是一个簇。根据用户的纬度和经度,我需要检查用户位置在这些集群中的位置并将用户放入其中。

我需要实现的是一种对用户位置进行聚类并了解哪些用户彼此最近的方法。

将世界划分为网格的想法只是一种选择。如果这是一个更简单的方法,那么,更好。我知道我可以通过多种方式检查两个给定用户的距离,但这不是我想要的。我需要创建位置集群并将每个用户放在相关集群中。

有人知道实现上述目标的脚本/api/方式吗?

非常感谢任何帮助。

谢谢

【问题讨论】:

【参考方案1】:

Cluster analysis 是一个复杂的问题,存在许多解决方案,具体取决于您的需求和可用信息。

k-means 是一种算法,您可以在其中提供您期望的集群数量作为初始参数,并且该算法将围绕该数字进行集群。它很快,但通常不会导致最佳结果和/或迫使您为 k 选择一个您无法猜测的数字。

DBSCAN 是一种基于两个位置之间的距离和您提供的截止半径创建集群的算法。它比 k-means 产生更好的结果,但速度也慢得多。

除此之外,还有更多可用的算法,所有算法都针对不同的数据模型或用例进行了调整和优化。我知道在 php 中没有任何实现。你真正想要的是一个支持 GIS 的数据库,例如 PostgreSQL + PostGIS。这是一个绝佳的选择。有一个本机 k-means extension 可用。你可以hook it into R,里面有many packages for all sorts of clustering algorithms。

如果您的数据集足够大,那是唯一可行的方法,而且肯定会进行一些初步的艰苦战斗。否则,您几乎会被一个简单的舍入坐标到最近整数和计数算法所困扰,该算法很容易在 PHP 中使用几乎任何数据库实现(但只能让您获得基于方形网格的集群,而不是漂亮)。

当然,使用简单的工具可以通过许多折衷方案来解决这个问题。在数据库中进行简单的基于网格的聚类以缩小数据集的范围,然后使用基于权重的算法在客户端的 PHP 或 javascript 中进一步聚类那些剩余的标记。或者每天晚上使用任何缓慢的方法预先计算整个事情。但是任何实现都不会像使用体面的 GIS 后端所能实现的那样好。


几年前我曾处理过一个类似的问题,认为它不会那么难并最终放弃它,因为使用我当时可用的工具发现它很难。你的普通 PHP/mysql 组合几乎没有给你任何东西来充分解决这个问题。一旦您升级到正确的工具,就会突然有更多解决方案可供您使用。就我而言,目前是 PostGIS、R 和 GeoServer。由于任何算法要么是 CPU 密集型,要么是内存密集型,或者两者兼而有之,PHP 通常不足以实现它,而且没有原生 GIS 数据类型和函数的数据库会给你的生活带来不必要的困难。

【讨论】:

我有点困惑。 K-means 需要知道有多少簇。但是我如何决定有多少个集群?我的意思是,我只得到用户的纬度和经度。集群是我之后想要创建的。至于 DBSCAN,第二个位置可能是什么?我应该将北极和南极作为两个位置吗?当我得到用户的纬度和经度时,DBSCAN 将如何理解所属集群?这对我来说是全新的,我根本不明白:/ 没错。这就是为什么 k-means 对于大多数应用程序来说毫无价值。如果您的数据集分布非常均匀(例如高斯噪声),​​则它很有用。否则没有那么多。 DBSCAN 必须在整个 数据集 上工作。它随机选择一个点并“走”过附近的点,直到再也找不到任何其他附近的点,然后在其他地方重新开始,从而形成集群。我真的可以推荐你玩一下 R,它是一个很棒的环境,可以直观地尝试不同的算法来了解它们的工作原理。 你说“否则你几乎会被一个简单的舍入坐标到最近整数和计数算法困住,这在 PHP 中很容易实现,几乎可以使用任何数据库 (但只会让你得到基于方形网格的集群,而不是漂亮)。”我认为这正是我正在寻找的。您对此有什么建议吗? 基本上:只需将纬度/经度四舍五入到最接近的整数(或其分数)和GROUP BY。根据您的需要,它可能就足够了,但如果您想要“地图上的标记”,它看起来并不漂亮。 @Php 这并非不可能,但远非理想。除了 PHP 和 MySQL 中最基本的 GIS 操作之外,几乎没有任何现有的基础设施。你能指出现有的 DBSCAN 或 MySQL 的类似实现吗?纯粹在 PHP 中执行此操作通常令人望而却步,因为您需要先将 所有 数据传输到内存中,这对于大型集合是不现实的。【参考方案2】:

我认为您不是在要求 k-means 或 dB 扫描。 Mysql 有空间扩展和点数据类型。因此,您可以简单地将用户放在点列中并使用点在矩形内的查询。我还写了一个基于怪物曲线的 quadkey php 集群脚本。它是在 Oracle dB 或其他中经常使用的四叉树。您可以给我写一封电子邮件或从 phpclasses 下载我的课程。包名是希尔伯特曲线。以下是 bing 地图平铺 http://msdn.microsoft.com/en-us/library/bb259689.aspx 的示例。

【讨论】:

请详细说明使用希尔伯特曲线可以解决什么问题。在我看来,OP 正在寻找一种聚类算法来产生类似于kiwicollection.com/search/map 的东西,我不确定你的答案是否朝着同一个方向发展。 当然,您正在解释平铺。但平铺不一定与聚类分析相同。我在回答中详细介绍了很多细节,但您所说的只是“使用希尔伯特/怪物/莫顿曲线”。这对于理解如何使用它、使用它的目的或结果会是什么样子并没有真正的帮助。 我不是集群或 R 方面的专家,但从您所写的内容来看,我也无法看出您是。客户端集群是有问题的,因为您需要将 整个数据集 传输到客户端,同样的问题是将其传输到 PHP 以在那里进行集群。尝试以这种方式对包含数百万个观测值的数据集进行聚类,这是非常不可行的。如果可能的话,这需要在数据库中发生。我真的很感兴趣是否有 R 的替代品可以这样做,但我也没有看到你有任何可行的方法。 ..cont.:请用实际代码扩展他如何“使用 mysql 空间索引”进行这样的集群应用程序。 我不认为 OP 正在寻找某个矩形内的位置。他正在研究clusters 中的clustering 任意点。 youtube.com/watch?v=zqKFH7WNmfE

以上是关于PHP Geolocation 将用户聚集到世界区域的主要内容,如果未能解决你的问题,请参考以下文章

攻防世界web进阶区

无法使用 AJAX 将 JS 变量传递给 PHP

攻防世界:web区 Simple_PHP

攻防世界-web-高手进阶区003-php_rce

攻防世界:WEB区WebShell

攻防世界 web进阶区 ics-06