【问题标题】:Fitting power law function with PyMC用 PyMC 拟合幂律函数
【发布时间】:2014-06-25 07:37:36
【问题描述】:

我目前正在尝试使用 PyMC 来确定适合给定数据的幂律参数。我使用的 pdf 公式取自:

A. Clauset、C. R. Shalizi 和 M. E. J. Newman,“幂律 经验数据中的分布,”Siam rev., vol. 51, iss. 4, pp. 661-703,2009 年。

为了生成具有特定给定参数的示例数据以测试我的代码,我使用了以下 Python 幂律包,该包实现了 Clauset 等人的方法:

https://pypi.python.org/pypi/powerlaw

如果我使用固定的 xmin 值(即幂律函数的下限),我的代码运行良好。但是,一旦我尝试确定 xmin 值,输出就会产生过高的 xmin 值。我已将相应的 xmin 部分注释掉:

test = powerlaw.Power_Law(xmin = 1., parameters = [1.5])
simulated = test.generate_random(1000)
fit = powerlaw.Fit(simulated, xmin=1.)
print fit.alpha
print fit.xmin

xmin = 1.

#alpha = mc.Uniform('alpha', 0,6, value=1.5) 
alpha = mc.Exponential('alpha', 1.5)
#xmin = mc.Uniform('xmin', min(simulated), max(simulated), value=min(simulated))
#xmin = mc.Exponential('xmin', 1.)
#print xmin.value

@mc.stochastic(observed=True)
def power_law(value=simulated, alpha=alpha, xmin=xmin):
    #value = value[value >= xmin]
    return np.sum(np.log((alpha-1) * xmin**(alpha-1) * value**-alpha))

model = mc.MCMC([alpha,xmin,power_law])
model.sample(iter=5000)

print(model.stats()['alpha']['mean'])
#print(model.stats()['xmin']['mean'])

alpha_samples = model.trace('alpha')[:]
#xmin_samples = model.trace('xmin')[:]

figsize(12.5,10)

ax = plt.subplot(311)
ax.set_autoscaley_on(False)

plt.hist(alpha_samples, histtype='stepfilled', bins=20, label="posterior of alpha", color="#A60628", normed=True)
plt.legend(loc="upper left")
plt.xlim([0,2])
plt.xlabel("alpha value")

#plt.subplot(312)

#plt.hist(xmin_samples, histtype='stepfilled', bins=20, 
#         label="posterior of xmin", color="#A60628", normed=True)
#plt.legend(loc="upper left")
#plt.xlim([0,500])
#plt.xlabel("xmin value")

我认为一个问题是我应该始终只考虑我的 power_law 函数中的数据 >= xmin。如果这样做,当我还确定 xmin 时,我会得到“正确”的 alpha 值,但 xmin 仍然太高。我也觉得这是一个不公平的比较,因为要在 MCMC 过程中查看的数据样本大小不同,因此可能性比较也存在偏差。

也许有人知道我该如何处理这个问题。

更新:我当前的代码在这里可用: http://www.philippsinger.info/notebooks/pl_pymc.html

【问题讨论】:

    标签: python distribution bayesian pymc power-law


    【解决方案1】:

    我认为当xmin 小于某些数据值时,您的可能性存在问题是正确的。我的解决方案是明确禁止这种情况,当它出现时返回 -np.inf 的对数似然:

    @mc.stochastic(observed=True)
    def power_law(value=simulated, alpha=alpha, xmin=xmin):
        if value.min() < xmin:
            return -np.inf
        return np.sum(np.log((alpha-1) * xmin**(alpha-1) * value**-alpha))
    

    我还建议使用总样本一半的老化期,并以图形方式检查收敛性,如下所示:

    model.sample(iter=5000, burn=2500)
    pm.Matplot.plot(model)
    

    (见this SO answer for a PyMC3 example of how I like to use burn-in and graphical convergence checks。)

    【讨论】:

    • 感谢转换提示。我自己已经想通了。不过,您误解了 xmin 的问题。我的意思是,对于不同的 xmin 值,我必须查看不同的数据长度。对于 xmin=1 vs xmin=2 的序列 [1,2,3] 我会查看不同的经验数据长度。我在代码中注释了我的方法:value = value[value &gt;= xmin]。你指出的问题也可能有问题,我认为我可以用统一的先验来解决这个问题。
    • 我不认为你的方法是一个有效的解决方案:当xmin=2 你有你忽略的概率为 0 的数据观察。在这种情况下,我认为返回-np.inf 是正确的做法。作为证据,这是我的方法中xmin 的后验平均值,与幂律相比。拟合值:xmin:1.0 与 0.998160020389。这是collected up in a notebook here
    • 好的,我想我现在明白你的方法了。它也适用于更高的xmin 值。但是,在这种情况下,您始终只会考虑低于数据最小值的潜在xmin 值,这只会导致数据的最低值成为适当的xmin 值。这类似于我之前手动将xmin 设置为最低值的结果。不过,幂律拟合的目标是获得幂律适用的最合适的xmin 值。这也可以是一些更高的价值。例如,[1,2,3] xmin 很可能是 2。
    • 我认为你需要一个不同的模型。 Clauset、Shalizi 和 Newman 的方法总是有xmin &lt;= data.min()
    • 这不是真的。在给定经验数据的情况下,在找到适当的xmin 值时明确确定了子句集方法。他们使用所有可能的xmin 值,然后限制数据以保证xmin &lt;= data.min() 并计算每个xmin 的KS 统计量。然后,最小距离确定适当的xmin 值。这正是我想要实现的目标。
    猜你喜欢
    • 2021-06-04
    • 1970-01-01
    • 2014-12-10
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-14
    相关资源
    最近更新 更多