Alias Table

AliasTable

典型的多项式分布的复杂度为 O ( k ) O(k) O(k) k k k为多项式分布的大小,那么能否将 O ( k ) O(k) O(k)的复杂度降为 O ( 1 ) O(1) O(1)呢?Alias方法就是这样的一种方法。

原理

对于概率分布 p i p_i pi其中 i ∈ { 1 , ⋯   , l } i\in\{1,\cdots,l\} i{1,,l},Alias方法要达到什么目的呢?Alias的目的是通过对原有的 l l l个概率值 p i p_i pi进行分解和合并,使得新形成的 l l l个概率值均等于 1 / l 1/l 1/l,且每个概率值最多来自原来的两个不同的概率值。用形象的话来描述的话,最后我们会得到 l l l个桶,每个桶内最多有两个颜色。得到转换后的结果,那么采样的话只需要两次就可以达到原来的效果,第一次采样得到一个桶的编号,第二次采样得到该桶内的颜色。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EGakd7xt-1602586237651)(http://ot6t5dysc.bkt.clouddn.com/20170716223747.png)]
举个例子,如图所示,上述概率分布的均值为 1 / 4 1/4 1/4,那么Alias方法通过对概率值得分解和组合,将1图转换为4图,如果采样得到第一个桶的话,然后产生一个 [ 0 , 1 / 4 ] [0,1/4] [0,1/4]的随机数,当落到红色范围内,采样得到的值为 1 1 1,否则为 4 4 4

伪代码

产生Alias表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-emCSFbS5-1602586237654)(http://ot6t5dysc.bkt.clouddn.com/GenerateAlias.png)]

采样

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0FosDVVe-1602586237656)(http://ot6t5dysc.bkt.clouddn.com/SampleAlias.png)]

代码

# -*- encoding:utf8 -*-

from random import randrange,random
import numpy as np
from datetime import datetime

class AliasTable():
    def __init__(self,probs):
        self.probs=probs
        probs=np.array(probs)
        self.bins=len(probs) 
        probs=probs*self.bins/np.sum(probs)    
        self.p_table=np.ones(self.bins,dtype=np.float64)
        self.b_table=np.zeros(self.bins,dtype=np.int64)
        p=1/self.bins
        L,H=[],[]
        for i in range(self.bins):
            if probs[i]<1:
                L.append(i)
            else:
                H.append(i)
        
        while len(L)>0 and len(H)>0:
            l=L.pop()
            h=H.pop()
            self.p_table[l]=probs[l]
            self.b_table[l]=h
            probs[h]=probs[h]-(1-probs[l])
            if probs[h]<1:
                L.append(h)
            else:
                H.append(h)

        while len(L)>0:
            l=L.pop()
            self.p_table[l]=1

        while len(H)>0:
            h=H.pop()
            self.p_table[H]=1
            
    def sample(self):  
        b=randrange(self.bins)
        if random()<self.p_table[b]:
            return b
        else:
            return self.b_table[b]

if __name__=='__main__':
    test=[0,1,2]
    at=AliasTable(test)
    t=at.sample() 

参考文献

  • Li, A. Q., Ahmed, A., Ravi, S., & Smola, A. J. (2014). Reducing the sampling complexity of topic models. 891-900.
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值