使用python从指数分布和模型生成随机数

使用python从指数分布和模型生成随机数,python,pandas,numpy,random,curve-fitting,Python,Pandas,Numpy,Random,Curve Fitting,我的目标是创建一个随机点的数据集,其直方图类似于指数衰减函数,然后通过这些点绘制指数衰减函数 首先,我尝试从指数分布创建一系列随机数(但没有成功,因为这些应该是点,而不是数字) from pylab import * from scipy.optimize import curve_fit import random import numpy as np import pandas as pd testx = pd.DataFrame(range(10)).astype(float) test

我的目标是创建一个随机点的数据集,其直方图类似于指数衰减函数,然后通过这些点绘制指数衰减函数

首先,我尝试从指数分布创建一系列随机数(但没有成功,因为这些应该是点,而不是数字)

from pylab import *
from scipy.optimize import curve_fit
import random
import numpy as np
import pandas as pd

testx = pd.DataFrame(range(10)).astype(float)
testx = testx[0]

for i in range(1,11):
   x = random.expovariate(15) # rate = 15 arrivals per second
   data[i] = [x]

testy = pd.DataFrame(data).T.astype(float)
testy = testy[0]; testy

plot(testx, testy, 'ko')
结果可能是这样的

然后我定义了一个函数,通过我的点画一条线:

def func(x, a, e):
return a*np.exp(-a*x)+e

popt, pcov = curve_fit(f=func, xdata=testx, ydata=testy, p0 = None, sigma = None) 

print popt # parameters
print pcov # covariance

plot(testx, testy, 'ko')

xx = np.linspace(0, 15, 1000)
plot(xx, func(xx,*popt))

plt.show()
我要寻找的是:(1)一种从指数(衰减)分布创建随机数数组的更优雅的方法,(2)如何测试我的函数是否确实通过数据点


我猜下面的内容与您想要的很接近。你可以用numpy从指数分布中生成一些随机数

data = numpy.random.exponential(5, size=1000)
然后可以使用
numpy.hist
创建它们的直方图,并将直方图值绘制到绘图中。您可能会决定将箱子中间作为点的位置(这种假设当然是错误的,但使用的箱子越多越有效)

配件的工作原理与问题中的代码相同。然后您将发现,我们的拟合粗略地找到了用于数据生成的参数(在本例中为~5)


我同意@ImportanceOfBeingErnes的解决方案,但我想为发行版添加一个(众所周知的?)通用解决方案。如果你有一个带有积分的分布函数,那么你可以通过将随机数与积分的反函数映射得到所需的分布。对于指数函数,积分也是指数的,逆是对数。所以可以这样做:

import matplotlib.pyplot as plt
import numpy as np
from random import random


def gen( a ):
    y=random()
    return( -np.log( y ) / a )


def dist_func( x, a ):
    return( a * np.exp( -a * x) )


data = [ gen(3.14) for x in range(20000) ]
fig = plt.figure()
ax = fig.add_subplot( 1, 1, 1 )
ax.hist(data, bins=80, normed=True, histtype="step") 
ax.plot(np.linspace(0,5,150), dist_func( np.linspace(0,5,150), 3.14 ) )
plt.show()
我想你实际上是在问一个回归问题,这正是Praveen所建议的

有一个bog标准指数衰减,到达y轴,约为y=0.27。因此,其方程式为
y=0.27*exp(-0.27*x)
。我可以围绕这个函数的值建立高斯误差模型,并使用下面的代码绘制结果

import matplotlib.pyplot as plt
from math import exp
from scipy.stats import norm


x = range(0, 16)
Y = [0.27*exp(-0.27*_) for _ in x]
error = norm.rvs(0, scale=0.05, size=9)
simulated_data = [max(0, y+e) for (y,e) in zip(Y[:9],error)]

plt.plot(x, Y, 'b-')
plt.plot(x[:9], simulated_data, 'r.')
plt.show()

print (x[:9])
print (simulated_data)
情节是这样的。请注意,我保存了输出值以供后续使用

现在我可以在自变量上计算受噪声污染的指数衰减值的非线性回归,
curve\u fit
就是这样做的

from math import exp
from scipy.optimize import curve_fit
import numpy as np

def model(x, p):
    return p*np.exp(-p*x)

x = list(range(9))
Y = [0.22219001972988275, 0.15537454187341937, 0.15864069451825827, 0.056411162886672819, 0.037398831058143338, 0.10278251869912845, 0.03984605649260467, 0.0035360087611421981, 0.075855255999424692]

popt, pcov = curve_fit(model, x, Y)
print (popt[0])
print (pcov)
额外的好处是,
curve\u fit
不仅计算参数-0.207962159793的估计值,还提供该估计值方差-0.00086071的估计值,作为
pcov
的一个元素。鉴于样本量较小,这似乎是一个相当小的值

下面是如何计算残差。请注意,每个残差都是数据值和使用参数估计从
x
估计的值之间的差值

residuals = [y-model(_, popt[0]) for (y, _) in zip(Y, x)]
print (residuals)

如果您想进一步“测试我的函数是否确实通过了数据点”,那么我建议您在残差中寻找模式。但是像这样的讨论可能超出了stackoverflow所欢迎的范围:Q-Q和P-P图,残差与
y
x
的图,等等。

你所说的“点”是什么意思还不太清楚。如果你从一个分布中抽取一个随机数(可能是指数分布或其他分布),它是一个数字,而不是一个点。因此,它只有一个坐标,而不是两个,所以它会出现在绘图中的什么位置?因此,也不可能通过一些数字来拟合一个函数。你混淆了两件事:从指数分布中得出一组更可能接近于零的数字,而它们远离零的概率呈指数下降。换句话说,这些数字的直方图将看起来像一个指数衰减函数,而不是数字本身。出于您的目的,您最好选择一些x值(如果您愿意,可以随机选择)并通过应用
exp(-beta*x)+noise
计算y值,其中您的噪声可以是高斯噪声。然后根据你的身材将
beta
a
进行比较。好的,我更新了我的问题,即分数与数字的问题。也许有人的答案可以使用@Praveen的建议,随机选择x值,并使用
exp(-beta*x)+noise
计算y值。嗨@Bill Bell谢谢你的回答。这对我很有帮助。你能告诉我如何使用python获取残差的函数或文档吗?我已经改变了答案,从“这是如何计算残差的方法”开始。@JAG2024:如果这是你需要的,你愿意吗?
residuals = [y-model(_, popt[0]) for (y, _) in zip(Y, x)]
print (residuals)