因此,今天早上我了解到Minkowski指标并不总是意味着。
有关详细信息,请参见wolfram。
显然,这只是个p范数。 Scipy可以选择对p范数进行加权,但只能使用正加权,因此无法实现相对论的Minkowski度量。
我想对相对论4维空间中的点进行分层聚类。有两点;a = [a_time, a_x, a_y, a_z]
b = [b_time, b_x, b_y, b_z]
它们之间的距离应该是;invarient_s(a, b) = sqrt(-(a_time-b_time)^2 + (a_x-b_x)^2 + (a_y-b_y)^2 + (a_z-b_z)^2)
我在python中工作,理想情况下使用scipy的fcluster。在我开始编写自己的集群之前,是否有将其用于fcluster的指标?我可以添加到可用指标列表吗?
编辑;似乎只有fclusterdata首先支持指标。
最佳答案
坏消息是,确实内置指标(尤其是一个名为Minkowski的指标)不支持负权重。我怀疑其原因是,在适当的度量标准中,只有且仅当d(x,y) = 0
时才可以具有x = y
,这是Minkowski度量标准所违反的。这可能是scipy
中任何加权度量标准均不支持负权重的原因,另请参见this github thread中的注释。
好消息是scipy.cluster.hierarchy.fclusterdata
的文档存在错误(now fixed in master),因为它声称
metric: str, optional
The distance metric for calculating pairwise distances.
See distance.pdist for descriptions and linkage to verify
compatibility with the linkage method.
实际的implementation of
fclusterdata
只是将metric
输入参数传递给pdist
,这允许将自定义可调用对象作为metric
传递:metric: str or function, optional
当然,我们可以定义自己的Minkowski度量函数并将其传递给
fclusterdata
,但是我们必须确保所有点在空间上都是分开的,否则我们会得到复杂的距离,并且pdist
会大声失败(抱怨“有限”数据,因为np.sqrt
当给出负数时将返回nan
,并且nan
无法通过np.isfinite
中的linkage
校验)。通过这种合理的警告,类似以下内容的工作:from scipy.cluster.hierarchy import fclusterdata
from numpy.random import default_rng # only for dummy data
# generate random data, use new random machinery for best practices
N = 10
rng = default_rng()
X = rng.random((N, 4)) * [0.01, 1, 1, 1] # make them all space-like
def physical_minkowski(v1, v2):
"""Return the proper Minkowski metric for 4-vectors with signature -+++"""
return np.sqrt(([-1, 1, 1, 1] * v1).dot(v2))
fclusterdata(X, t=1, metric=physical_minkowski)
# returns uninteresting array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1], dtype=int32)
由于上面的函数可能会被调用很多次,因此使用
numba.njit
对其进行编译以提高性能可能是有意义的。只需进行很小的更改就可以实现:import numba
@numba.njit
def jitted_minkowski(v1, v2):
return np.sqrt((np.array([-1, 1, 1, 1]) * v1).dot(v2))
我使用IPython的内置
%timeit
魔术和N = 1000
为上述两个度量函数计时,以进行合理的比较:>>> %timeit scipy.spatial.distance.pdist(X, metric=physical_minkowski)
... %timeit scipy.spatial.distance.pdist(X, metric=jitted_minkowski)
2.2 s ± 90.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
385 ms ± 12.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
这意味着对于较大的4个向量集,JIT编译的版本要快5倍,并且编译只需执行一次(您甚至可以将编译后的函数缓存在磁盘上,这样就不必每次都编译它了。您运行脚本)。
关于python - Scipy聚类;使用物理Minkowski度量?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59577418/