python - 从分位数拟合分布
问题描述
我正在尝试从 Python 中的 SAS复制一个示例,在该示例中我拟合了汇总统计数据的分布。我可用的汇总统计数据是总数、最小值、最大值、p50、p75、p85、p95、p98、p99 和 p99.9。测量来自分布式机器网络,包括延迟或大小分布。目标是从每台机器重新构建混合,然后结合这些分布来估计整个网络的分布,并以流式方式定期执行此操作。
我正在查看PyMC、Pyro和Pomegranate的文档并获得混合模型的一般要点,但我不明白的是如何为每个分布设置初始参数,给定可用数据使用哪个对我来说,或者如何将每个分布转移到相应的分位数以构建整体分布。
考虑到这些框架中的任何一个,这可能吗?
解决方案
在Pyro 论坛的帮助下回答我自己的问题。下面的代码包含问题前半部分的解决方案,从收集的分位数中找到与参数匹配的分布:
import torch
import torch.distributions as dist
from torch.optim import Adam
from typing import List, Tuple
def find_cauchy_params(quantiles: List[Tuple[float, float]]):
alpha = torch.tensor(1.0, requires_grad=True)
beta = torch.tensor(1.0, requires_grad=True)
quantile_tensors = [
(quantile, torch.tensor(quantile_value))
for quantile, quantile_value in quantiles
]
def loss_fn():
loss = 0.0
d = dist.Cauchy(alpha, beta)
for quantile, quantile_value in quantile_tensors:
loss += (quantile - d.cdf(quantile_value)) ** 2
return loss
optim = Adam([alpha, beta], lr=0.01)
for step in range(1000):
optim.zero_grad()
loss = loss_fn()
print("loss", loss)
loss.backward()
optim.step()
print("alpha = {}".format(alpha.item()))
print("beta = {}".format(beta.item()))
find_cauchy_params(
[(0.5, 0.0), (0.75, 0.0), (0.95, 1.0), (0.98, 1.0), (0.99, 8.0), (0.999, 11.0)]
)
截断输出:
...
loss tensor(0.0317, grad_fn=<AddBackward0>)
loss tensor(0.0317, grad_fn=<AddBackward0>)
loss tensor(0.0317, grad_fn=<AddBackward0>)
loss tensor(0.0317, grad_fn=<AddBackward0>)
alpha = -0.04828706011176109
beta = 0.11657208949327469
推荐阅读
- javascript - 我想将对象的平面数组存储为嵌套对象形式(如树格式)
- java - MongoDB Java驱动程序将嵌套对象的id字段转换为_id
- python - Tkinter 主题和背景
- mysql - mysqli_real_connect(): (HY000/1045): Access denied for user 'phpmyadmin'@'localhost' (使用密码: YES)
- javascript - 在删除 baseHref Angular 后状态导航不起作用
- django - 如何为不具有相同值的 2 个字段添加约束?
- css - 文本与 justify-content: space-evenly 奇怪地对齐;
- prolog - Prolog - 如何将时间戳设置为谓词中的参数?
- sql - sqlite:如何以不平凡的方式修改列内容[示例]
- python - 如何在seaborn distplot的模式下画一条垂直线