非常大的数据集中的成对距离
Posted
技术标签:
【中文标题】非常大的数据集中的成对距离【英文标题】:Pairwise distance in very large datasets 【发布时间】:2021-07-18 17:41:15 【问题描述】:我有一个大约 [5000000 x 6] 的数组,我只需要选择彼此相距一定距离的点(行)。
想法应该是:
从数据数组的第一行开始new_array
将 new_array 与数据数组中的第二行进行比较
如果它们之间的 pdist > tol,则将行追加到 new_array
将 new_array 与数据数组中的第三行进行比较
等等……
一个问题是 RAM 大小。即使在 pdist 中,我也无法一次比较所有行。
所以我一直在考虑将数据集拆分为较小的数据集,但后来我不知道如何检索数据集中行的索引信息。
我试过 scipy cdist、scipy euclidean、sklearn euclidean_distances、sklearnpaired_distances,下面的代码是我能得到的最快的。一开始它很快,但是在 40k 循环之后它变得非常慢。
xyTotal=np.random.random([5000000,6])
tol=0.5
for i,z in enumerate(xyTotal):
if (pdist(np.vstack([np.array(ng),z]))>tol).all():
ng.append(z)
对这个问题有什么建议吗?
编辑
ktree = BallTree(xyTotal, leaf_size=40,metric='euclidean')
btsem=[]
for i,j in enumerate(xyTotal):
ktree.query_radius(j.reshape(1,-1),r=tol, return_distance=True)
if (ktree.query_radius(j.reshape(1,-1),r=tol, count_only=True))==1:
btsem.append(j)
这很快,但我只挑选异常值。当我到达靠近另一个点(即在一个小集群中)时,我不知道只选择一个点并留下其他点,因为我将获得集群中所有点的相同指标(它们都有距离相同)
【问题讨论】:
【参考方案1】:计算速度很慢,因为算法的复杂性是二次的:O(k * n * n)
其中 n 是 len(xyTotal)
,k
是条件为真的概率。因此,假设k=0.1
和n=5000000
,运行时间将会很长(可能需要数小时的计算)。
希望您可以编写一个在O(n * log(n))
时间运行的更好的实现。然而,这很难实现。您需要将ng
点添加到kd 树 中,然后您可以搜索最近邻 并检查与当前点的距离是否大于tol
。
请注意,您可以找到实现 k-d 树的 Python 模块,并且 SciPy 文档提供了用纯 Python 编写的 an example of implementation(因此可能效率不高)。
【讨论】:
你好,杰罗姆。我已经尝试过使用 sklearn NearestNeighbors 进行类似的操作。outroneigh = NearestNeighbors(n_neighbors=2) filtered=[xyTotal[0]] for i,j in enumerate(xyTotal): outroneigh.fit(np.vstack([filtered,j])) if outroneigh.kneighbors(j.reshape(1,-1),return_distance=True)[0][0,1]>tol: print(i) filtered.append(j)
问题是为了获得与其他方法相同的答案,我需要继续拟合附加数组。这种拟合比 pdist 慢得多。
这不是append
的问题,而是np.vstack
从所有过去的值重建一个全新的数组。你不需要那个。实际上,append
也不需要。如果你想使用 Numpy 数组,你可以预先分配一个大数组,分配单元格并分割好的部分。请注意,在 CPython 列表中,我认为 append
应该以摊销的 O(1)
运行。您应该首先关注复杂性,然后再关注优化/矢量化。
我明白你的意思并同意。但我无法弄清楚如何不使用追加或重建数组,因为我必须测试一个数组中的点与另一个数组中的点并连接 if 条件. pdist 也仅适用于 ndarrays,因此我需要构建一个数组以传递给 pdist。但是,如果您告诉我用 KDTree 对整个数据数组进行一次拟合,我用 NearestNeighbors 尝试过一次。我试图获取每个点到所有点的距离,但结果不一样。我可以确定这样做关于离群点,我想要,但是当我有接近点时它会变得混乱,我可能想要。以上是关于非常大的数据集中的成对距离的主要内容,如果未能解决你的问题,请参考以下文章