散圆方差

2024-10-02 12:24:09 发布

您现在位置:Python中文网/ 问答频道 /正文

根据我的理解,循环方差的范围是0到1。这在wikipedia以及{a2}中也得到了确认。但由于某些原因,scipy.stats的循环方差函数给出了大于1的值。在

import numpy as np
from scipy.stats import circmean, circvar

a = np.random.randint(0, high=360, size=10)

print(a)
print(circmean(a, 0, 360))
print(circvar(np.deg2rad(a)))
[143 116 152 172 349 152 182 306 345  81]
135.34974541954665
2.2576538466653857

有人能告诉我为什么我从函数circvar得到大于1的值


Tags: 函数fromimportnumpya2asstatsnp
3条回答

可能不应该。circstd的计算看起来正常:

return ((high - low)/2.0/pi) * sqrt(-2*log(R))

但是,circvar的计算看起来是错误的:

^{pr2}$

我不知道它为什么把循环方差计算成2*ln(1/R)。这可能是我以前从未见过的近似值,但我不知道-我可能会为此打开一个bug。在

根据docstring

... uses a definition of circular variance that in the limit of small angles returns a number close to the 'linear' variance.

事实上,它是维基百科所说的circstd的平方

... values between 0 and infinity. This definition of the standard deviation ... is useful because for a wrapped normal distribution, it is an estimator of the standard deviation of the underlying normal distribution. It will therefore allow the circular distribution to be standardized as in the linear case, for small values of the standard deviation. This also applies to the von Mises distribution ...

它还提到,对于小息差,循环方差的两个定义是相同的,直到因子为2。在

不太有用的答案是因为scipy就是这样定义它的,所以你最好让开发人员得到一个明确的答案。 真正地。文档中的示例是

from scipy.stats import circvar
circvar([0, 2*np.pi/3, 5*np.pi/3])
2.19722457734

所以你不能说这种行为是未经批准的。 但为什么要这样做呢?在

你的第二个链接定义了一组n个角a_1。。。作为联合国

V = 1 − \hat{R_1}

在哪里

\hat{R_1} = R_1 / n R_1 = \sqrt{C^2 + S^2}

以及

C = \sum_{i=1}^n cos(a_i) S = \sum_{i=1}^n sin(a_i)

scipy库通过

^{pr2}$

这有点难理解。 如果我们假设样本是零均值,范围是[0,2*pi],并且使用默认轴(在示例中都是真的),可以将其简化为

S = mean(sin(samples))
C = mean(cos(samples))
R = hypot(S, C)
V = 2 * log(1/R)

所以scipy使用的定义是通过2*log(1/R)而不是1-R来转换R。 这似乎很奇怪。 纵观历史,https://github.com/scipy/scipy/blame/v1.1.0/scipy/stats/morestats.py#L2696-L2733,统计数据一度是用

ang = (samples - low)*2*pi / (high-low)
res = stats.mean(exp(1j*ang))
V = 1-abs(res)
return ((high-low)/2.0/pi)**2 * V

这似乎符合你提供的定义。 在添加测试的同时,在一个错误修复中改变了这一点,但是没有提到新的计算是从哪里来的。在

关于scipy bug跟踪器的一些讨论可以在https://github.com/scipy/scipy/pull/5747上找到。 这表明这种行为是故意的,不会被纠正。 astropy中还有另一个可用的实现http://docs.astropy.org/en/stable/api/astropy.stats.circvar.html,它指出

The definition used here differs from the one in scipy.stats.circvar. Precisely, Scipy circvar uses an approximation based on the limit of small angles which approaches the linear variance.

因此,总而言之,由于未知原因,scipy使用了一个近似值(在某些情况下这似乎相当糟糕)。但是,由于向后兼容,它不会被修复,所以您可能需要使用astropy的实现。在

相关问题 更多 >

    热门问题