ฉันต้องการดึงตัวอย่างจากการแจกแจงความน่าจะเป็นด้วย CDF 1 - e^(-x^2)
มีวิธีใน python/scipy/etc หรือไม่ เพื่อให้คุณสามารถสุ่มตัวอย่างจากการแจกแจงความน่าจะเป็นโดยให้เฉพาะ CDF เท่านั้น
ฉันต้องการดึงตัวอย่างจากการแจกแจงความน่าจะเป็นด้วย CDF 1 - e^(-x^2)
มีวิธีใน python/scipy/etc หรือไม่ เพื่อให้คุณสามารถสุ่มตัวอย่างจากการแจกแจงความน่าจะเป็นโดยให้เฉพาะ CDF เท่านั้น
หากต้องการสร้างคลาสตัวแปรสุ่มที่กำหนดเองโดยกำหนด CDF คุณสามารถคลาสย่อย scipy.rv_continuous
และแทนที่ rv_continuous._cdf
จากนั้นจะสร้าง PDF ที่เกี่ยวข้องและข้อมูลทางสถิติอื่น ๆ เกี่ยวกับการจัดจำหน่ายของคุณโดยอัตโนมัติ เช่น
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats
class MyRandomVariableClass(stats.rv_continuous):
def __init__(self, xtol=1e-14, seed=None):
super().__init__(a=0, xtol=xtol, seed=seed)
def _cdf(self, x):
return 1-np.exp(-x**2)
if __name__ == "__main__":
my_rv = MyRandomVariableClass()
# sample distribution
samples = my_rv.rvs(size = 1000)
# plot histogram of samples
fig, ax1 = plt.subplots()
ax1.hist(list(samples), bins=50)
# plot PDF and CDF of distribution
pts = np.linspace(0, 5)
ax2 = ax1.twinx()
ax2.set_ylim(0,1.1)
ax2.plot(pts, my_rv.pdf(pts), color='red')
ax2.plot(pts, my_rv.cdf(pts), color='orange')
fig.tight_layout()
plt.show()
หากต้องการเพิ่มโซลูชันโดย Heike คุณสามารถใช้ Inverse Transform Sampling เพื่อสุ่มตัวอย่างผ่าน CDF : :
import math, random
import matplotlib.pyplot as plt
def inverse_cdf(y):
# Computed analytically
return math.sqrt(math.log(-1/(y - 1)))
def sample_distribution():
uniform_random_sample = random.random()
return inverse_cdf(uniform_random_sample)
x = [sample_distribution() for i in range(10000)]
plt.hist(x, bins=50)
plt.show()
ฉันอยากรู้มากว่าสิ่งนี้ทำงานอย่างไรใน SciPy เช่นกัน ดูเหมือนว่ามันจะทำอะไรบางอย่างที่คล้ายคลึงกับข้างต้นมาก อ้างอิงจากเอกสาร SciPy:
วิธีการเริ่มต้น _rvs อาศัยค่าผกผันของ cdf, _ppf ซึ่งใช้กับตัวแปรสุ่มที่สม่ำเสมอ ในการสร้างตัวแปรสุ่มอย่างมีประสิทธิภาพ จำเป็นต้องเขียนทับ _ppf เริ่มต้น (เช่น หาก cdf ผกผันสามารถแสดงในรูปแบบที่ชัดเจนได้) หรือจำเป็นต้องใช้วิธีการสุ่มตัวอย่างในวิธีการ _rvs ที่กำหนดเอง
และอิงตาม ซอร์สโค้ด SciPy, _ppf
(นั่นคือค่าผกผันของ CDF) ที่จริงแล้วดูเหมือนว่าจะมีการประมาณเป็นตัวเลขหากไม่ได้ระบุไว้อย่างชัดเจน เจ๋งมาก!