我使用scipy计算跟随积分:
from scipy.stats import norm
def integrand(y, x):
# print "y: %s x: %s" % (y,x)
return (du(y)*measurment_outcome_belief(x, 3)(y))*fv_belief(item.mean, item.var)(x)
return dblquad(
integrand, norm.ppf(0.001, item.mean, item.var),
norm.ppf(0.999, item.mean, item.var),
lambda x: norm.ppf(0.001, x, 3),
lambda x: norm.ppf(0.999, x, 3))[0]
我有项目(正态分布)的信念状态和以项目的实际价值为条件的测量。(也是正态分布) 使用此积分i计算信息的值(测量此项目的有用程度)。
计算此积分需要花费大量时间的问题。 是否有更有效的方法来计算它(我不需要100%的精度),如monte carlo整合或类似的东西?
我知道在python中有skmonaco
库用于monte carlo积分,但积分的限制必须是数字,不像scipy,内部积分限制,取决于外部(例如从上面
lambda x: norm.ppf(0.001, x, 3)
) 这里如何使用skmonaco计算双积分
>>> from skmonaco import mcquad
>>> mcquad(lambda x_y: x_y[0]*x_y[1], # integrand
... xl=[0.,0.],xu=[1.,1.], # lower and upper limits of integration
... npoints=100000 # number of points
... )
正如您所看到的,内部积分的极限不依赖于外积分。 有人可以推荐库或方法来有效地计算这个积分吗?
答案 0 :(得分:2)
在scikit-monaco中处理非立方集成卷的最简单方法是重新定义集成函数,使其在集成区域之外返回0(请参阅文档的this部分):
def modified_integrand(xs):
x, y = xs
if norm.ppf(0.001, x, 3) < y < norm.ppf(0.999, x, 3):
return integrand(xs) # the actual integrand
else:
return 0.0
正如Ami Tavori所说,如果集成区域的大部分区域为零,这将是非常低效的。为了进行调解,您可以使用MISER或VEGAS算法:这两种算法都可以“学习”积分的形状,以便在感兴趣的区域更有效地分布点。
那就是说,你的整合区域基本上是一个旋转的矩形:
import matplotlib.pyplot as plt
from scipy.stats import norm
import numpy as np
xs = np.linspace(-10, 10)
ys = np.linspace(-10, 10)
# Plot integration domain
# Red regions are in the domain of integration, blue
# regions are outside
plt.contourf(xs, ys,
[ [ 1 if norm.ppf(0.001, x, 3) < y < norm.ppf(0.999, x, 3)
else 0 for x in xs ] for y in ys ])
在这种情况下,旋转积分坐标会好得多。例如,定义
r = x - y
R = (x + y)/2.0
您的被子是:
def rotated_integrand(rs):
R, r = rs
x = R + r/2.0
y = R - r/2.0
return integrand(np.array([x,y]))
r
中的积分限制现在是常量(-9.27..9.27
,在您给出的示例中)。 R
上的积分限制仍为(-inf
,inf
),因此您需要逐渐增加R
的积分区域,直到积分收敛为止。我肯定会建议使用MISER算法(scikit-monaco中的mcmiser
),而不是统一采样。
最后,根据您使用的函数的名称判断,看起来您正在进行某种形式的贝叶斯更新。如果是这种情况,您可以考虑使用Markov Chain Monte Carlo的PyMC库,这可能比通用MC集成库更合适。
答案 1 :(得分:1)
蒙特卡洛集成是一个好主意,并不难实现。然而,相对于其他方法,均匀地对点进行采样会收敛,这些方法迭代地进行采样,并且在每个步骤中,基于体积的样本直到该点为止。
检查recursive stratified sampling。
适应您的自定义区域(显然不是超立方体)可能不会非常困难。
不幸的是,我认为没有Python库能够开箱即用。