gpt4 book ai didi

python - 如何实现高斯分布的概率密度函数

转载 作者:行者123 更新时间:2023-11-28 21:40:07 26 4
gpt4 key购买 nike

我需要在 Python 中实现一个类,它表示单变量(目前)正态分布。我的想法如下

class Norm():
def __init__(self, mu=0, sigma_sq=1):
self.mu = mu
self.sigma_sq = sigma_sq
# some initialization if necessary

def sample(self):
# generate a sample, where the probability of the value
# of the sample being generated is distributed according
# a normal distribution with a particular mean and variance
pass

N = Norm()
N.sample()

生成的样本应该按照下面的概率密度函数分布

probability density function for normal distribution

我知道 scipy.statsNumpy 提供了执行此操作的函数,但我需要了解这些函数是如何实现的。任何帮助将不胜感激,谢谢:)

最佳答案

我最终使用了@sascha 的建议。我看了两个 this维基百科文章和 Numpy 源代码并找到了这个 randomkit.c实现函数 rk_gauss(实现 Box Muller 变换)、rk_doublerk_random(实现模拟的 Mersenne Twister 随机数生成器)的文件Box Muller 变换所需的均匀分布随机变量)。

然后我从 here 改编了 Mersenne Twister Generator并实现 Box Muller 变换以模拟高斯分布(有关随机扭曲生成器的更多信息 here)。

这是我最后写的代码:

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

class Distribution():
def __init__(self):
pass

def plot(self, number_of_samples=100000):
# the histogram of the data
n, bins, patches = plt.hist([self.sample() for i in range(number_of_samples)], 100, normed=1, facecolor='g', alpha=0.75)
plt.show()

def sample(self):
# dummy sample function (to be overridden)
return 1

class Uniform_distribution(Distribution):
# Create a length 624 list to store the state of the generator
MT = [0 for i in xrange(624)]
index = 0

# To get last 32 bits
bitmask_1 = (2 ** 32) - 1

# To get 32. bit
bitmask_2 = 2 ** 31

# To get last 31 bits
bitmask_3 = (2 ** 31) - 1

def __init__(self, seed):
self.initialize_generator(seed)

def initialize_generator(self, seed):
"Initialize the generator from a seed"
global MT
global bitmask_1
MT[0] = seed
for i in xrange(1,624):
MT[i] = ((1812433253 * MT[i-1]) ^ ((MT[i-1] >> 30) + i)) & bitmask_1

def generate_numbers(self):
"Generate an array of 624 untempered numbers"
global MT
for i in xrange(624):
y = (MT[i] & bitmask_2) + (MT[(i + 1 ) % 624] & bitmask_3)
MT[i] = MT[(i + 397) % 624] ^ (y >> 1)
if y % 2 != 0:
MT[i] ^= 2567483615

def sample(self):
"""
Extract a tempered pseudorandom number based on the index-th value,
calling generate_numbers() every 624 numbers
"""
global index
global MT
if index == 0:
self.generate_numbers()
y = MT[index]
y ^= y >> 11
y ^= (y << 7) & 2636928640
y ^= (y << 15) & 4022730752
y ^= y >> 18

index = (index + 1) % 624
# divide by 4294967296, which is the largest 32 bit number
# to normalize the output value to the range [0,1]
return y*1.0/4294967296

class Norm(Distribution):
def __init__(self, mu=0, sigma_sq=1):
self.mu = mu
self.sigma_sq = sigma_sq
self.uniform_distribution_1 = Uniform_distribution(datetime.now().microsecond)
self.uniform_distribution_2 = Uniform_distribution(datetime.now().microsecond)
# some initialization if necessary

def sample(self):
# generate a sample, where the value of the sample being generated
# is distributed according a normal distribution with a particular
# mean and variance
u = self.uniform_distribution_1.sample()
v = self.uniform_distribution_2.sample()
return ((self.sigma_sq**0.5)*((-2*np.log(u))**0.5)*np.cos(2*np.pi*v)) + self.mu

这很完美,并且生成了一个很好的高斯分布

Norm().plot(10000)

Simulated Gaussian Distribution

关于python - 如何实现高斯分布的概率密度函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45991419/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com