关于scipy.stats.rv_continuous的子类化我有3个问题。 我的目标是编码截断正态分布,截断指数分布和2个均匀分布的统计混合模型。
1)为什么通过mm_model.rvs(size = 1000)绘制随机变量这么慢?我在纪录片中读到了一些关于性能问题的内容,但我真的很惊讶。
2)通过mm_model.rvs(size = 1000)绘制随机变量后,我得到了这个IntegrationWarning?
IntegrationWarning:已实现最大细分数(50)。 如果增加限制没有产生任何改善,建议分析 被积函数以确定困难。如果一个位置 可以确定局部困难(奇点,不连续性) 可能从分割间隔和调用积分器中获益 关于子范围。也许应该使用专用集成商。 warnings.warn(msg,IntegrationWarning)
3)我在纪录片中读到我可以通过"形状"将参数传送到pdf。参数。我试着调整我的pdf并设置形状参数,但它没有用。有人可以解释一下吗?
感谢您的帮助。
def trunc_norm(z,low_bound,up_bound,mu,sigma):
a = (low_bound - mu) / sigma
b = (up_bound - mu) / sigma
return stats.truncnorm.pdf(z,a,b,loc=mu,scale=sigma)
def trunc_exp(z,up_bound,lam):
return stats.truncexpon.pdf(z,b=up_bound*lam,scale=1/lam)
def uniform(z,a,b):
return stats.uniform.pdf(z,loc=a,scale=(b-a))
class Measure_mixture_model(stats.rv_continuous):
def _pdf(self,z):
z_true = 8
z_min = 0
z_max = 10
p_hit = 0.7
p_short = 0.1
p_max = 0.1
p_rand = 0.1
sig_hit = 1
lambda_short = 0.5
sum_p = p_hit + p_short + p_max + p_rand
if sum_p < 0.99 or 1.01 < sum_p:
misc.eprint("apriori probabilities p_hit, p_short, p_max, p_rand have to be 1!")
return None
pdf_hit = trunc_norm(z,z_min,z_max,z_true,sig_hit)
pdf_short = trunc_exp(z,z_true,lambda_short)
pdf_max = uniform(z,0.99*z_max,z_max)
pdf_rand = uniform(z,z_min,z_max)
pdf = p_hit * pdf_hit + p_short * pdf_short + p_max * pdf_max + p_rand * pdf_rand
return pdf
#mm_model = Measure_mixture_model(shapes='z_true,z_min,z_max,p_hit,p_short,p_max,p_rand,sig_hit,lambda_short')
mm_model = Measure_mixture_model()
z = np.linspace(-1,11,1000)
samples = mm_model.pdf(z)
plt.plot(z,samples)
plt.show()
rand_samples = mm_model.rvs(size = 1000)
bins = np.linspace(-1, 11, 100)
plt.hist(rand_samples,bins)
plt.title("measure mixture model")
plt.xlabel("z: measurement")
plt.ylabel("p: relative frequency")
plt.show()
答案 0 :(得分:0)
(1)和(2)可能是相关的。您要求scipy仅根据您提供的密度生成随机样本。
我真的不知道scipy会做什么,但我怀疑它整合了密度(&#34; pdf&#34;)以获得概率函数(&#34; cdf&#34;)然后反转它将统一样本映射到您的分布。这在数字上是昂贵的,因为您经历了容易出错。
为了加快速度,您可以直接实施_rvs
来帮助实现目标。只需绘制一个制服来决定要选择混合的哪个子模型,然后调用所选子模型的rvs
。与您可能需要的其他功能类似。
以下是有关如何实现矢量化rvs
的一些提示:
批量选择子模型。由于您的子模型数量很少np.digitize
应该足够好。如果可能,请为子模型使用rv_frozen
个实例;它们非常方便,但我似乎记得你不能将所有可选参数传递给它们,所以你可能需要单独处理它们。
self._bins = np.cumsum([p_hit, p_short, p_max])
self._bins /= self._bins[-1] + p_rand
submodel = np.digitize(uniform.rvs(size=size), self._bins)
result = np.empty(size)
for j, frozen in enumerate((frz_trunc_norm, frz_trunc_exp, frz_unif_1, frz_unif_2)):
inds = np.where(submodel == j)
result[inds] = frozen.rvs(size=inds.shape)
return result
Re(3)这是scipy docs所说的。
关于形状的注释:子类不需要明确指定它们。在这种情况下,将从被覆盖的方法(pdf,cdf等)的签名中自动推导出形状。如果由于某种原因,您希望避免依赖内省,则可以明确指定形状作为实例构造函数的参数。
所以通常的方法是在你的方法中加入一些参数。