수학적 이론으로부터 "경사 균일 분포"로부터 난수 생성


9

어떤 목적을 위해, "경사 균일 한"분포로부터 난수 (데이터)를 생성해야합니다. 이 분포의 "기울기"는 적절한 간격으로 다를 수 있으며,이 분포에 따라 경사도에 따라 분포가 균일에서 삼각형으로 변경되어야합니다. 여기 내 파생물이 있습니다.

여기에 이미지 설명을 입력하십시오

간단하게 만들고 에서 까지의 데이터 형식을 생성합시다 (파란색, 빨간색은 균일 분포). 파란색 선의 확률 밀도 함수를 구하려면 해당 선의 방정식 만 있으면됩니다. 그러므로:0B

f(x)=tg(φ)x+Y(0)

그리고 이후 (그림) :

tg(φ)=1/BY(0)B/2Y(0)=1Btg(φ)B2

우리는 그것을 가지고 있습니다 :

f(x)=tg(φ)x+(1Btg(φ)B2)

이후 PDF이며, CDF 같음 :f(x)

F(x)=tg(φ)x22+x(1Btg(φ)B2)

이제 데이터 생성기를 만들어 봅시다. 아이디어는 고치면 여기에 설명 된 균일 분포 에서 에서 숫자를 얻을 경우 임의의 숫자 를 계산할 수 있다는 입니다. 나는 고정 된 내 분포 (100 개) 난수가 필요한 경우 따라서, , 그 다음 어떤을 위해 균일 한 분포에서 가 "경사 유통"에서, 그리고 로 계산 될 수있다 :φ,Bx(0,1)φ,Bti(0,1)xix

tg(φ)xi22+xi(1Btg(φ)B2)ti=0

이 이론을 통해 파이썬으로 코드를 만들었습니다.

import numpy as np
import math
import random
def tan_choice():
    x = random.uniform(-math.pi/3, math.pi/3)
    tan = math.tan(x)
    return tan

def rand_shape_unif(N, B, tg_fi):
    res = []
    n = 0
    while N > n:
        c = random.uniform(0,1)
        a = tg_fi/2
        b = 1/B - (tg_fi*B)/2
        quadratic = np.poly1d([a,b,-c])
        rots = quadratic.roots
        rot = rots[(rots.imag == 0) & (rots.real >= 0) & (rots.real <= B)].real
        rot = float(rot)
        res.append(rot)
        n += 1
    return res

def rand_numb(N_, B_):
    tan_ = tan_choice()
    res = rand_shape_unif(N_, B_, tan_)
    return res

그러나 생성 된 숫자는 rand_numb0 또는 B에 매우 가깝습니다 (25로 설정 한 경우). 100 개의 숫자를 생성 할 때 분산이 없습니다. 모두 25에 가깝거나 모두 0에 가깝습니다. 한번에 :

num = rand_numb(100, 25)
numb
Out[140]: 
[0.1063241766836174,
 0.011086243095907753,
 0.05690217839063588,
 0.08551031241199764,
 0.03411227661295121,
 0.10927087752739746,
 0.1173334720516189,
 0.14160616846114774,
 0.020124543145515768,
 0.10794924067959207]

따라서 내 코드에는 매우 잘못된 것이 있습니다. 누구든지 내 파생 또는 코드를 도와 줄 수 있습니까? 나는 지금 이것에 대해 미쳤다. 나는 어떤 실수도 볼 수 없다. R 코드가 비슷한 결과를 줄 것이라고 생각합니다.


2
난수 만 생성하면 분포를 전혀 계산할 필요가 없습니다. 그림에 다트를 던지고 x 좌표를 유지 하지만 " " 라고 표시된 왼쪽 삼각형에 다트 가 좌표를 에서 . 예를 들어 및에 값을 지정 하고 ( 과 사이의 값이 주어지면 분포를 생성 하는 실제 매개 변수 ) 필요한 임의의 값의 수로 설정하십시오 . 코드 는 다음과 같습니다 .ϕxBxBtheta11nRx<-runif(n,-1,1);x<-(ifelse(runif(n,-1,1)>theta*x,-x,x)+1)*(B/2)
whuber

답변:


9

당신의 결정은 괜찮습니다. 에 양의 밀도를 얻으려면 를 제한 해야합니다. 코드 에서 사이에 를 사용해야합니다. , 코드가 실패하는 곳입니다.(0,B)

B2tanϕ<2.
B=25ϕ±tan12625

이차 솔버 사용을 피할 수 있으며 0과 사이의 근을 선택할 수 있습니다 . 이차 다항식의 해결 될 와 구성에 의해 및 ; 또한 는 에서 증가합니다 .Bx

F(x)=t
F(x)=12tanϕx2+(1BB2tanϕ)x.
F(0)=0F(B)=1F(0,B)

이것으로부터 이면 관심있는 포물선의 부분이 포물선의 오른쪽 부분이고 유지하는 뿌리가 두 뿌리 중 가장 높은 것을 알 수 있습니다. 되고 반대로 이면 포물선이 거꾸로되어 왼쪽에 관심이 있습니다. 부품. 유지할 루트가 가장 낮습니다. 의 부호를 고려 하면 첫 번째 경우 와 동일한 루트 (예 : 와 같은 루트) 인 것으로 보입니다 .tanϕ>0

x=1tanϕ(B2tanϕ1B+(B2tanϕ1B)2+2tanϕt.)
tanϕ<0tanϕ+Δ

다음은 R 코드입니다.

phi <- pi/8; B <- 2
f <- function(t) (-(1/B - 0.5*B*tan(phi)) + 
       sqrt( (1/B - 0.5*B*tan(phi))**2 + 2 * tan(phi) * t))/tan(phi)
hist(f(runif(1e6)))

히스토그램 1

그리고 :ϕ<0

phi <- -pi/8
hist(f(runif(1e6)))

여기에 이미지 설명을 입력하십시오


1
실수를했습니다. 각도를 경계에서 벗어 났기 때문에 알았습니다. 그러나 의 수치 솔버를 사용하여 왜 avouid를 사용 해야하는지에 대한 당신의 설명 은 여전히 ​​안개 낀다 . 좀 더 설명해 주시겠습니까? 나는 그것을 얻는 것을 좋아합니다. F(x)
Robert

@Robert 의 값 이 정확 하면 코드가 잘 작동한다고 생각합니다 . 그러나 잠재적 인 문제점을 포착하지 못하게합니다 (0과 사이에 솔루션이없는 경우 또는 두 솔루션이 모두있는 경우 또는 실제 솔루션이없는 경우). 기성품 솔버를 사용하지 않는 추가 작업은 그만한 가치가 있습니다. ϕB
Elvis
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.