바이어스 코인을 사용하여 확률이 Bernoulli 변수 시뮬레이션


9

누군가가 를 시뮬레이션하는 방법을 알려줄 수 있습니까? 여기서 은 동전 던지기를 사용하여 (필요한 횟수만큼) ?Bernoulli(ab)a,b∈NP(H)=p

나는 거부 샘플링을 사용하려고 생각했지만 그것을 못 박았습니다.


1
이것은 원래 코스 나 교과서에서 질문입니까? 그렇다면 [self-study]태그 를 추가 하고 위키를 읽으십시오 . 질문 끝에 도움을 청할 필요는 없습니다. 여기에 글을 올리는 모든 사람이 도움을 원한다는 것을 알고 있습니다.
— 실버 피쉬

1
@Glen_b의 훌륭한 글이 있습니다. (어딘가를 기억할 수는 없지만) 왜 "확률 p를 갖는 바이어스 코인"과 같은 것이 없는지 p에 대한 질문이 있습니다.
— 실버 피쉬

2
@dsaxton 질문은 "필요한만큼"이라고 말합니다. 그것은 확률 1로 한정되지만 제한되지는 않습니다 (고정 된 토스 수를 초과 할 수 있음). 그러나 그 기초에 반대하는 것은 "머리를 얻을 때까지 공정한 동전을 던지다"는 것이 기하를 생성하는 방법으로 실행 가능하지 않다고 말하는 것과 같습니다 ( 난수12
— Glen_b-복지국 Monica

1
@AbracaDabra 이것은 수업을위한 운동입니까? 그렇지 않은 경우 어떻게 발생합니까?
— Glen_b-복지 주 모니카

1
@Glen_b : 그것은 내 수업의 연습이 아닙니다. 방금이 사고의 사슬에서 나에게 일어났다 ... : 고전적인 확률에 따르면, 당신이 토스의 수를 늘리면 비율이 반으로 수렴됩니다. 따라서 편향된 사람들도 마찬가지입니다. 동전을 특정 숫자로 수렴 시키려면 가 그 숫자 여야합니다. 이제 우리는 숫자를 생산하고 싶다면 와 다른 숫자 (알려 지거나 알려지지 않은)를 가진 동전을 가지고 있다면 어떨까요? #Heads#tailsP(H)P(H)
— AbracaDabra

답변:


8

셀 수없이 많은 솔루션이 있으므로 효율적인 솔루션을 찾으십시오 .

이 아이디어의 기본 개념은 Bernoulli 변수를 구현하는 표준 방법으로 시작합니다. 균일 한 랜덤 변수 를 매개 변수 . 경우 반환 ; 그렇지 않으면 반환하십시오 .Ua/bU<a/b10

coin을 균일 난수 생성기로 사용할 수 있습니다p . 간격 내에서 균일하게 숫자 를 생성하려면 동전을 뒤집습니다. 헤드 일 때 , 구간 의 첫 번째 부분 에서 균일 한 값 를 재귀 적으로 생성 합니다. 꼬리 일 때 구간 의 마지막 부분 에서 를 재귀 적으로 생성 합니다. 어떤 시점에서 목표 간격이 너무 작아서 실제로 숫자를 어떻게 선택하는지는 중요하지 않습니다. 이것이 재귀가 시작되는 방식입니다. 이 절차는 유도에 의해 쉽게 입증되는 바와 같이 균일 한 변이 (원하는 정밀도까지)를 생성하는 것이 분명합니다.U[x,y)XpX1−p

이 아이디어는 효율적이지 않지만 효율적인 방법으로 이어집니다. 각 단계에서 주어진 간격 에서 숫자를 그릴 것이기 때문에 , 먼저 그것을 그려야하는지 여부를 먼저 확인하지 않겠습니까? 목표 값이이 간격을 벗어난 경우 , 임의 값과 목표 값을 비교 한 결과를 이미 알고 있습니다. 따라서이 알고리즘은 빠르게 종료되는 경향이 있습니다. (이것은 질문에서 요청 된 거부 샘플링 절차 로 해석 될 수 있습니다 .)[x,y)

이 알고리즘을 더 최적화 할 수 있습니다. 모든 단계에서 실제로 사용할 수 있는 두 개의 코인이 있습니다. 코인의 레이블을 다시 지정하면 우연히 헤드로 만들 수 있습니다 . 따라서 사전 계산으로 재 라벨을 사용하여 레이블을 다시 지정하여 종료에 필요한 예상 플립 횟수를 줄입니다. 이 계산은 비용이 많이 드는 단계 일 수 있습니다.1−p

예를 들어, Bernoulli 변수를 직접 에뮬레이션하기 위해 코인을 사용하는 것은 비효율적 입니다. 평균적으로 거의 10 번의 뒤집기가 필요합니다. 그러나 코인을 사용한다면 단 두 번의 플립으로 확실하게 뒤집을 수 있으며 예상되는 플립 횟수는 입니다.p=0.9(0.01)p=1−0.0=0.11.2

자세한 내용은 다음과 같습니다.

주어진 반 개방 구간 를 구간으로 분할I=[x,y)

[x,y)=[x,x+(y−x)p)∪[x+(y−x)p,y)=s(I,H)∪s(I,T).

이것은 반 개방 간격으로 작동 하는 두 가지 변환 및 를 정의합니다.s(∗,H)s(∗,T)

용어의 문제로, 만약 실수의 집합 이라면I

t<I

는 의 하한을 의미합니다 : 모든 대한 . 마찬가지로, 의미 상부 행이다 .tIt<xx∈It>ItI

쓰십시오 . (실제로 가 합리적인 것이 아니라 실제 라면 아무런 차이가 없습니다 ; 우리는 만 필요합니다 .)a/b=tt0≤t≤1

원하는 Bernoulli 매개 변수를 사용하여 변량 를 생성하는 알고리즘은 다음과 같습니다 .Z

  1. 집합 과 .n=0In=I0=[0,1)

  2. 반면 {토스 경화가 생성하는 . 집합 증가 .}(t∈In)Xn+1In+1=S(In,Xn+1).n

  3. 만약 다음 집합 . 그렇지 않으면 설정하십시오 .t>In+1Z=1Z=0


이행

예를 R들어, 함수로서 alorithm 의 구현이 있습니다 draw. 인수는 목표 값 와 간격 이며 처음에는 입니다. 구현 하는 보조 기능을 사용합니다 . 반드시 필요한 것은 아니지만 동전 던지기 수를 추적합니다. 랜덤 변수, 던지기 횟수 및 마지막으로 검사 한 간격을 반환합니다.t[x,y)[0,1)ss

s <- function(x, ab, p) {
  d <- diff(ab) * p
  if (x == 1) c(ab[1], ab[1] + d) else c(ab[1] + d, ab[2])
}
draw <- function(target, p) {
  between <- function(z, ab) prod(z - ab) <= 0
  ab <- c(0,1)
  n <- 0
  while(between(target, ab)) {
    n <- n+1; ab <- s(runif(1) < p, ab, p)
  }
  return(c(target > ab[2], n, ab))
}

정확도 사용 및 테스트의 예로 및 . 하자 그리 평균 (및 표준 오류)에 대한 알고리즘, 보고서를 사용하여 값을, 그리고 사용 넘겼의 평균 수를 나타냅니다.t=1/100p=0.910,000

target <- 0.01
p <- 0.9
set.seed(17)
sim <- replicate(1e4, draw(target, p))

(m <- mean(sim[1, ]))                           # The mean
(m - target) / (sd(sim[1, ]) / sqrt(ncol(sim))) # A Z-score to compare to `target`
mean(sim[2, ])                                  # Average number of flips

이 시뮬레이션 에서, 플립의 는 헤드였다. 목표 보다 낮지 만 의 Z- 점수는 하지 않습니다.이 편차는 우연의 원인 일 수 있습니다. 평균 플립 횟수는 10보다 조금 작습니다. 만약 코인을 사용했다면 , 평균은 였지만 여전히 목표와 크게 다르지 않았지만 평균 플립 만이 필요했을 것입니다.0.00950.01−0.51549.8861−p0.00941.177


나는이 솔루션과 솔루션 2의 유사점을 도울 수는 없지만 대답합니다. 편견없는 동전 (편향된 동전 문제에 대한 PS의 흥미로운 해결책)을 가정하고 기본 -2의 모든 계산 / 비교를 수행하는 반면, 기본 10의 모든 계산 / 비교를 수행합니다. 어떻게 생각하십니까?
— Cam.Davidson.Pilon

1
@cam 나는 당신이 내 예제에 속을지도 모른다고 생각합니다. 비록 그들이 기초 10에서 좋은 숫자를 사용하지만, 그 구조는 어떤 특정한 기초와는 아무 관련이 없습니다.
— whuber

2
(+1) 매우 깔끔한 해상도. 최적화는 및 / 또는 과 같은 거듭 제곱 으로 상한과 하한 에 . 시뮬레이션 된 Bernoullis 수의 관점에서 최적의 이분법을 찾는 것이 좋습니다. a/bpn(1−p)m(n+mm)pn(1−p)m
— Xi'an

5

여기 해결책이 있습니다 (지저분한 해결책이지만 내 첫 번째 찌르기입니다). 실제로 무시할 수 있으며 WLOG는 합니다. 왜? 2 개의 바이어스 코인 플립으로부터 바이어스되지 않은 코인 플립을 생성 하는 영리한 알고리즘 이 있습니다 . 따라서 라고 가정 할 수 있습니다 .P(H)=pP(H)=1/2P(H)=1/2

을 생성하기 위해 두 가지 솔루션을 생각할 수 있습니다 (첫 번째는 내 것이 아니라 두 번째는 일반화입니다).Bernoulli(ab)

해결책 1

편견이없는 동전을 번 뒤집 습니다. 경우 헤드가 존재하지 않는, 다시 시작. 헤드 가 경우 첫 번째 코인이 헤드인지 아닌지를 반환합니다 ( ).baaP(first coin is heads | a heads in b coins)=ab

해결책 2

이것은 값으로 확장 될 수 있습니다 . 쓰기 바이너리 형식이다. 예를 들어Bernoulli(p)p0.1=0.0001100110011001100110011...base 2

우리는 동전 뒤집기를 사용하여 새로운 이진수를 만들 것입니다. 시작 하고 머리 (1) 또는 꼬리 (0)가 나타나는지 여부에 따라 숫자를 추가하십시오. 각각의 플립에서, 새로운 이진수와 의 이진 표현을 같은 숫자까지 비교하십시오 . 결국 두 개가 분기되고 가 이진수보다 크면 반환됩니다 .0.p bin(p)

파이썬에서 :

def simulate(p):
    binary_p = float_to_binary(p)
    binary_string = '0.'
    index = 3
    while True:
        binary_string += '0' if random.random() < 0.5 else '1'
        if binary_string != binary_p[:index]:
            return binary_string < binary_p[:index]
        index += 1

몇 가지 증거 :

np.mean([simulate(0.4) for i in range(10000)])

약 0.4입니다 (그러나 빠르지는 않습니다)


좋은 대답이지만 방법 1을 사용하여 비합리적 p를 수행하는 방법을 설명 할 수 있습니까?
— AbracaDabra

2
@AbracaDabra 왜 의 합리성이 중요할까요? p
— Glen_b-복지 주 모니카

@AbracaDabra : 의 값이 무엇이든, 및 을 얻을 확률은 동일합니다. 즉 이므로 하나를 다른 사람과 비교할 확률은 입니다. p(0,1)(1,0)p(1−p)1/2
— 시안

4

나는 간단한 해결책을 보았지만 의심 할 여지없이 여러 가지 방법이 있습니다. 이 방법은 두 단계로 나눌 수 있습니다.

  1. 불공평 한 동전 던지기 절차 (특정 동전과 동전이 확률 헤드를 생성하는 방법의 조합)가 주어지면 동일한 확률로 두 사건에서 생성됩니다 . 이 두 가지 가능한 이벤트 및 호출 할 수 있습니다 . [이에 대한 간단한 접근법이 있습니다. 와 를 짝으로하여 두 개의 똑같이 비슷한 결과를 생성해야합니다. 다른 모든 결과는 새로운 쌍을 생성합니다. 다시 시도하십시오.]pH∗T∗H∗=(H,T)T∗=(T,H)

  2. 이제 시뮬레이션 된 공정한 동전을 사용하여 두 가지 흡수 상태로 무작위 보행을 생성합니다. 원점에서 흡수 상태의 거리를 선택하여 (위 및 아래) 하나의 흡수 상태를 원하는 정수 비율로 설정하여 흡수 확률을 설정할 수 있습니다. 당신의 위 흡수 장벽을 배치하면 특히, 과의 낮은 일 (원점에서 프로세스를 시작), 흡수 될 때까지 랜덤 워크 (random walk)를 실행, 위 장벽에서 흡수 확률은 입니다.a−(b−a)aa+(b−a)=ab

    (여기서 계산해야 할 계산이 있지만 재귀 관계로 작업하여 확률을 상당히 쉽게 얻을 수 있습니다 ... 또는 무한 시리즈를 합산하여 다른 방법을 사용할 수 있습니다.)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.