我使用scipy.stats
的随机变量如下:
import scipy.stats as st
x1 = st.uniform()
x2 = st.uniform()
现在我想基于先前的随机变量创建另一个随机变量,并为新的随机变量进行var
之类的计算。假设我希望新的随机变量类似于max(2, x1) + x2
。如何动态定义?
答案 0 :(得分:0)
我的旧答案如下:
(当引用SO文档的答案被删除时,我被提示再次查看这个问题。我认为这是一个更好的答案。)
首先,据我所知,对于两个或多个变量的非线性函数的方差,没有一般方法可以得到一个很好的闭式表达式。可能大多数凡人采用某种蒙特卡罗策略来近似这样的数量。
以下是一些代码,可以生成针对此特定情况执行此操作的绘图。它适用于许多其他人。
从单位均匀随机变量生成两个伪随机样本,然后计算伪随机随机变量Y
作为这些样本元素的函数。
>>> import scipy.stats as stats
>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> X1 = stats.uniform.rvs(0,1, 5000)
>>> X2 = stats.uniform.rvs(0,1, 5000)
>>> Y = [max(2,x1)+x2 for (x1,x2) in zip(X1,X2)]
现在,为了确定该函数的密度函数,绘制其直方图。
>>> plt.hist(Y)
(array([ 501., 526., 490., 481., 513., 488., 525., 490., 521., 465.]), array([ 2.00012599, 2.10007992, 2.20003386, 2.2999878 , 2.39994173,
2.49989567, 2.59984961, 2.69980354, 2.79975748, 2.89971141,
2.99966535]), <a list of 10 Patch objects>)
>>> plt.show()
我们很幸运,因为它很容易识别。在这里。
这是一种制服,其支持是封闭的间隔[2,3]。我们可以再次使用scipy,这次是为了获得它的方差。其他时刻可用;见文档。
>>> stats.uniform.stats(2,1, moments='v')
array(0.08333333333333333)
这些都不是真的必要,不是吗?
作为U(0,1)随机变量X1从不超过1.因此,max(X1,2)必须为2.那么2 + X2必须是U(2,3)。该随机变量与X2具有相同的比例;只是它的位置已经改变。因此,它的方差必须相同,并且U(0,1)的方差为0.0833333。
编辑“下一天”:
刚刚学会(来自https://stackoverflow.com/a/46383333/131187)同情现在支持随机变量我很想尝试解决这个问题。
>>> from sympy.stats import Uniform, Variance
>>> from sympy import symbols, Integral
>>> X1 = Uniform('X1', 0, 1)
>>> X2 = Uniform('X2', 0, 1)
唉,正如其他答案的作者所说,似乎无法处理涉及max
的表达。
>>> Variance(max(2, X1) + X2)
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "C:\Python34\lib\site-packages\sympy-1.0.1.dev0-py3.4.egg\sympy\core\relational.py", line 195, in __nonzero__
raise TypeError("cannot determine truth value of Relational")
TypeError: cannot determine truth value of Relational
但是在这个问题的情况下并不重要。它很容易消除。我们有,它产生方差积分的精确值。
>>> Variance(2 + X2)
Variance(X2 + 2)
>>> Variance(2 + X2).evaluate_integral()
1/12
'旧答案'从这里开始:
我认为不是直接的。但是,这种方法可能对您有用。
假设您首先知道感兴趣的随机变量的函数的pdf或cdf。然后你可以在scipy.stats中使用rv_continuous来计算该函数的方差和其他时刻。
显然'有趣'从这里开始。通常你会尝试定义cdf。对于随机变量的任何给定值,这是表达式(例如您给出的表达式)不超过给定值的概率。因此,确定cdf减少到解决两个变量中的(无限)不等式集合。当然,通常有强大的模式可以大大降低执行此任务的复杂性和难度。
答案 1 :(得分:0)
在OpenTURNS中,使用Symbolic functions可以进行更多的操作。
在您的情况下,x1和x2代表独立分布
import openturns as ot
x1 = ot.Uniform()
x2 = ot.Uniform()
因此,边际分别为x1和x2的组合分布为:
dist = ot.ComposedDistribution([x1, x2], ot.IndependentCopula(2))
dist.setDescription(["x1", "x2"]) # labels
# note the use of "IndependentCopula of dimension 2" as second argument
如果您要使用大小为5的样本
sample = dist.getSample(5)
print(sample)
>>> [ x1 x2 ]
0 : [ -0.752141 -0.897212 ]
1 : [ 0.850966 0.857914 ]
2 : [ -0.340213 -0.344882 ]
3 : [ -0.166526 0.458643 ]
4 : [ 0.378453 -0.908958 ]
如前所述,您可以将基于(x1,x2)的模型定义为符号函数。在您的示例中:y = max(2,x1)+ x2
model = ot.SymbolicFunction(["x1", "x2"], ["max(2, x1) + x2"])
您可以申请model(sample)
[ y0 ]
0 : [ 1.10279 ]
1 : [ 2.85791 ]
2 : [ 1.65512 ]
3 : [ 2.45864 ]
4 : [ 1.09104 ]
但是您的模型可以是多维的。例如:
model = ot.SymbolicFunction(["x1", "x2"], ["x1^2+x2", "x2^2+x1"])
应用于样品将产生二维样品
>>> [ y0 y1 ]
0 -0.331496 0.05284813
1 1.582057 1.586982
2 -0.2291374 -0.2212693
3 0.4863741 0.04382738
4 -0.7657314 1.204657
在创建更高级的模型时,这非常有趣。在后一种情况下,绘制大小为10,000 out = model(dist.getSample(10000))
的输出可得出
import matplotlib.pyplot as plt
plt.scatter(out.getMarginal(0),out.getMarginal(1), s=0.5)