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


9

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

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

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

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

그리고 이후 (그림) :

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

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

f(x)=tg(φ)x+(1B−tg(φ)B2)

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

F(x)=tg(φ)x22+x(1B−tg(φ)B2)

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

tg(φ)xi22+xi(1B−tg(φ)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 좌표를 유지 하지만 " " 라고 표시된 왼쪽 삼각형에 다트 가 좌표를 에서 . 예를 들어 및에 값을 지정 하고 ( 과 사이의 값이 주어지면 분포를 생성 하는 실제 매개 변수 ) 필요한 임의의 값의 수로 설정하십시오 . 코드 는 다음과 같습니다 .ϕxB−xBtheta−11nRx<-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ϕ±tan−1⁡2625

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

F(x)=t
F(x)=12tan⁡ϕ⋅x2+(1B−B2tan⁡ϕ)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.