- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
作为研究的一部分,我从对数正态分布测量平局的均值和标准差。给定基础正态分布的值,应该可以分析性地预测这些数量(如https://en.wikipedia.org/wiki/Log-normal_distribution所示)。
但是,如下图所示,情况似乎并非如此。第一个图显示了对数正态数据相对于高斯σ的均值,而第二个图显示了对数正态数据相对于高斯的σ。显然,“计算”线与“分析”线非常不同。
我将高斯分布的均值与mu = -0.5*sigma**2
与sigma相关联,因为这确保了对数正态场的均值应为1。请注意,这是由我从事的物理学领域引起的:例如,如果设置mu=0.0
,分析值仍然会发生。
通过将代码复制并粘贴到问题的底部,应该可以复制下面的图。任何有关可能导致此问题的建议将不胜感激!
对数正态与高斯西格玛的均值:
对数正态的Sigma与高斯的Sigma:
注意,要生成上面的图,我使用了N=10000
,但是为了提高速度在下面的代码中添加了N=1000
。
import numpy as np
import matplotlib.pyplot as plt
mean_calc = []
sigma_calc = []
mean_analytic = []
sigma_analytic = []
ss = np.linspace(1.0,10.0,46)
N = 1000
for s in ss:
mu = -0.5*s*s
ln = np.random.lognormal(mean=mu, sigma=s, size=(N,N))
mean_calc += [np.average(ln)]
sigma_calc += [np.std(ln)]
mean_analytic += [np.exp(mu+0.5*s*s)]
sigma_analytic += [np.sqrt((np.exp(s**2)-1)*(np.exp(2*mu + s*s)))]
plt.loglog(ss,mean_calc,label='calculated')
plt.loglog(ss,mean_analytic,label='analytic')
plt.legend();plt.grid()
plt.xlabel(r'$\sigma_G$')
plt.ylabel(r'$\mu_{LN}$')
plt.show()
plt.loglog(ss,sigma_calc,label='calculated')
plt.loglog(ss,sigma_analytic,label='analytic')
plt.legend();plt.grid()
plt.xlabel(r'$\sigma_G$')
plt.ylabel(r'$\sigma_{LN}$')
plt.show()
最佳答案
TL; DR
对数正态分布呈正偏态,尾部分布较重。当对从高度偏斜分布中抽取的样本执行浮点算术运算(例如求和,均值或标准差)时,采样向量将包含在几个数量级(数十年)内具有差异的值。这使得计算不准确。
问题来自这两行:
mean_calc += [np.average(ln)]
sigma_calc += [np.std(ln)]
ln
包含非常低和非常高的值,其数量级远高于浮点精度。
(max(ln) + min(ln)) <= max(ln)
from scipy import stats
for s in ss:
mu = -0.5*s*s
ln = stats.lognorm(s, scale=np.exp(mu)).rvs(N*N)
f = stats.lognorm.fit(ln, floc=0)
mean_calc += [f[2]*np.exp(0.5*s*s)]
sigma_calc += [np.sqrt((np.exp(f[0]**2)-1)*(np.exp(2*mu + s*s)))]
mean_analytic += [np.exp(mu+0.5*s*s)]
sigma_analytic += [np.sqrt((np.exp(s**2)-1)*(np.exp(2*mu + s*s)))]
fit
使用MLE算法估计参数。这与您直接执行样本均值的原始方法完全不同。
fit
方法返回带有
(sigma, loc=0, scale=exp(mu))
的元组,该元组是文档中指定的
scipy.stats.lognorm
对象的参数。
N
和
100
之间的
10000
范围)并且将scale参数设置为的对数正态分布中绘制了不同大小(
sigma
和
0.1
之间的
10
范围)的样本。酉。
import warnings
import numpy as np
from scipy import stats
# Make computation reproducible among batches:
np.random.seed(123456789)
# Parameters ranges:
sigmas = np.arange(0.1, 10.1, 0.1)
sizes = np.logspace(2, 5, 21, base=10).astype(int)
# Placeholders:
rv = np.empty((sigmas.size,), dtype=object)
xmean = np.full((3, sigmas.size, sizes.size), np.nan)
xstd = np.full((3, sigmas.size, sizes.size), np.nan)
xextent = np.full((2, sigmas.size, sizes.size), np.nan)
eps = np.finfo(np.float64).eps
# Iterate Shape Parameter:
for (i, s) in enumerate(sigmas):
# Create Random Variable:
rv[i] = stats.lognorm(s, loc=0, scale=1)
# Iterate Sample Size:
for (j, N) in enumerate(sizes):
# Draw Samples:
xs = rv[i].rvs(N)
# Sample Extent:
xextent[:,i,j] = [np.min(xs), np.max(xs)]
# Check (max(x) + min(x)) <= max(x)
if (xextent[0,i,j] + xextent[1,i,j]) - xextent[1,i,j] < eps:
warnings.warn("Potential Float Arithmetic Errors: logN(mu=%.2f, sigma=%2f).sample(%d)" % (0, s, N))
# Generate different Estimators:
# Fit Parameters using MLE:
fit = stats.lognorm.fit(xs, floc=0)
xmean[0,i,j] = fit[2]
xstd[0,i,j] = fit[0]
# Naive (Bad Estimators because of Float Arithmetic Error):
xmean[1,i,j] = np.mean(xs)*np.exp(-0.5*s**2)
xstd[1,i,j] = np.sqrt(np.log(np.std(xs)**2*np.exp(-s**2)+1))
# Log-transform:
xmean[2,i,j] = np.exp(np.mean(np.log(xs)))
xstd[2,i,j] = np.std(np.log(xs))
sigma > 4
时,新的MCVE开始发出警告。
np.finfo(np.float64).precision # 15
np.finfo(np.float64).eps # 2.220446049250313e-16
1 + 1e6
的结果是什么?
1,000,001.0
,但必须四舍五入为
1.000e6
。这意味着:由于舍入精度,运算的结果等于最大数。它是有限精度算法的固有特性。
N
不会改善MCVE中较大的
sigma
值的估计。
sigma > 3
时,我们没有足够的有效数字(小于5)来执行有效的计算。
N
,使估计量默认为有偏差。
np.mean(xs)
np.std(xs)
xs
中存储的值之间的重大差异,估计值将具有巨大的算术浮点误差。下图重现了您的问题:
xmean[2,i,j] = np.exp(np.mean(np.log(xs)))
xstd[2,i,j] = np.std(np.log(xs))
N
和
sigma
,采用对数变换得出的均值和标准差估计值均与MLE相同:
np.allclose(xmean[0,:,:], xmean[2,:,:]) # True
np.allclose(xstd[0,:,:], xstd[2,:,:]) # True
import matplotlib.pyplot as plt
fig, axe = plt.subplots()
idx = slice(None, None, 5)
axe.loglog(sigmas, xmean[0,:,idx])
axe.axhline(1, linestyle=':', color='k')
axe.set_title(r"MLE: $x \sim \log\mathcal{N}(\mu=0,\sigma)$")
axe.set_xlabel(r"Standard Deviation, $\sigma$")
axe.set_ylabel(r"Mean Estimation, $\hat{\mu}$")
axe.set_ylim([0.1,10])
lgd = axe.legend([r"$N = %d$" % s for s in sizes[idx]] + ['Exact'], bbox_to_anchor=(1,1), loc='upper left')
axe.grid(which='both')
fig.savefig('Lognorm_MLE_Emean_Sigma.png', dpi=120, bbox_extra_artists=(lgd,), bbox_inches='tight')
关于python - 对数正态分布的均值和标准差与分析值不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53651223/
我的问题:非常具体。我正在尝试想出解析以下文本的最简单方法: ^^domain=domain_value^^version=version_value^^account_type=account_ty
好吧,这就是我的困境: 我正在为 Reddit 子版 block 开发常见问题解答机器人。我在 bool 逻辑方面遇到了麻烦,需要一双更有经验的眼睛(这是我在 Python 中的第一次冒险)。现在,该
它首先遍历所有 y 值,然后遍历所有 x 值。我需要 X 和 y 同时改变。 For x = 3 To lr + 1 For y = 2 To lr anyl.Cells(x, 1)
假设我有一个包含 2 列的 Excel 表格:单元格 A1 到 A10 中的日期和 B1 到 B10 中的值。 我想对五月日期的所有值求和。我有3种可能性: {=SUM((MONTH(A1:A10)=
如何转换 Z-score来自 Z-distribution (standard normal distribution, Gaussian distribution)到 p-value ?我还没有找到
我正在重写一些 Javascript 代码以在 Excel VBA 中工作。由于在这个网站上搜索,我已经设法翻译了几乎所有的 Javascript 代码!但是,有些代码我无法准确理解它在做什么。这是一
我遇到过包含日期格式的时间戳日期的情况。然后我想构建一个图表,显示“点击”项目的数量“每天”, //array declaration $array1 = array("Date" => 0); $a
我是scala的新手! 我的问题是,是否有包含成员的案例类 myItem:Option[String] 当我构造类时,我需要将字符串内容包装在: Option("some string") 要么 So
我正在用 PHP 创建一个登录系统。我需要用户使用他或她的用户名或电子邮件或电话号码登录然后使用密码。因为我知道在 Java 中我们会像 email==user^ username == user 这
我在 C++ 项目上使用 sqlite,但是当我在具有文本值的列上使用 WHERE 时出现问题 我创建了一个 sqlite 数据库: CREATE TABLE User( id INTEGER
当构造函数是显式时,它不用于隐式转换。在给定的代码片段中,构造函数被标记为 explicit。那为什么在 foo obj1(10.25); 情况下它可以工作,而在 foo obj2=10.25; 情况
我知道这是一个主观问题,所以如果需要关闭它,我深表歉意,但我觉得它经常出现,让我想知道是否普遍偏爱一种形式而不是另一种形式。 显然,最好的答案是“重构代码,这样你就不需要测试是否存在错误”,但有时没有
这两个 jQuery 选择器有什么区别? 以下是来自 w3schools.com 的定义: [attribute~=value] 选择器选择带有特定属性,其值包含特定字符串。 [attribute*=
为什么我们需要CSS [attribute|=value] Selector根本当 CSS3 [attribute*=value] Selector基本上完成相同的事情,浏览器兼容性几乎相似?是否存在
我正在解决 regx 问题。我已经有一个像这样的 regx [0-9]*([.][0-9]{2})。这是 amont 格式验证。现在,通过此验证,我想包括不应提供 0 金额。比如 10 是有效的,但
我正在研究计算机科学 A 考试的样题,但无法弄清楚为什么以下问题的正确答案是正确的。 考虑以下方法。 public static void mystery(List nums) { for (
好的,我正在编写一个 Perl 程序,它有一个我收集的值的哈希值(完全在一个完全独立的程序中)并提供给这个 Perl 脚本。这个散列是 (string,string) 的散列。 我想通过 3 种方式对
我有一个表数据如下,来自不同的表。仅当第三列具有值“债务”并且第一列(日期)具有最大值时,我才想从第四列中获取最大值。最终值基于 MAX(DATE) 而不是 MAX(PRICE)。所以用简单的语言来说
我有一个奇怪的情况,只有错误状态保存到数据库中。当“状态”应该为 true 时,我的查询仍然执行 false。 我有具有此功能的 Controller public function change_a
我有一个交易表(针对所需列进行了简化): id client_id value 1 1 200 2 2 150 3 1
我是一名优秀的程序员,十分优秀!