Ubuntu 16.10
GTX 750ti(需要一张NVIDIA的显卡,越新越好,新卡的Compute Capability版本高)
NVIDA CUDA 8.0
NVIDIA 驱动 375.26
gcc version 4.9
因为Ubuntu是机子新装的,所以我安装了Linux自己用的一些基本环境和python科学计算的库,请各取所需。
sudo apt-get install vim
|
|
sudo apt-get install git
sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
sudo apt-get install autojump
安装open-jdk sudo apt-get install openjdk-8-jdk
安装pycharm
首先贴一段Tensorflow官网上GPU支持对NVIDIA的环境需求:If you are installing TensorFlow with GPU support using one of the mechanisms described in this guide, then the following NVIDIA software must be installed on your system:
CUDA® Toolkit 8.0. For details, see NVIDIA’s documentation. Ensure that you append the relevant Cuda pathnames to the LD_LIBRARY_PATH
environment variable as described in the NVIDIA documentation.
The NVIDIA drivers associated with CUDA Toolkit 8.0.
cuDNN v5.1. For details, see NVIDIA’s documentation. Ensure that you create the CUDA_HOME
environment variable as described in the NVIDIA documentation.
GPU card with CUDA Compute Capability 3.0 or higher. See NVIDIA documentation for a list of supported GPU cards.
The libcupti-dev library, which is the NVIDIA CUDA Profile Tools Interface. This library provides advanced profiling support. To install this library, issue the following command:
除了最后的libcupti-dev库可以直接apt-get,我们需要装的大头就是CUDA® Toolkit和cuDNN两个东西,各种坑从这里开始了囧。
按照 NVIDIA’s documentation 给出的步骤:
在安装后的验证过程中需要注意的几个点如下:
|
|
这里最坑爹的一点是LIBRARY_PATH这个环境变量配置,官方的文档上一点没提,如果不写的话,在编译cuda的samples时,会在3_Imaging这个samples下报这个错误
|
|
因为Ubuntu 16.10自带的gcc编译器版本是6.2,对于CUDA来说太新了,所以会报错
|
|
可以看到CUDA 8.0 能够支持的gcc最新版本不能超过5。网上给出的比较好的解决办法是利用Ubutnu的update-alternatives 命令来切换版本,具体命令如下:
|
|
敲完sudo update-alternatives --config gcc
之后,你就可以看到不同版本的gcc优先级了。
根据Recommended Actions](http://docs.nvidia.com/cuda/cuda-installation-guide-linux/index.html#recommended-post)步骤编译Cuda的那些samples,如果出现Finished building CUDA samples
,说明所有samples的编译通过了。可以敲NVIDIA_CUDA-8.0_Samples ./bin/x86_64/linux/release/nbody
,可以看到以下效果
下载 cuDNN之前需要注册一下,成为NVIDIA的开发者,然后把下载的包解压拷贝到CUDA的链接库和头文件目录就行了。
|
|
安装Tensorflow有多种方式,这里我直接用的pip安装,python版本是2.7。
|
|
都搞定之后,启动ipython,输入
|
|
能看到输出的结果,说明GPU加速安装成功了。
|
|
其实三硬币的例子不写,前面的介绍也够了,写这个纯粹是吃撑了。这次我们采取更加普遍的假设,将原先假设的3枚硬币拓展开来。现在假设有\(K+1\)个骰子,第一个骰子有\(K\)个面,其余的骰子有\(T\)个面。进行如下实验:先掷第一个骰子,根据投出的结果\(Z_k\),选择第\(Z_k\)个骰子再投,观测到投出的\(N\)个结果,每个结果\(w_n\)可能是 \[
1,3,7,8,3,2,6,9,...
\]
可以看到现在第1个骰子投出的标签服从多项分布: \[Z_k \sim Multinomial(\pi)\] 然后剩余骰子投出的面也服从多项分布 \[W_{Z_{kt}} \sim Multinomial(\theta_{Z_k})\] 我们假设,随机变量\(\pi\)和\(\theta\)的先验分布为狄利克雷分布,超参分别为\(\alpha\)和\(\beta\)。
让我们写出模型的联合概率: \[ \begin{split}P(W,Z,\Pi,\Theta)&=p(\pi|\alpha)\prod^K_{k=1}p(\theta_k|\beta)\prod^N_{n=1}\prod^K_{k=1}\prod^T_{t=1}p(z_{nkt}|\pi_{nkt})p(w_{n}|\theta_{z_{nkt}})\\ \end{split} \] 相应地,我们利用平均场理论切断模型直接耦合的地方(见图1),设定一个近似真实后验的分布族\(q\)。 \[ \begin{split}P(W,Z,\Pi,\Theta)&=q(\pi|\nu)\prod^K_{k=1}q(\theta_k|\lambda_k)\prod^N_{n=1}\prod^K_{k=1}\prod^T_{t=1}q(z_{nkt}|\phi_{nkt})\\ \end{split} \]
然后我们最小化\(q\) 与真实后验之间的KL 散度,也就是最大化证据下界\(\mathcal{L}\)(ELBO)。 证据下界写出来是这样的: \[ \begin{split} \mathcal{L} &= E_q[\log p(\pi|\alpha)]-E_q[\log q(\pi|\nu)] \\ &+\sum_k E_q[\log p(\theta_k|\beta)]-\sum_k E_q[\log q(\theta_k|\lambda_k)] \\ &+\sum_n\sum_t\sum_k E_q[\log p(z_{nkt}|\pi_{nkt})]-\sum_n\sum_t\sum_k E_q[\log q(z_{nkt}|\phi_{nkt})] \\ &+ \sum_n\sum_t\sum_k E_q[\log p(w_{nt}|\theta_{z_{nkt}})] \end{split} \]
因为Dirichlet分布为 \[ Dir(\vec{p}|\vec{\alpha})=\frac{\Gamma(\sum^K_{k=1}\alpha_k)}{\prod^K_{k=1}\Gamma{(\alpha_k)}}\prod^K_{k=1}p_k^{\alpha_k-1} \]
由LDA原论文的Appendix A.1可知,Dirichlet的某个分布(single probability component )的log期望为 \[ \mathbb{E}[\log p_k|\alpha_k]=\psi(\alpha_k)-\psi(\sum_k \alpha_k) \] 其中\(\psi(\alpha)=\frac{d}{d\alpha}\log \Gamma(\alpha)\)。 根据这个公式,计算\(\mathcal{L}\)关于\(q\)的期望,我们可以得到 \[ \begin{split} \mathcal{L} &=\log\Gamma(\sum_k \alpha_k)-\log\Gamma(\alpha_k)+\sum_{k}(\alpha_k-1)[\Psi(\nu_{k})-\Psi(\sum_v \nu_{k})]\\ &-\log\Gamma(\sum_k \nu_k)+\log\Gamma(\nu_k)-\sum_{k}(\nu_k-1)[\Psi(\nu_{k})-\Psi(\sum_v \nu_{k})]\\ &+\sum_k \log\Gamma(\sum_t \beta_{k,t})-\sum_{k,t}\log\Gamma(\beta_{k,t})+\sum_{k,t}(\beta_t-1)[\Psi(\lambda_{k,t})-\Psi(\sum_k \lambda_{k,t})]\\ &-\sum_k \log\Gamma(\sum_t \lambda_{k,t})+\sum_{k,t}\log\Gamma(\lambda_{k,t})-\sum_{k,t}(\lambda_{k,t}-1)[\Psi(\lambda_{k,t})-\Psi(\sum_k \lambda_{k,t})]\\ &+\sum_n\sum_k\sum_t \phi_{nkt}[\Psi(\alpha_{k})-\Psi(\sum_k \alpha_{k})]-\sum_n\sum_k\sum_t \phi_{nkt}\log \phi_{nkt} \\ &+\sum_n\sum_k\sum_t \phi_{nkt}\delta_t(w_{n})[\Psi(\lambda_{k,t})-\Psi(\sum_t \lambda_{k,t})] \\ \end{split} \] 其中\(\delta_t(w_{n})\)当且仅当\(w_n=t\)时为1,其余的时候均为0。因为多项分布\(p(x)=\prod^K_{k=1}p_k^{x_k}\)的期望\(E[x_k]=p_k\),所以这里有\(E[z_{nkt}]=\phi_{nkt}\),\(\phi_{nkt}\)代表隐藏变量的期望值。
将\(\mathcal{L}\)分别对各自的参数求导,解得 \[ \begin{split} &\nu_k=\alpha_k \\ &\phi_{dnk} \propto \exp\{\Psi(\lambda_{k,t})-\Psi(\sum_t \lambda_{k,t})\} \\ &\lambda_{k,t}=\beta_t+\sum_n\phi_ {nkt}\delta_t(w_n) \end{split} \] 相互迭代到收敛就好啦。
]]>首先一句话介绍Lean Cloud:
LeanCloud(aka. AVOS Cloud)提供一站式后端云服务,从数据存储、实时聊天、消息推送到移动统计,涵盖应用开发的多方面后端需求。
我们只用到它的数据存储部分,具体步骤如下:
首先在theme/你的主题/layout/_widget
目录下新建popular_posts.ejs
文件,其内容为
|
|
修改theme/你的主题/layout/_partial/head.ejs
文件,在head标签的最后插入:
|
|
注意Lean Cloud引用的js文件位置可能会变化,如果代码里位置打不开的话,记得去官方的JavaScript SDK文档找一下最新的位置。
修改theme/你的主题/layout/_partial/after-footer.ejs
文件,在最后插入:
|
|
这段代码的核心逻辑就是对Counter对象的增加和查询,每一篇文章都会有一个time字段来记录访问次数。这里查询的时候我用的是文章通过Hexo生成的URL作为主键的,所以post文件夹目录下的文件名一旦取好就不要轻易修改了,要不然访问次数会重新计算的:)。
最后,修改theme/你的主题/config.yml
文件,在widgets:
选项找个位置下添加- popular_posts
即可。
插件的效果可以见我博客的右侧”浏览数目“插件,样式和文章显示数目可以直接在代码里改,浏览量数据都存在“Counter”表中,见图(顺便测试下七牛云):
PS:这个浏览量数据是可以自己改的,我是原来是照搬的wordpress的数据,它包括了Robot和人访问量的总和,感觉不太靠谱,不利于新文章上榜,现在全都除以10了:)。
]]>扯一点闲话,这半年发生了不少事,导致博客断更了半年多。一言难尽,就上一句心灵鸡汤来概括吧,顺便弘扬一下正能量:
所有的事情最后都会有好结局,如果你觉得结局不好,那是因为还没有到最后。
进入正题,这两天闲下来之后,也是起了心思,想把博客从wordpress迁移到静态博客上,原因如下:
静态博客先使用了Github推荐的Jekyll,发现需要自己搞的东西太多,于是转用了基于node.js的Hexo。Hexo有以下优点:
hexo n
,hexo g
,hexo s
,hexo d
就能 搞定一切。在搭建过程,主要参考了以下文章:
以上的文章已经足够基本了解hexo博客的整个搭建过程了,只需要照做即可。我的博客主题是基于landscape-plus改的,另外参考了howiefh的 landscape-f主题,添加了多说最近评论小部件以及我自己写的浏览计数小部件。图片都托管在七牛云存储上。
在博客从wordpress迁移到hexo的过程中,主要碰到的问题及解决办法如下:
概率图模型(Graphical Model)是概率论和图论之间的桥梁,概率图模型的基本想法来自模块的概念,即一个复杂系统是由简单的部分所联合而成的。概率论部分告诉我们哪些部分是耦合在一起的,然后提供推断模型的方法,而图论部分给我们一个非常直观的认识,把拥有相互关系的变量看做数据结构,从而导出一般化的方法来解决这个问题。很多经典的多元概率系统,比如混合模型,因子分析,隐含马尔科夫模型,Kalman filter 和Ising model等,从概率图模型的角度来看,都可以看做普遍隐含形成过程的一种实例表现。这意味着,一旦在某个系统上有什么特别的方法发现,就很容易推广到一系列的模型中去。除此之外,概率图模型还非常自然地提供了设计新系统的方法。
在概率图模型中,点代表随机变量,点与点之间边的存在与否代表了点与点之间是存在条件依赖。点与边的组合描绘了联合概率分布的特征结构。假设有\(N\)个二元随机变量,在没有任何信息帮助的情况下,联合分布\(P(X_1,\ldots,X_N)\),需要\(O(2^N)\)个参数。而通过概率图描绘点与点之间的条件关系之后,表示联合分布,所需要的参数会减少很多,这对后面的模型的推断和学习是有帮助的。
概率图模型主要分为两种,无向图(也叫Markov random fields)和有向图(也叫Bayesian networks),前者多用于物理和图像领域,后者多用于AI和机器学习,具体的基本就不多介绍了。下面给出一个简单贝叶斯网络的例子。
这里Cloudy指是否多云,Sprinkler指洒水器是否打开,Rain指是否有雨, WetGrass指草地是否湿了。
推断的主要目的是在知道观察变量的值的情况下估计隐藏变量的值。如果我们观察到生成模型的“叶子”,然后可以尝试推断隐藏的原因(diagnosis),反之如果观察到生成模型的“根”,就可以尝试预测它的节点(predicition)。
使用的方法就是贝叶斯公式
\[P(X|y)=\frac{P(y|X)P(X)}{P(y)}\]
其中\(X\)是隐藏变量,\(y\)是观察到的值。公式可以这么解释:
\[\text{posterior}=\frac{\text{conditional likelihood} \times \text{prior}}{\text{likelihood}}\]
以前面的图为例,当我们观察到草地是湿的(\(W=1\))时,有可能有2个原因:下雨(\(R=1\))或者开着洒水器(\(S=1\))。我们根据贝叶斯公式求得它们各自的概率
\[P(S=1|W=1)=\frac{P(S=1,W=1)}{P(W=1)}=\frac{\sum_{c,r}P(C=c,S=1,W=1,R=r)}{P(W=1)}=0.430\]
\[P(R=1|W=1)=\frac{P(R=1,W=1)}{P(W=1)}=\frac{\sum_{c,s}P(C=c,S=1,W=1,R=r)}{P(W=1)}=0.708\]
分母作为归一化常数,同时也是似然
\[P(W=1)=\sum_{c,s,r}P(C=c,S=r,R=r,W=1)=0.6471\]
可以看到草地湿因为下雨的概率要比因为洒水器的概率高。一般来说在实际情况中,利用后验概率算积分的时候不会像例子这么容易。比如分母\(Z\),有可能是指数级别的加和(可以参见pluskid大神的文章),而且,在连续型隐藏变量里,很有可能是求一个无解析解的积分。
因为推断的问题一般都比较复杂,我们自然希望能用一些方法来加速推断的过程。
根据概率图的结构,我们可以将条件独立的节点的生成概率区分开来写,比如:
\[ \begin{split} &P(W=w) =\sum_c\sum_s\sum_r P(C=c,S=s,R=r,W=w) \\ &= \sum_c \sum_s \sum_r P(C=c)\times P(S=s|C=c)\times P(R=r|C=c)\times P(W=w|S=s,R=r) \\ \end{split} \]
参数消去算法的主要目的就是尽量可能的合并子项来减少计算量,我们将上面的式子化为:
\[ P(W=w)=\sum_c P(C=c)\times \sum_s P(S=s|C=c)\times \sum_r P(R=r|C=c)\times P(W=w|S=s,R=r) \]
可以看到第三项与前两个求和项无关。这样我们可以得到合并之后的图:
如果概率图比较复杂,存在重复统计的情况,我们可以使用动态规划算法来避免重复的计算。如果概率图是无环的(比如一棵树),可以用局部信息传播算法(Belief Propagation,HMM的Sum-Product算法的泛化版本)来做推断。如果概率图有环就比较麻烦,因为局部信息传播可能会被重复计算,从而导致算法不收敛。这个时候可以用Junction Tree方法把概率图转化成一棵树(可能会很复杂,见pluskid 的例子)。
推断算法的时间复杂度是指数级别的(取决于概率图中的最大簇的大小),优化它是个NP-hard 问题,所以就导致了推断的近似方法产生。除了图复杂以外还有另外一个原因,即使图的复杂度很低,如果一些节点是连续随机变量,在很多情况下它们对应的积分是没有解析解的。
流行的近似推断方法主要有三种:
Sampling(Monte Carlo) methods。采样做法就是通过抽取大量的样本来逼近真实的分布。最简单的是importance sampling,根据出现的结果的比例采样。在高维空间中更有效的方法叫Markov Chain Monte Carlo,是利用马科夫链的性质来生成某个分布的样本,包括Metropolis-Hastings算法和Gibbs Samppling算法等。
Variational Infernece。变分推断采取的是另一种做法,通过限制近似分布的类型,得到一种局部最优,但具有确定解的近似后验分布。最简单的方法叫做mean-field approximation,就是把概率图里的点全部解耦,看做相互独立的,然后对每个点引进一个变分参数,通过循环地迭代参数来最小化近似分布和真实分布的KL距离。
Loopy Belief Propagation。之前我们讲到Belief Propagation 算法,是应用在无环的图上的,然后LBP就是不管图有没有环,都直接使用这个算法去求解。
Learning可以分很多情况,比如估计参数,或者估计模型的结构,或者两者都有。根据变量是否被观察到和结构是否已知可以对learning方法分类(见下图):
还有一个区别在于,我们的目标在于寻找一个最有可能的模型(点估计),还是在所有可能的模型上做贝叶斯估计。在结构已知的时候,贝叶斯参数估计和推断是等价的,这时候隐藏的节点就代表了这些参数。如果结构未知,还要有对概率图结构的学习过程。
这种最简单,因为结构已知,变量全部都观察到了,所以直接求极大似然值(MLE)就好了。令数据为\(D=\{D_1,\ldots,D_M\}\),那么似然为
\[ L=\frac{1}{M}\log \prod^M_{m=1}P(D_m|G)=\frac{1}{M}\sum^n_{i=1}\sum^M_{m=1}\log P(X_i|Pa(X_i),D_m) \]
这里\(Pa(X_i)\)是\(X_i\)的父亲节点。我们依据概率图的结构分解整个似然式子,然后独立地最大化每个参数。以之前的图为例,我们有
\[ P_{ML}(W=w|S=s,R=r)=\frac{(W=w,S=s,R=r)}{(S=s,R=r)} \]
这里\((S=s,R=r)\)和\((W=w,S=s,R=r)\)分别为下雨而且洒水器开着的次数和满足前两个条件的同时,草地湿了的次数。可以看到极大似然是根据观察到的数据得出最有可能的结果。如果我们有一些训练数据的话,也可以加上先验条件,做最大后验估计(MAP).
如果结构已知,但是有些节点是隐藏的话,我们可以通过EM算法来寻找一个局部最优的MLE。EM的算法的思想就是求那些隐藏节点的期望值,然后把期望值看做观察到的值。以\(W\)节点为例,我们用期望代替观察到的次数,得到
\[P(W=w|S=s,R=r)=\frac{E(W=w,S=s,R=r)}{E(S=s,R=r)}\]
这里\(E(e)\)就是在当前参数下,事件\(e\)发生次数的期望值。这个期望可以由单次发生事件\(e\)的期望多次加和得到。
\[E (e)=E \sum_m I(e|D_m)=\sum_m P(e|D_m)\]
这里\(I(e|D_m)\)是个指示函数,当事件\(e\)在第\(m\)个数据时发生为1,其余都为0。得到期望值后,我们可以重新最大化参数,然后重新计算期望,反复迭代达到一个局部的最优解。
这种情况虽然我们可以观察到概率图中每个节点的数据,但是节点与节点之间的边关系未知。完全图能够给出最大的似然值,那是因为这种情况最复杂,含有最多的参数,很明显过拟合了。 为了解决过拟合的问题,我们可以加上对模型选择的先验条件,使用贝叶斯公式最大化后验
\[P(G|D)=\frac{P(D|G)P(G)}{P(D)}\]
求log我们得到
\[L=\log P(G|D)=\log P(D|G) + \log P(G)+ c\]
这里\(c=-\log P(D)\)是个与模型\(G\)独立的常数。如果先验偏向于简单的模型,那么\(P(G)\)就能对复杂模型起到惩罚作用。事实上就算先验不这么做,使用贝叶斯原理计算的边缘似然(marginal likelihood)
\[P(D|G)=\int P(D|G,\theta)P(\theta|G)d \theta\]
(\(\theta\)为模型的参数)能够自动地倾向解释数据的最简单模型,如果模型参数太多的话,它只能在一个很宽的数据范围内预测,而没办法给小范围数据一个很大的发生概率(也就是说复杂模型更可能“对”,但是不够“准”),而简单模型刚好反之。这个现象被叫做奥卡姆剃刀(Ockham’razor)。
尽管我们可以通过上面那个\(L\)来衡量模型的好坏(被称作Bayesian Score),我们依然还是需要一个方法来寻找得分最高的概率图。穷举的复杂度是超指数级别的,所以我们一般用一些局部的搜索算法(比如多重启的爬山法)或者划分区域来搜索图空间。另外地,由于我们求的是模型生成数据的后验概率\(P(G|D)\),我们可以直接从这个后验概率分布中抽样一些图出来,这叫MCMC search。
最后也是最难的情况,就是图结构未知,而且存在隐藏变量。这导致了边缘似然非常难求,需要对隐藏变量\(Z\)积分才能得到。
\[P(D|G)=\int_Z P(D,Z|G,\theta)P(\theta|G)d \theta\]
一种办法是做拉普拉斯近似(Laplace Approximation),计算得到
\[\log P(D|G) \approx \log P(D|G,\hat{\theta_G})-\frac{d}{2}\log M\]
这里\(M\)是样本个数,\(\hat{\theta_G}\)是参数的最大似然估计(由EM算法得到),\(d\)是模型的维度(在全观察到的情况下,模型维度等于自由参数的个数,在存在隐藏变量的情况下,模型维度会少于参数个数)。这个式子被叫做Bayesian Information Criterion,和Minimum Description Length (MDL) 是等价的。
式子的第一项就是似然,而第二项减去一个代表模型复杂度的量,所以BIC score是对复杂模型有惩罚的。尽管BIC是可以分解的(decomposable),局部的搜索算法还是非常昂贵,因为我们每一步都要跑一次EM 算法来得到\(\theta\)。一种可选的办法是在EM的M 步直接做一个局部搜索,得到一个局部最优的BIC score,这个方法被称作Structural EM。
当然,结构学习不仅仅包括寻找已经存在节点的连通性,还包括在必要情况下增加隐藏节点等等更为复杂的东西。
参考文献:
举一个一元高斯模型的例子。假设我们有数据\(\mathbf{X}=\{x_1,\ldots,x_M\}\),要推断平均值\(\mu\)和精度\(\tau(1/\sigma)\)的后验概率分布。 写出似然 \[\begin{equation} p(\mathbf{X}|\mu,\tau)=(\frac{\tau}{2\pi})^{N/2}\exp\{-\frac{\tau}{2}\sum^N_{n=1}(x_n-\mu)^2\} \end{equation}\] 其中\(\mu,\tau\)各自服从先验分布 \[\begin{equation}p(\mu|\tau)=N(\mu|\mu,(\lambda_0\tau)^{-1})\end{equation}\] \[\begin{equation}p(\tau)=Gam(\tau|a_0,b_0)\end{equation}\] 其中Gam为Gamma分布(见备注1)。
好,我们现在假设\(q\)之间的分布都独立。 \[\begin{equation}q(\mu,\tau)=q_u(\mu)q_r(\tau)\end{equation}\]
对于\(q_u(\mu)\)我们有 \[\begin{equation} \begin{split} \ln q^*_u(\mu)&= \mathbb{E}_r[\ln p(\mathbf{X}|\mu,\tau)+\ln p(\mu|\tau)]+const \\\ &= -\frac{\mathbb{E}[\tau]}{2}\{\lambda_0(\mu-u_0)^2+\sum^N_{n=1}(x_n-\mu)^2\}+const \\\ \end{split} \end{equation}\]
我们把未知数\(\mu\)的项加和起来,就可以看出\(q^*_u(\mu)\)恰好是个高斯分布 \(N(\mu|u_N,\lambda_N^{-1})\),其中 \[\begin{equation} \begin{split}u_N &=\frac{\lambda_0u_0+N\bar{x}}{\lambda_0+N} \\\lambda_N &=(\lambda_0+N)\mathbb{E}[\tau] \\\end{split}\end{equation}\]
同样对于\(q_r(\tau)\),我们有 \[\begin{equation}\begin{split}\ln q^*_r(\tau)&=\mathbb{E}_u[\ln p(\mathbf{X}|\mu,\tau)+\ln p(\mu|\tau)]+\ln p(\tau)+const \\&=(a_0-1)\ln \tau-b_o \tau+\frac{1}{2}\ln \tau+\frac{N}{2}\ln \tau \\& -\frac{\tau}{2}\mathbb{E}_u[\sum^N_{n=1}(x_n-\mu)^2+\lambda_0(\mu-u_0)^2]+const \\\end{split}\end{equation}\] 这里\(q^*_r(\tau)\)也恰好是个Gamma分布 \(Gam(\tau|a_N,b_N)\),其中 \[\begin{equation}\begin{split}a_N&=a_0+\frac{N}{2} \\b_N&=b_0+\frac{1}{2}\mathbb{E}_u[\sum^N_{n=1}(x_n-\mu)^2+\lambda_0(\mu-u_0)^2]\end{split}\end{equation}\] 首先,要注意我们并未对\(q_u(\mu)\)或\(q_r(\tau)\)的最佳形式作出任何假设,它们就自然地形成了似然函数的形式(高斯分布)和它的先验分布形式(Gamma分布)。 然后可以看到这里\(q_u(\mu)\)与\(q_r(\tau)\)通过\(\mathbb{E}_r\)与\(\mathbb{E}_u\)相互依赖。我们展开这些式子,使用高斯分布与Gamma分布的性质(见备注1)计算它们的期望: \[\begin{equation}\begin{split}& E[\tau|a_N,b_N]=\frac{a_N}{b_N} \\& E[\mu|u_N,\lambda^{-1}_N]=u_N \\& E[X^2]=Var(X)+(E[X])^2 \\& E[\mu^2|u_N,\lambda^{-1}_N]=\lambda^{-1}_N+u_N^2 \\\end{split}\end{equation}\] 将式子(9)带入之前的式子(7)消去期望,最终得到: \[\begin{equation}\begin{split}& u_N =\frac{\lambda_0u_0+N\bar{x}}{\lambda_0+N} \\& \lambda_N =(\lambda_0+N)\frac{a_N}{b_N} \\& a_N=a_0+\frac{N+1}{2}\\&b_N=b_0+\frac{1}{2}[(\lambda_0+N)(\lambda^{-1}_N+\mu^2_N)\\& -2(\lambda_0u_0+\sum^N_{n=1}x_n)u_N+(\sum^N_{n=1}{x_n}^2)+\lambda_0{u_0}^2)]\\\end{split}\end{equation}\] 所以这时候循环依赖的对象变成了\(\lambda_N\)和\(b_N\)。然后我们迭代计算这些值
最后我们就得到了近似分布\(Q(Z)\)的所有超参数的值。
首先我们看到,之前这个\(\ln p(X)\)(也就是似然)难求是因为\(Z\)未知,在我们这个例子里的具体表现为未知参数\(\mu\)与\(\tau\)之间存在耦合关系,即\(\mu\)是由\(\tau\)生成的(\(p(\mu|\tau)\)。由于原模型存在共轭先验,所以变分后验分布的因子函数形式也可以用同样的共轭结构。因为我们定义\(Q(Z)\)分布的目的是要获得tractable的分布,所以可以在原模型的分布上作小修改,只要斩断耦合的部分即可。(这部分论述可能有问题,还需要多看书才行)
所以我们假设\(q(\mu)\)与\(q(\tau)\)之间相互独立,即\(q(\mu)\)的参数不受\(\tau\)的控制。但它依旧是个高斯分布,\(q(\tau)\)依旧是个Gamma分布,只是各自的参数未知。所以我们只要把下界看成这些分布的未知参数的函数形式,然后通过对各自参数的求导就能获得下界的极大值。(可能是因为指数家族的关系,未知参数的期望都有固定的函数形式,所以比较好求)
以之前为例,我们假设 \[\begin{equation}\begin{split}&q(\mu)=N(\mu|u_N,\lambda_N^{-1}) \\&q(\tau)=Gam(\tau|a_N,b_N) \\\end{split}\end{equation}\] 其中,\(a_N,b_N,u_N,\lambda_N^{-1}\)均为未知参数。
写出变分下界 \[\begin{equation}\begin{split}L &=\int\int q(\mu,\tau)\ln \frac{p(X,\mu,\tau)}{q(\mu,\tau)} \text{du} \text{dr} \\&=\mathbb{E}_q[\ln p(X,\mu,\tau)]-\mathbb{E}_q[\ln q(\mu,\tau)] \\&=\mathbb{E}_q[\ln p(X|\mu,\tau)]+\mathbb{E}_q[\ln p(\mu|\tau)]+\mathbb{E}_q[\ln p(\tau)] \\&-\mathbb{E}_q[\ln q(\mu)]-\mathbb{E}_q[\ln q(\tau)] \\\end{split}\end{equation}\] 其中 \[\begin{equation}\begin{split}&\mathbb{E}_q[\ln p(X|\mu,\tau)]= \frac{N}{2}\mathbb{E}_r[\ln \tau]-\frac{\tau}{2}\mathbb{E}_u[\sum^N_{n=1}(x_n-\mu)^2] \\&\mathbb{E}_q[\ln p(\mu|\tau)]= \frac{1}{2}\mathbb{E}_r[\ln \tau]- \frac{\tau}{2}\mathbb{E}_u[\lambda_0(\mu-u_0)^2]\\&\mathbb{E}_q[\ln p(\tau)]= (a_0-1)\mathbb{E}_r[\ln \tau]-b_o \mathbb{E}_r[\tau]\\&\mathbb{E}_q[\ln q(\mu)]= u_N\\&\mathbb{E}_q[\ln p(\tau)]= \frac{a_N}{b_N}\\\end{split}\end{equation}\] 根据Gamma分布的性质,将消去式(13)中的期望,最后我们获得的式子将只包括\(a_N,b_N,u_N,\lambda_N^{-1}\)这4个变量,分别对其求导,就可以得到每个参数的更新公式了(同式(10))。
备注: 1.Gamma分布 \[\begin{equation}Gam(\lambda|a,b)=\frac{1}{\Gamma(a)}b^a\lambda^{a-1}\exp(-b\lambda)\end{equation}\] 它的一些期望 \[\begin{equation}\begin{split}& \mathbb{E}[\lambda]=\frac{a}{b} \\& var[\lambda]=\frac{a}{b^2} \\& \mathbb{E}[\ln \lambda]=\Psi(a)-\ln(b)\\\end{split}\end{equation}\] 其中\(\Psi(a)=\frac{d}{da}\ln \Gamma(a)\)
]]>变分推断是一类用于贝叶斯估计和机器学习领域中近似计算复杂(intractable)积分的技术,它广泛应用于各种复杂模型的推断。本文是学习PRML第10章的一篇笔记,错误或不足的地方敬请指出。
先给出问题描述。记得在上一篇EM的文章中,我们有一个观察变量\(\mathbf{X}=\{x^{\{1\}},\ldots,x^{\{m\}}\}\)和隐藏变量\(\mathbf{Z}=\{z^{\{1\}},\ldots,z^{\{m\}}\}\), 整个模型\(p(\mathbf{X},\mathbf{Z})\)是个关于变量\(\mathbf{X},\mathbf{Z}\)的联合分布,我们的目标是得到后验分布\(P(\mathbf{Z}|\mathbf{X})\)的一个近似分布。
在之前介绍过Gibbs Sampling这一类Monte Carlo算法,它们的做法就是通过抽取大量的样本估计真实的后验分布。而变分推断不同,与此不同的是,变分推断限制近似分布的类型,从而得到一种局部最优,但具有确定解的近似后验分布。
之前在EM算法的介绍中我们有似然的式子如下: \[\begin{equation}\ln p(\mathbf{X})=L(q)+KL(q||p)\end{equation}\] 其中这里公式中不再出现参数\(\theta\),因为参数不再是固定的值,而变成了随机变量,所以也是隐藏变量,包括在\(\mathbf{Z}\)之内了。
这里的KL散度\(KL(q||p)\)描述了估计分布与真实分布的差别。当\(KL(q||p)=0\)时,俩分布就是相同的。因为我们不知道真实的后验分布是啥,所以直接最小化KL是做不到的,但是我们可以通过最大化\(L(q)\) 来达到这个目的。可以认为\(L(q)\)越大,则模型对数据拟合程度越好。由于\(\ln p(X) \geq L (q)\)始终成立,所以\(L (q)\)被称作证据下界(evidence lower bound),见图1。
为了极大化\(L(q)\),我们需要选择合适的函数\(q\),使其便于计算。要注意到\(L(q)\)并非普通的函数,而是以函数\(q\)为自变量的函数,这就是泛函。泛函可以看成是函数概念的推广,而变分方法是处理泛函的数学领域,和处理函数的普通微积分相对。变分法最终寻求的是极值函数:它们使得泛函取得极大或极小值。
要注意我们对每个\(q(\mathbf{Z}_i)\)的函数形式并没有做任何限制。这种将\(q\)分解的方法叫做平均场理论(mean field theory),主要基于基于系统中个体的局部相互作用可以产生宏观层面较为稳定的行为这个物理思想。
根据以上假设,我们来最大化下界\(L(q)\),因为假设\(q_i(\mathbf{Z}_i)\)分布之间都是独立的,所以我们依次轮流来优化,以\(q_j(\mathbf{Z}_j)\)为例(为了简单起见,缩写为\(q_j\))。
另加的这个C是为了归一化整个分布,有\(C=\int exp(\mathbb{E}_{i\neq j}[\ln p(\mathbf{X},\mathbf{Z})])d\mathbf{Z}_j\) 。然后依次更新其他\(\mathbf{Z}_j\),最终相互迭代达到稳定。
我们也可以直接衡量模型的下界。在实际应用中,变分下界可以直接判断算法是否收敛,也可以通过每次迭代都不会降低这一点来判断算法推导和实现的部分是否存在问题。 \[\begin{split}L(q)& =\int q(\mathbf{Z})\ln{\frac{p(\mathbf{X},\mathbf{Z})}{p(\mathbf{Z})}}d\mathbf{Z} \\& =\mathbf{E}_q[\ln p(\mathbf{X},\mathbf{Z})]-\mathbf{E}_q[\ln q(\mathbf{Z})] \\\end{split}\] 值得一提的是,如果我们能知道变分后验每个因子的函数形式的话,我们还有另一种估计参数的方法,这个详见例子。
变分推断和Gibbs sampling其实挺相似的:
|
|
改动都是基于这个代码。
如果要求恰好装满的话,初始化时除了\(F[0]=0\)以外,其余的F[1,…V]均设为负无穷。因为如果要求恰好装满,初始化的时候只有容量为0的背包装容量为0的物体才是合法状态,其余的状态全都不合法,用负无穷表示。
如果需要输出方案,我们只需逆推状态转移方程,确定这个状态是由哪一个策略所推出的,从而找到上一个状态即可。可以用\(G[i,v]\)记录来自哪个状态,代码如下:
|
|
其实不记录也可以,我们可以直接根据\(F[i][v]\)是否等于\(F[i-1][v-C[i]]+W[i]\)的值判断得到。
所谓的”字典序最小“就是按字典排序方式,1到N号物体的选择方案排列最靠前。很明显的1肯定比2靠前,也就是说我们尽量要选择前面的物体,由于我们原先的子问题”1..i个物体,背包容量j“会分解为”1…,i-1,背包容量j“和”1…i-1,背包容量j-C[i]“两个子问题并不符合字典序的假设,因为即使第i个物体服从字典序,也无法确定前i-1个物体是否服从字典序,因为1…i-1这个子问题已经被处理过了。
于是我们把循环顺序倒过来,子问题变成了“i..1个物体,背包容量j”会分解为“i-1…,1,背包容量j”和“i-1…1,背包容量\(j-C[i]\)”两个子问题,这样只要i做了服从字典序的选择,那我们只要去继续探究i-1…1这个子问题就好了。 所以我们把状态转移方程改成这样 \[ F[i,v]=\max\{F[i+1][v],F[i+1][v-C_i]+W_i\}\] 代码也只要把i逆序,i-1变成i+1即可。在输出的时候,如果\(F[i+1][v]==F[i+1][v-C_i]+W_i\)相等,尽量选加入i的策略,因为物品i必定比i+1靠前。代码
|
|
求方案总数一般只要把状态转移方程中的max改成sum,子问题定义为“可行的方案数”即可,要注意初始条件。
|
|
最优方案就是总价值最大的方案。这个时候只要跟着原01背包的策略走,哪个策略好就用哪个策略的方案数,如果一样好就把2个策略的方案数相加即可。
|
|
基本思想是将每个状态表示成有序队列,将状态转移方程中的max转化成有序队列的合并。\(F[i,v]\)这个有序队列是由\(F[i-1,v]\),\(F[i-1,v-C_i+W_i\)两个有序队列合并得到的。这个两个有序队列各自有自己的前K个最优解,然后两者合并得到当前的最优的K个解。 代码如下,为了节省空间使用了一维的01背包解法。
|
|
参考: 1.《背包问题9讲》,https://github.com/tianyicui/pack
]]>有\(N\)种物品和一个容量为\(V\)的背包,每种物品都有无限件可用。放入第i种物品的费用是\(C_i\),价值是\(W_i\)。求解:将哪些物品装入背包,可使这些物品的耗费的费用总和不超过背包容量,且价值总和最大。
\(F[i,v]\)代表前\(i\)件物品放入容量为\(v\)的背包可以获得的最大价值。 01背包的状态转移方程为: \[F[i,v]=\max\{F[i-1][v],F[i-1][v-C_i]+W_i\}\] 将“前\(i\)件物品放入容量为\(v\)的背包”中这个子问题,只考虑地\(i\)件物品的策略(放或不放)。如果放入\(i\)物品,问题转为“前i-1件物品放入容量为\(v-C_i\) 的背包中“这个子问题的最大价值\(F[i-1,v-C_i]\)加上\(W_i\)。如果不放,问题转化为”前i-1件物品放入容量为\(v-C_i\) 的背包中“,价值为\(F[i-1,v]\)。
代码是
注:由于后面代码有很多一样的地方,所以后面的就只列函数和不同的地方,数组定义和max函数定义什么就省略了。
因为状态转移方程只用到了i-1的状态,i-1之前的状态都用不上。所以只要保证我们在算\(F[i,v]\)时,能取得\(F[i-1,v]\)和\(F[i-1,v-C_i]\)的值即可。在只使用一维数组的情况下,只要保证在覆盖当前位置前,\(F[v]\)保存的是i-1时刻的\(F[v]\)的值就行,\(F[v-C_i]\)也是类似。所以只要每次循环中以\(v \leftarrow V,\ldots,0\) 的递减顺序计算更新\(F[v]\)就可以了。 关键代码如下
|
|
事实上,由于后面的问题可以分解为一维数组解01背包问题,所以将处理01背包问题中的一个物品的过程抽象出来,定义如下。
|
|
有N种物品和一个容量为V的背包,每种物品都有无限件可用。放入第i种物品的费用是\(C_i\),价值是\(W_i\)。求解:将哪些物品装入背包,可使这些物品的耗费的费用总和不超过背包容量,且价值总和最大。
如果按01背包的思路,我们只要有状态转移矩阵 \[F[i,v]=\max\{F[i-1][v-k C_i]+k W_i|0 \leq k \leq [v/C_i]\}\] 这个问题有\(O(VN)\)个状态要解,而且求每个状态的时间是\(O(\frac{v}{C_i})\),总的复杂度上界是\(O(NV\sum \frac{V}{C_i})\),还是比较大的。 代码如下:
|
|
我们的问题是求”前\(i\)件物品放入容量为\(v\)的背包“的最大价值,原先的循环是先确定前i-1个物品的最优策略,然后考虑加不加物品\(i\),来比较不同容量\(v\)下背包的价值是否有变化,但是这里物品\(i\)变成多个可选了,所以复杂度提高了。我们反过来想,先确定背包\(v-1\)容量时的物品的最优策略,然后考虑\(v\)容量下,对于随着可选物品\(i\)的增多,考虑背包的最大价值是否有变化。 状态转移方程为 \[F[i,v]=\max\{F[i-1][v],F[i][v-C_i]+W_i\}\] 这里\(F[i-1][v]\)是不选第\(i\)个物品时,背包的最大价值,\(F[i][v-C_i]+W_i\)是选了物品\(i\)时,背包的最大价值。需要注意的是,在\(v\)增长的过程中,物品\(i\)有可能被选择多次,因为每轮\(v\)的循环都要考虑一次物品\(i\)。 代码如下:
|
|
直接先给出代码:
|
|
这个算法的时间复杂度也是\(O(VN)\),但空间复杂度只有\(O(N)\)。你会注意到,这个代码与01背包的优化算法只有\(v\)的循环顺序不同而已。这个不同之处就是问题的关键。在\(v \leftarrow V,\ldots,0\) 的递减顺序计算的时候,背包内除了当前加或不加的物品\(i\)以外,其余的物品一定是前\(i-1\)个之中的,这样保证了物品\(i\)只会被处理一次。而完全背包问题中,物品\(i\)是可以加无数次的,我们在对当前容量\(v\)的背包做加不加物品\(i\)的策略时,是根据有可能在之前较小的容量\(v\)中已经选入第\(i\)种物品的子结果\(F[i,v-C_i]\)中得到的(而不是\(F[i-1,C_i]\))。 所以,写出来的状态转移方程是这 \[F[v]=\max\{F[v],F[v-C_i]+W_i\}\] 我们可以理解为 \[F[i,v]=\max\{F[i-1][v],F[i][v-C_i]+W_i\}\] 和优化思路1的状态转移方程一摸一样。 同样,我们将完全背包的过程抽象出来:
|
|
有N种物品和一个容量为V的背包。第i种物品最多有\(M_i\)件可用,每件耗费的空间是\(C_i\),价值是\(W_i\)。求解将哪些物品装入背包可使这些物品的耗费的空间总和不超过背包容量,且价值总和最大。
基本思路和完全背包类似,就是将\(k\)的上限改为\(M_i\)即可,这里就不写了。
如果我们直接把第\(i\)种物品的看做对\(M_i\)个01背包物品做选择的话,其复杂度其实并没有下降。
换一种拆分方式,我们希望把第\(i\)中物品换成一些小的物品,不管第\(i\) 种物品有几件,都可以由这些小物品的相互组合得到。现在考虑二进制的思想,把物品拆成\(2^k*C_i\),\(1,2,2^{k-1}\),价值为\(2^k*W_i\)的物品。假设最大物品数量是\(M_i\),必定存在一个k,使得\(1+2+2^2+\ldots+2^{k-1} \leq M_i \leq 1+2+2^2+\ldots+2^k\)。用\(k\)位二进制最多能表示到\(\sum_{i=1}^k 2^{i-1}=2^k+1\)这么大的数,而由上面的式子,肯定有\(M_i-2^k+1<2^k\),所以用\(k\)位二进制数就可以表示系数中的最大值\(M_i-2^k+1\)。令系数为\(1+2+2^2+\ldots+2^{k-1},M_i-2^k+1\),\(k\)是满足\(M_i-2^k+1>0\)的最小整数。
同样地,完全背包也可以使用这个方法,只不过上限变成了\([v/C_i]\)而已。
给出代码如下:
|
|
将整个过程抽象出来,得到
|
|
有N件物品和一个容量为V的背包。放入第i件物品最多有\(M_i\)件可用,每件占用的容量是\(C_i\)。求是否能刚好填满给定容量的背包。这个问题只求可行性,不考虑价值,有复杂度为\(O(VN)\)的算法。
这个问题是有\(O(VN)\)的解法的,它的思想是这样的,令\(F[i][j]\)代表“用了前\(i\)中物品刚好填满容量为\(j\)的背包后,还留下的可用物品\(i\)的个数”。如果\(F[i][j]=-1\)说明这个状态不行,如果状态可行的话应该有\(0 \leq F[i][j]\leq M_i\)。
首先,在循环到第\(i\)个物品的时候,用前\(i-1\)个物品能够填满容量为\(j\)的背包的情况必须被记录下来,这时候只要我们不选\(i\),就可以填满容量为\(j\)的背包了。(注意,不选\(i\)的时候\(F[i][j]=M_i\))。当然,如果用前\(i-1\)个物品能够填满容量为\(j\)的背包,那么我们只要加上一个物品\(i\),就可以恰好填满容量为\(j+C[i]\)的背包啦。
所以状态转移矩阵是这样的, \[F[i,j]=\max{F[i][j],F[i][j-C[i]]-1}\] 两种情况,一种情况是\(F[i,j]\)是由\(F[i][j-C[i]]\)得来,因为用了一个物品\(i\),所以值\(为F[i][j-C[i]]-1\),另一种情况是不使用物品\(i\),由\(F[i-1,j]\) 直接得到,这时候值为\(M_i\)。 给出代码:
最后\(F[N][0,\ldots,V]\)就是多重背包在各个容量上是否可行的答案。
如果将前面1、2、3中的三种背包问题混合起来。也就是说,有的物品只可以取一 次(01 背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限 (多重背包)。应该怎么求解呢?
直接调用之前的三个过程
|
|
参考: 1.《背包问题9讲》,https://github.com/tianyicui/pack 2.师兄的博客,http://www.ahathinking.com/archives/118.html
]]>虽然我猜出了公式,但是还是不怎么懂。。。讲一下猜的过程:
虽然我们知道了具体的概率,还是希望有个期望值来告诉我们大概在吃几个盘子的时候你能够舔遍全食堂的盘子。根据《算法导论》5.4.2的说法,我们将吃到以前没吃过的盘子的时候定义为“命中”,然后我们要求为了吃完m个盘子需要吃的次数n。
命中次数可以用来讲n次吃饭划分为多个阶段。第i个阶段包括从第i-1次命中到第i次命中所吃的次数。第1阶段因为所以盘子都没被吃过,所以是必中的。第i阶段的每一次吃饭,都有i-1个盘子被吃过,m-i+1个盘子没被吃过,这样第i次命中的概率就是(m-i+1)/m。
用\(n_i\)表示第i阶段的吃饭次数。每个随机变量\(n_i\)都服从概率为(m-i+1)/m的几何分布。根据几何分布的期望可以算得最后的式子是调和级数的上界,所以我们希望吃完所有的盘子大概需要\(m\ln m\)次,这个问题也被称作赠卷收集者问题(coupon collector’s problem)。 如果食堂有1000 个盘子,我们大学4年估计是吃不完的。。。
]]>题目(引用自参考1):假设有3枚硬币,分别记做A,B,C。这些硬币正面出现的概率分别是\(\pi\),\(p\)和\(q\)。进行如下掷硬币实验:先掷硬币A,根据其结果选出硬币B或C,正面选B,反面选硬币C;然后投掷选重中的硬币,出现正面记作1,反面记作0;独立地重复\(n\)次(n=10),结果为 \[1111110000\] 我们只能观察投掷硬币的结果,而不知其过程,估计这三个参数\(\pi\),\(p\)和\(q\)。
可以看到投掷硬币时到底选择了B或者C是未知的。我们设隐藏变量Z 来指示来自于哪个硬币,\(Z=\{z_1,z_2,\ldots,z_n \}\),令\(\theta=\{\pi,p,q\}\),观察数据\(X=\{x_1,x_2,\ldots,x_n \}\)。
写出生成一个硬币时的概率: \[\begin{split}P(x|\theta) & =\sum_z P(x,z|\theta)=\sum_z P(z|\pi)P(x|z,\theta) \\& =\pi p^x (1-p)^{1-x}+(1-\pi)q^x(1-q)^{1-x} \\\end{split}\] 有了一个硬币的概率,我们就可以写出所有观察数据的log似然函数: \[L(\theta|X)=\log P(X|\theta)=\sum^n_{j=1}\log[\pi p^{x_j} (1-p)^{1-{x_j}}+(1-\pi)q^{x_j}(1-q)^{1-{x_j}}]\] 然后求极大似然 \[\hat{\theta}=\arg \max L(\theta|X)\] 其中\(L(\theta|X)=\log P(X|\theta)=\log \sum_Z P(X,Z|\theta)\)。因为log里面带着加和所以这个极大似然是求不出解析解的。 如果我们知道隐藏变量Z的话,求以下的似然会容易很多: \[L(\theta|X,Z)=\log P(X,Z|\theta)\] 但是隐藏变量Z的值谁也不知道,所以我们转用EM算法求它的后验概率期望\(E_{Z|X,\theta}(L(\theta|X,Z))\)的最大值。
E步:假设当前模型的参数为\(\pi,p,q\)时,隐含变量来自于硬币B的后验概率 \[\mu=P(Z|X,\theta)=\frac{\pi p^{x_i}(1-p)^{1-x_i}}{ \pi p^{x_i}(1-p)^{1-x_i}+(1-\pi)q^{x_i}(1-q)^{1-x_i}}\] 那么隐含变量来自于硬币C的后验概率自然为\(1-\mu\)。
M步: 先写出似然关于后验概率的期望,它是似然期望下界函数的最大值, \[\begin{split}&E_{Z|X,\theta}(L(\theta|X,Z))=\\&\sum^n_{j=1}[ \mu \log{\frac{\pi p^{x_i}(1-p)^{1-x_i}}{\mu}}+(1-\mu) \log{\frac{(1-\pi)q^{x_i}(1-q)^{1-x_i}}{1-\mu}} ]\\\end{split}\] 要注意这里把\(\mu\)看做固定值。然后我们分别求偏导,获得参数\(\pi,p,q\)的新估计值 \[\begin{split}& \pi=\frac{1}{n}\sum^n_{j=1}\mu_j \\& p=\frac{\sum^n_{j=1}\mu_j x_j}{\sum^n_{j=1}\mu_j} \\& q=\frac{\sum^n_{j=1}(1-\mu_j) x_j}{\sum^n_{j=1}(1-\mu_j)} \\\end{split}\]
算法首先选取参数初始值\(\theta^{(0)}=\pi^{(0)},p^{(0)},q^{(0)}\),然后迭代到收敛为止。
其实这道题用EM做就可以了,因为最近看了Gibbs Sampling,所以套一下看看,如果有错敬请指出~
先给出Gibbs sampling的抽象的应用步骤,由于目标是对latent varibles逐一sample得到complete data再算充分统计量。所以关键是求 \(P(Z_i|Z_{-i},O,\alpha)\):
首先我们确定建模过程,画出概率图: 可以看到硬币B还是硬币C的类标签服从贝努利分布 \[Z_j \sim Bernoulli(\pi)\] 然后硬币正反面的出现也服从贝努利分布 \[W_{z_{j}k} \sim Bernoulli(\theta_{Z_j})\] 其中\(\theta=\{p,q\}\)。需要注意这里参数都变成了随机变量,都有先验分布。为了简单和无偏倚起见,Beta分布的先验参数均设为1, \(\alpha=<1,1>\),\(\beta=<1,1>\),这样\(p(\alpha)=1,p(\beta)=1\),在实际运算中就不考虑了。
然后写出联合分布来应该是(要注意这里的联合分布应该是似然与先验\(p(\theta)\)的乘积,因为先验\(p(\alpha)=1,p(\beta)=1\)所以省略了后项)
\[ \begin{split}P(C,Z,\pi,p,q)&=p(W|Z,\Theta)p(\Theta|\gamma_{\theta})p(Z|\pi)p(\pi|\gamma_{\pi})\\ &= \prod^N_{i=1} \pi^{z_{i}} (1-\pi)^{1-z_{i}} p^{W_{z_{i0}}} (1-p)^{W_{z_{i1}}} q^{W_{(1-z_{i})0}} (1-q)^{W_{(1-z_{i})1}} \\ & =\pi^{C_0} (1-\pi)^{C_1} p^{N_{C_0}(0)} (1-p)^{N_{C_0}(1)} q^{N_{C_1}(0)} (1-q)^{N_{C_1}(1)} \\ \end{split} \]
其中\(z_i=0\)时选中硬币B,\(z_i=1\)时选中硬币C,\(W_{xj}\)是观察到的硬币B或硬币C的正反结果,正面为\(W_{x0}=1,W_{x1}=0\),反面为\(W_{x1}=1,W_{x0}=0\) ,\(C_0\)是所有结果中选中硬币B的次数,\(C_1\)是选中硬币C的次数,\(N_{C_0}(0)\)是选B 的硬币中正面的硬币个数,\(N_{C_0}(1)\) 是选B的硬币中反面的硬币个数,\(N_{C_1}(0)\)是选C的硬币中正面的硬币个数,\(N_{C_1}(1)\)是选C的硬币中反面的硬币个数。
然后根据Gibbs Sampling对隐藏变量Z采样,首先,我们设\({Z}^{-j}\)是除了\(Z_j\)外所有的硬币标签,然后\(C^{(-j)}\)是除了\(W_j\)外所有的硬币结果集合。硬币A的投掷有2个结果,\(Z_j=0\)(硬币B)或\(Z_j=1\)(硬币C)。如果\(Z_j=0\),那么\(C_0^{-j}=C_0-1,C_1^{-j}=C_1\)。反之如果文档\(Z_j=1\),那么\(C_1^{-j}=C_1-1,C_0^{-j}=C_0\)。
我们构建Gibbs Sampler,采样公式为: \[\begin{split}P(Z_j=0|Z^{-j},C^{-j},\pi,p,q) &=\frac{P(Z,C,\pi,p,q)}{P(Z^{-j},C^{-j},\pi,p,q)} \\&=\pi p^{W_{j0}} (1-p)^{W_{j1}}\\P(Z_j=1|Z^{-j},C^{-j},\pi,p,q) &=\frac{P(Z,C,\pi,p,q)}{P(Z^{-j},C^{-j},\pi,p,q)} \\&=(1-\pi) q^{W_{j0}} (1-q)^{W_{j1}}\end{split}\]
然后根据这两个概率对\(Z_j^{(t+1)}\)做贝努利实验,得到新采样的结果。
在对\(Z\)采样获得了所有硬币的正反面之后,我们接下来要估计\(\pi,p,q\)。
Gibbs Sampler的公式分别为: \[\begin{split}&P(\pi|Z,C,p,q)=\pi^{C_0} (1-\pi)^{C_1}\\&P(p|Z,C,\pi,q)=p^{N_{C_0}(0)} (1-p)^{N_{C_0}(1)}\\&P(q|Z,C,\pi,p)=q^{N_{C_1}(0)} (1-q)^{N_{C_1}(1)}\\ \end{split}\] 这里\(\pi,p,q\)均服从贝努利分布,根据Beta-Bernoulli共轭(之前先验分布为Beta(1,1)),我们可以把他们看成后验的Beta分布 \[\begin{split}&\pi \sim Beta(1+C_0,1+C_1)\\&p \sim Beta(1+N_{C_0}(0),1+N_{C_0}(1))\\&q \sim Beta(1+N_{C_1}(0),1+N_{C_1}(1))\\\end{split}\] 然后从各自的Beta分布中采样出\(\pi,p,q\)的值,详见这里的求\(\theta\)部分。
根据《Gibbs Sampling for the UniniTiated》上所说,\(\pi\)可以被积分掉来简化联合分布,这种方法被称作“Collapsed Gibbs Sampling”,指通过积分避开了实际待估计的参数,转而对每个硬币的正反面\(z\)进行采样,一旦每个硬币的z确定下来,被积分的值可以在统计频次后计算出来。正巧这里\(\theta=\{p,q\}\)也只生成一个样本,可以被积分,就统统给积分好了。 \[\begin{split}&P(C,Z)= \int\int\int P(C,Z,\pi,p,q) d \pi d p d q \\&=\int\int\int \pi^{C_0} (1-\pi)^{C_1} p^{N_{C_0}(0)} (1-p)^{N_{C_0}(1)} q^{N_{C_1}(0)} (1-q)^{N_{C_1}(1)} d \pi d p d q \\&=\int \pi^{C_0} (1-\pi)^{C_1}d \pi \int p^{N_{C_0}(0)} (1-p)^{N_{C_0}(1)} dp \int q^{N_{C_1}(0)} (1-q)^{N_{C_1}(1)} \\&=\frac{\Gamma(C_0+1)\Gamma(C_1+1)}{\Gamma(C_0+C_1+2)}\frac{\Gamma(N_{C_0}(0)+1)\Gamma(N_{C_0}(1)+1)}{\Gamma(C_0+2)}\frac{\Gamma(N_{C_1}(0)+1)\Gamma(N_{C_1}(1)+1)}{\Gamma(C_1+2)}\end{split}\] 最后一步是根据Beta分布的积分公式得出的。要注意这个式子里还是存在未知数的\(Z\)的,只不过被加和掩盖了而已。
在这里采样公式就变成了 \[\begin{split}&P(Z_j=0|Z^{-j},C^{-j})=\frac{C_0}{C_0+C_1+1}(\frac{N_{C_0}(0)}{C_0+1})^{W_{j0}}(\frac{N_{C_1}(0)}{C_1+1})^{W_{j1}}\\&P(Z_j=1|Z^{-j},C^{-j})=\frac{C_1}{C_0+C_1+1}(\frac{N_{C_0}(1)}{C_0+1})^{W_{j0}}(\frac{N_{C_1}(1)}{C_1+1})^{W_{j1}}\\ \end{split}\] 根据这两个概率对\(Z_j^{(t+1)}\)做贝努利实验,得到新采样的结果。
在\(Z\)的一轮迭代结束后我们还要估计被积分了的变量的值,已知后验概率为 \[\begin{split}&p(\pi|Z)=\prod^n_{i=1}p(z|\pi)p(\pi|r_\pi)=Beta(\pi|1+C_0,1+C_1)\\&p(p|Z)=\prod^n_{i=1}p(z|p)p(p|r_\theta)=Beta(\pi|1+N_{C_0}(0),1+N_{C_0}(1))\\&p(q|Z)=\prod^n_{i=1}p(z|q)p(q|r_\theta)=Beta(\pi|1+N_{C_1}(0),1+N_{C_1}(1))\\ \end{split}\] 根据贝叶斯推断的话,我们应该求整个参数分布上的期望,所以有 \[E(\pi)=\int \pi \cdot \pi^{C_0+1-1}(1-\pi)^{C_1+1-1} d \pi=\frac{C_0+1}{C_0+C_1+2}\] 这里还是利用Beta分布的积分公式,同理剩下的俩为 \[\begin{split}&E(p)=\frac{N_{C_0}(0)+1}{C_0+2}\\&E(q)=\frac{N_{C_1}(0)+1}{C_1+2}\\ \end{split}\] 这里可以看到先验知识(分子式上面的1和分母的2)和观察到的数据很好的结合了起来。
两者都常用来估计latent variable分布的参数。主要思想一致:先估计生成一些latent variable,然后看成complete data,算参数。 区别:
EM直接估计所有latent varibles的联合概率;
Gibbs估计单个单个latent variable的条件概率;
所以,EM类似梯度下降,而Gibbs类似于coordinate gradient decent(不是conjugate)。
EM算法中的E步估计所有latent varible的联合概率分布,可能很复杂。所以可以用抽样的方法来估计,以下是似然函数的期望表达式: \[Q(\theta,\theta^{old})=\int p(Z|X,\theta^{old})\ln p(Z,X|\theta)d Z\] 我们可以在后验概率\(p(Z|X,\theta^{old})\)的分布上进行有限次数的抽样来接近这个期望: \[Q(\theta,\theta^{old}) \simeq \frac{1}{L}\sum^L_{l=1}\ln p(Z^{(l)},X|\theta)\] 然后像往常一样在M步优化Q函数,这个方法叫做Monte Carlo EM算法。
而每次在E步只生成一个样本的方法叫做stochastic EM,是Monte Carlo EM 算法的一个特例。在E步,我们从后验概率\(p(Z|X,\theta^{old})\)中抽取一个样本,用来近似计算似然的期望,然后在M步更新模型参数的值。
刚才介绍的Collapsed Gibbs Sampling的方法就是stochastic EM的一个例子,只不过,M步骤的参数估计结果在E步骤中没有用到,所以不需要重复多余的M步骤,只需在最后进行一次M步骤,得到所需要的参数即可。
这篇是下篇,讨论中篇联合分布中对参数求积分来简化的问题。
之前存在的一个问题就是为啥我们可以对连续参数\(\pi\)求积分消去它,而不能对词分布\(\theta_0\)和\(\theta_1\)求积分。这个主意看上去很美,但是实际做的时候,你会碰到一大把无法约掉的伽马函数。让我们看看具体的过程。
首先明确的是,我们的目标是求得从这个文档所在的类\(C_x\)(除去该文档)中生成的\(\theta\)分布中生成这篇文档的所有词的概率(真拗口啊- -)。我们先做个简单的版本,先求生成这篇文档中的一个词的概率,我们令\(w_k\) 为文档\(W_j\)中的\(k\)位置的词,然后为了简单起见,省略以下公式所有的统计量上都存在的\((-j)\)上标: \[\begin{split}& P(w_k=y|\mathbb{C}_x^{(-j)}; \gamma_\theta) \\& =\int_\Delta P(w_k=y|\theta)P(\theta|\mathbb{C}_x^{(-j)}; \gamma_\theta) d\theta \\&=\int_\Delta\theta_{x,y}\frac{\Gamma{(\sum^V_{i=1}\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i})}}{\prod^V_{i=1}\Gamma{(\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i})}}\prod^V_{i=1}\theta_{x,i}^{\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i}-1}d\theta\\&= \frac{\Gamma{(\sum^V_{i=1}\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i})}}{\prod^V_{i=1}\Gamma{(\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i})}} \int_\Delta\theta_{x,y} \prod^V_{i=1}\theta_{x,i}^{\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i}-1}d\theta\\&= \frac{\Gamma{(\sum^V_{i=1}\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i})}}{\prod^V_{i=1}\Gamma{(\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i})}} \int_\Delta\theta_{x,y}^{\mathcal{N}_{\mathbb{C}_x}(y)+\gamma_{\theta_y}}\prod^V_{i=1\wedge i\neq y}\theta_{x,i}^{\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i}-1}d\theta\\&= \frac{\Gamma{(\sum^V_{i=1}\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i})}}{\prod^V_{i=1}\Gamma{(\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i})}} \frac{\Gamma{(\mathcal{N}_{\mathbb{C}_y}(i)+\gamma_{\theta_y}+1)\prod^V_{i=1\wedge i\neq y}\Gamma{(\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i})}} }{\Gamma(\sum^V_{i=1}\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i}+1)}\\&=\frac{\mathcal{N}_{\mathbb{C}_x}(y)+\gamma_{\theta_y}}{\prod^V_{i=1}\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i}}\end{split}\] 这个过程是和之前求\(\pi\)的积分是一样的,只不过由Beta分布换成了Dirichlet 分布的情形。在此时,我们获得了一个简单清晰的生成单个词的概率,介于我们实际上需要生成文档中的所有词,为什么能不能用这种方法生成文档\(W_j\)中每一个词,然后把所有生成词的概率相乘呢?
答案是不行。因为每个单词中\(\theta_{x,y}\)它并不是一个固定的值,每一次我们对单个词的抽样将对\(\theta\)的值产生影响!如果我们尝试着一次性生成2个词,就会发现在倒数第二步无法消去大量的伽马函数。从概率图上看,每个\(\theta\)的箭头指向\(R_j\)个相互的独立的词,所以这些词处于一个贝叶斯网络中,如果\(\theta\)未知的话,我们不能假设这些词都是独立的。
在积分变量的时候要小心,如果是多项分布抽一个样本,对其积分就可以让Gibbs Sampler更简单。反之,如果一次从同一个多项分布中抽取多个样本,即使可以积分,形式也会非常复杂。
PS:
看到这里我有疑问。在LDA中,doc-topic分布\(\theta\)和topic-word分布\(\phi\)恰恰是通过积分求出来的,难道是因为它们假设主题和词的样本是一次性全部生成的?LDA的采样方法被称为”Collapsed Gibbs Sampling“,即通过积分避开了实际待估计的参数,转而对每个单词w的主题z采样,然后通过确定所有w的z然后积分获得\(\theta\)和\(\phi\)的值,和这里的区别究竟在哪?
2013/7/2日更新:
看了维基百科对Dirichlet-multinomial distribution的介绍,终于搞明白了。
首先这个跟是不是用“Collapsed”方法没啥关系,而是这两个模型有本质上的不同。
在LDA模型中,每个词\(w_{dn}\)都是由唯一的\(z_{dn}\)生成的,两者是一一对应的关系。我们写出\(z_{dn}\)生成文档\(W_j\)的联合概率 \[\begin{split}P(W_j|Z_n)& =p(w_{dn}|W_j^{-dn},z_{dn})p(W_j^{-dn}|z_{dn}) \\& =p(w_{dn}|W_j^{-dn},z_{dn})P(W_j^-{dn}) \\& \sim p(w_{dn}|W_j^{-dn},z_{dn}) \\\end{split}\] 可以看到,我们注意到\(W_j^{-dn}\)(除去了\(w_{dn}\)的词集合)中没有任何一个点与\(z_{dn}\)有关。
而朴素贝叶斯模型,它和LDA非常类似,唯一的区别就在于它是一篇文档一个主题,而不是一个词一个主题。这样的话,一个分布topic-word分布就会生成多个词,而不是生成一个。在计算隐藏变量\(Z\)的条件分布时,就需要一次性包含\(Z_d\)所产生的所有词,从而像上面所说的那样坑爹地无法化简。
这篇是中篇,介绍一个非常简单的朴素贝叶斯文档模型生成的例子,用来说明Gibbs Sampler具体是如何构造的。
首先我们有一批文档,文档里面有很多单词,这些单词都是无顺序可交换的(词袋模型),这些文档分成两类,类标签为0或者1。给予一篇未标记的文档\(W_j\),我们要做的工作就是预测文档的类标签是\(L_j=0\)还是\(L_j=1\)。为了方便起见,我们定了类标签所表示的类\(\mathbb{C}_0={W_j|L_j=0}\)和\(\mathbb{C}_1={W_j|L_j=1}\)。一般来说预测这种事都是选择最有可能发生的,即找到\(W_j\)的后验概率\(P(L_j|W_j)\)最大的标签\(L_j\)。使用贝叶斯公式 \[\begin{equation} \begin{split} L_j=\arg \max \limits_{L}P(L|W_j)& =\arg \max \limits_{L}\frac{P(W_j|L)P(L)}{P(W_j)}\\& =\arg \max \limits_{L} P(W_j|L)P(L) \\\end{split} \end{equation}\] 因为分母\(P(W_j)\)与\(L\)无关所以删去了。 通过贝叶斯公式的转换,我们可以想象这些文档的生成过程。首先,我们选择文档的类标签\(L_j\);假设这个过程是通过投硬币完成的(正面概率为\(\pi=P(L_j=1)\) ),正式地来说,就是服从贝努利分布 \[\begin{equation}L_j \sim Bernoulli(\pi)\end{equation}\] 然后,对于文档上\(R_j\)个“词位”中的每一个,我们根据一个概率分布\(\theta\),随机独立地抽样一个词\(w_i\)。因为每个类生成词的\(\theta\)分布都不同,所以应该有\(\theta_1\)和\(\theta_2\),具体地生成词的时候,我们根据文档的标签\(L_j\)来决定由哪个类来生成 \[\begin{equation} W_j \sim Multinomial(R_j,\theta_{L_j}) \end{equation}\]
上面提到的参数\(\pi\)和\(\theta\)还有各自的先验知识。我们假设参数\(\pi\)是从一个参数为\(\gamma_{\pi_1}\)和\(\gamma_{\pi_0}\)的Beta分布中采样出来的。这里\(\gamma_\pi=<\gamma_{\pi_1},\gamma_{\pi_0}>\) 被称作超参数,因为它们是先验模型的参数,是为了确定模型的参数而存在的。类似地,就像Beta分布是贝努利分布的共轭先验一样,\(\theta\) 参数的确定来自于参数为\(\gamma_\theta\)的Dirichlet分布。公式如下: \[\begin{equation}\pi \sim Beta(\gamma_\pi)\end{equation}\]\[\begin{equation}\theta \sim Dirichlet(\gamma_\theta)\end{equation}\] 选择Beta分布和Dirichlet分布作为先验分布,是为了数学上的方便。所以的参数定义见图1和图2(这个概率图非常好看,是从别人的博客对这篇文章的介绍中借来的,来自于[3]).
状态空间。在前面提到过一样,Gibbs 抽样器要做的是遍历模型中\(k\)维状态空间,对里面所有的变量采样。在当前模型的状态空间中存在以下变量:
1个标量变量\(\pi\)
2个向量变量\(\theta_0\)和\(\theta_1\)。
N篇文档所对应的二元标签向量变量\(\mathbf{L}\)。
还有每篇文档里的词向量\(W_j\),但是他们是被观察到的数据,值已经知道了(这就是为啥图2中的概率图\(W_{jk}\)是实心的)。
初始化。初始化就是一篇文档的生成过程,不细讲了。
对于之前提到的每次循环\(t=1\ldots T\),我们都像上篇的式子(11)中提到的那样,利用其他变量的条件分布对状态空间中的每个变量更新。具体过程如下:
写出所有变量的联合分布
简化联合分布的公式
确定上篇的式(11)中条件分布的公式
给出采样器伪码的最终形式
根据模型,我们可以得到整个文档的联合分布\(P(\mathbb{C},\mathbf{L},\pi,\theta_0,\theta_1;\gamma_{\pi_1},\gamma_{\pi_0},\gamma_{\theta})\)。 根据模型的生成过程和概率图,我们可以将联合分布分解: \[\begin{equation} P(\pi|\gamma_{\pi_1},\gamma_{\pi_0})P(\mathbf{L}|\pi)P(\theta_0|\gamma_{\theta})P(\theta_1|\gamma_{\theta})P(\mathbb{C}_0|\theta_0,\mathbf{L})P(\mathbb{C}_1|\theta_1,\mathbf{L}) \end{equation}\] 然后将一个一个地来解释这些式子(从引用了一部分):
\(P(\pi|\gamma_{\pi_1},\gamma_{\pi_0})\)。这个式子是根据超参数为\(\gamma_{\pi_1}\)和\(\gamma_{\pi_0}\)的Beta分布中采样出\(\pi\)的公式,根据Beta 分布的定义,概率为 \[\begin{equation}P(\pi|\gamma_{\pi_1},\gamma_{\pi_0})=\frac{\Gamma(\gamma_{\pi_1}+\gamma_{\pi_0})}{\Gamma(\gamma_{\pi_1})\Gamma(\gamma_{\pi_0})}\pi^{\gamma_{\pi_1}-1}(1-\pi)^{\gamma_{\pi_0}-1} \end{equation}\] 因为右边式子的\(\frac{\Gamma(\gamma_{\pi_1}+\gamma_{\pi_0})}{\Gamma(\gamma_{\pi_1})\Gamma(\gamma_{\pi_0})}\) 是个常量(设为\(c\)),而整个联合分布最终要把所有的常量归一化,所以在这里先不管它,把式子写作 \[\begin{equation} P(\pi|\gamma_{\pi_1},\gamma_{\pi_0}) \propto \pi^{\gamma_{\pi_1}-1}(1-\pi)^{\gamma_{\pi_0}-1} \end{equation}\]
\(P(\mathbf{L}|\pi)\)。第二个式子是由参数\(\pi\)或\(1-\pi\)生成标签变量1或0的过程,要注意一共有\(N\)篇文档,每篇文档的标签生成都是相互独立的: \[\begin{equation} \begin{split}P(\mathbf{L}|\pi)& =\prod^N_{n=1}\pi^{L_n}(1-\pi)^{N-L_n} \\ &=\pi^{C_1}(1-\pi)^{C_0} \\ \end{split} \end{equation}\] 其中\(C_0\)是和\(C_1\)分别是标签为0和1的文档数目。
\(P(\theta_0|\gamma_{\theta})\)和\(P(\theta_1|\gamma_{\theta})\)。这个式子是根据超参数为\(\gamma_{\theta}\)的Dirichlet分布中采样出\(\theta_0\)和\(\theta_1\)的词分布的过程。因为\(\theta_0\)和\(\theta_1\)相互独立,生成的过程是一样的,所以为了简单起见,我们暂时舍去类的下标,公式如下: \[\begin{equation} \begin{split} P(\theta|\gamma_{\theta})&=\frac{\Gamma{(\sum^V_{i=1}\gamma_{\theta_i})}}{\prod^V_{i=1}\Gamma{(\gamma_{\theta_i})}}\prod^V_{i=1}\theta_i^{\gamma_{\theta_i}-1}\\& = c'\prod^V_{i=1}\theta_i^{\gamma_{\theta_i}-1} \\& \propto \prod^V_{i=1}\theta_i^{\gamma_{\theta_i}-1} \\\end{split} \end{equation}\] \(\gamma_{\theta_i}\)代表了向量\(\gamma_{\theta}\)第\(i\)维的值。类似地,\(\theta_i\)代表向量\(\theta\)地\(i\)维的值,其物理意义就是该分布上第\(i\)个词被生成的概率。\(c'\)是另一个归一化因子。
\(P(\mathbb{C}_0|\theta_0,\mathbf{L})\)和\(P(\mathbb{C}_1|\theta_1,\mathbf{L})\)。这俩式子是具体地生成该类的所有文档中的所有词的过程。首先要求来看对于单独一个文档\(n\),产生所有word也就是\(W_n\)的概率。假设对于某个文档,\(\theta=(0.2,0.5,0.3)\),意思就是word1产生概率为0.2,word2产生概率为0.5,word3的概率为0.3。假如这个文档里word1有2个,word2有3个,word3有2个,则这个文档的产生概率就是(0.20.2)(0.50.50.5)(0.30.3)。所以按照这个道理,一个文档生成的联合概率如下: \[\begin{equation}P(W_n|\mathbf{L},\theta_{L_n})=\prod^V_{i=1}\theta_i^{W_{ni}} \end{equation}\] 这里\(\theta_{L_n}\)代表了文档\(n\)所在的类(\(\theta_0\)或\(\theta_1\)),\(\theta_i\)像之前提过的那样,代表产生第\(i\)个词的概率,而指数\(W_{ni}\)为该词出现的频率。现在我们有一篇文档的生成概率了,然后我们把一个类别下面的所有文档都合并起来(因为都是相互独立的么) \[\begin{equation}\begin{split} P(\mathbb{C}_x|\mathbf{L},\theta_x)& =\prod_{n\in \mathbb{C}_x} \prod^V_{i=1}\theta_i^{W_{ni}} \\ &=\prod^V_{i=1}\theta_{x,i}^{\mathcal{N}_{\mathbb{C}_x(i)}}\end{split}\end{equation}\] 其中\(x\)代表了类的标号(这里是0或1),\(\mathcal{N}_{\mathbb{C}_x}\)代表了类标号为\(x\)的所有文档生成词\(i\)的数目。
然后我们将先验知识 \(P(\mathbf{L}|\pi)\)与观察到的evidence\(P(\pi|\gamma_{\pi_1},\gamma_{\pi_0})\) 相乘,我们可以看到估计的参数\(\pi\) 是如何被观察到的数据所影响的。利用式子(7) 和(9) 我们得到 \[\begin{equation} \begin{split} P(\pi|\mathbf{L};\gamma_{\pi_1},\gamma_{\pi_0}) &=P(\mathbf{L}|\pi)P(\pi|\gamma_{\pi_1},\gamma_{\pi_0}) \\& \propto [\pi^{C_1}(1-\pi)^{C_0}][\pi^{\gamma_{\pi_1}-1}(1-\pi)^{\gamma_{\pi_0}-1}] \\& \propto \pi^{C_1+\gamma_{\pi_1}-1}(1-\pi)^{C_0+\gamma_{\pi_0}-1} \\ \end{split} \end{equation}\] 对于\(\theta\),类似地我们结合(10)和(12),有 \[\begin{equation} \begin{split}P(\theta|W_n;\gamma_\theta)& =P(W_n|\theta)P(\theta|\gamma_\theta) \\& \propto \prod^V_{i=1}\theta_i^{W_{ni}} \prod^V_{i=1}\theta_i^{\gamma_{\theta_i}-1} \\& \propto \prod^V_{i=1}\theta_i^{W_{ni}+\gamma_{\theta_i}-1} \\\end{split}\end{equation}\] 然后从一篇文章推广到某类下的所有文章,我们有 \[\begin{equation} P(\theta_x|\mathbb{C}_x;\gamma_\theta) \propto \prod^V_{i=1}\theta_{x,i}^{\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i}-1} \end{equation}\] 最后,我们把所有的因式都乘起来,再令\(\mu=<\gamma_{\pi_1},\gamma_{\pi_0},\gamma_{\theta}>\),写出简化后的全联合概率: \[\begin{equation} P(\mathbb{C},\mathbf{L},\pi,\theta_0,\theta_1;\mu) \propto \pi^{C_1+\gamma_{\pi_1}-1}(1-\pi)^{C_0+\gamma_{\pi_0}-1} \prod^V_{i=1}\theta_{0,i}^{\mathcal{N}_{\mathbb{C}_0}+\gamma_{\theta_i}-1} \theta_{1,i}^{\mathcal{N}_{\mathbb{C}_1}+\gamma_{\theta_i}-1} \end{equation}\]
为了进一步地简化模型,我们可以对参数\(\pi\)求积分,从而消去这个参数。 \[\begin{equation} \begin{split}& P(\mathbb{C},\mathbf{L},\theta_0,\theta_1;\mu)\\ =&\int_\pi P(\mathbb{C},\mathbf{L},\pi,\theta_0,\theta_1;\mu) d\pi \\=&\int_\pi P(\pi|\gamma_{\pi_1},\gamma_{\pi_0})P(\mathbf{L}|\pi)P(\theta_0|\gamma_{\theta})P(\theta_1|\gamma_{\theta})P(\mathbb{C}_0|\theta_0,\mathbf{L})P(\mathbb{C}_1|\theta_1,\mathbf{L}) d\pi \\ =&P(\theta_0|\gamma_{\theta})P(\theta_1|\gamma_{\theta})P(\mathbb{C}_0|\theta_0,\mathbf{L})P(\mathbb{C}_1|\theta_1,\mathbf{L}) \int_\pi P(\pi|\gamma_{\pi_1},\gamma_{\pi_0})P(\mathbf{L}|\pi) d\pi \\\end{split}\end{equation}\] 这里我们对积分式子内的\(\pi\)求积分 \[\begin{equation} \begin{split}&\int_\pi P(\pi|\gamma_{\pi_1},\gamma_{\pi_0})P(\mathbf{L}|\pi) d\pi \\ =&\frac{\Gamma(\gamma_{\pi_1}+\gamma_{\pi_0})}{\Gamma(\gamma_{\pi_1})\Gamma(\gamma_{\pi_0})}\pi^{\gamma_{\pi_1}-1}(1-\pi)^{\gamma_{\pi_0}-1} \pi^{C_1}(1-\pi)^{C_0} d\pi \\=& \frac{\Gamma(\gamma_{\pi_1}+\gamma_{\pi_0})}{\Gamma(\gamma_{\pi_1})\Gamma(\gamma_{\pi_0})} \int_\pi \pi^{C_1+\gamma_{\pi_1}-1}(1-\pi)^{C_0+\gamma_{\pi_0}-1} d\pi \\\end{split}\end{equation}\] 要注意这里式子右边的积分部分其实是尚未归一化的参数为\(C_1+\gamma_{\pi_1}\)和\(C_0+\gamma_{\pi_0}\) 的Beta分布求积分,所以我们只需要先补上Beta(\(C_1+\gamma_{\pi_1}\),\(C_0+\gamma_{\pi_0}\))归一化的常数项即可: \[\begin{equation}\frac{\Gamma(C_0+C_1+\gamma_{\pi_1}+\gamma_{\pi_0})}{\Gamma(C_1+\gamma_{\pi_1})\Gamma(C_0+\gamma_{\pi_0})}\end{equation}\] 令\(N=C_0+C_1\),我们得到(注意这里应为Beta归一化的常数的倒数!!!原文中写反了) \[\begin{equation} \int_\pi P(\pi|\gamma_{\pi_1},\gamma_{\pi_0})P(\mathbf{L}|\pi) d\pi=\frac{\Gamma(\gamma_{\pi_1}+\gamma_{\pi_0})}{\Gamma(\gamma_{\pi_1})\Gamma(\gamma_{\pi_0})} \frac{\Gamma(C_1+\gamma_{\pi_1})\Gamma(C_0+\gamma_{\pi_0})}{\Gamma(C_0+C_1+\gamma_{\pi_1}+\gamma_{\pi_0})} \end{equation}\] 最后得出 \[\begin{equation}P(\mathbb{C},\mathbf{L},\theta_0,\theta_1;\mu) \propto \frac{\Gamma(\gamma_{\pi_1}+\gamma_{\pi_0})}{\Gamma(\gamma_{\pi_1})\Gamma(\gamma_{\pi_0})} \frac{\Gamma(C_1+\gamma_{\pi_1})\Gamma(C_0+\gamma_{\pi_0})}{\Gamma(C_0+C_1+\gamma_{\pi_1}+\gamma_{\pi_0})}\prod^V_{i=1}\theta_{0,i}^{\mathcal{N}_{\mathbb{C}_0}(i)+\gamma_{\theta_i}-1} \theta_{1,i}^{\mathcal{N}_{\mathbb{C}_1}(i)+\gamma_{\theta_i}-1}\end{equation}\] 这里很容易想到的是,既然我们可以通过对\(\pi\)求积分来简化联合分布,为什么不用这种方法把里面的参数全积分了呢?详细请见下篇的解释。
根据Gibbs 抽样的定义,我们每次都从条件分布中抽样出\(Z_i\)的新值: \[\begin{equation} P(Z_i|z_1^{(t+1)},\ldots,z^{(t+1)}_{i-1},z^{(t)}_{i+1},\ldots,z^{t}_k) \end{equation}\] 替换成具体的例子,在分配\(L_1^{(t+1)}\)的值时,我们需要计算条件分布 \[\begin{equation}P(L_1|L_2^{(t)},\ldots,L_N^{(t)},\mathbb{C},\theta_0^{(t)},\theta_1^{(t)};\mu)\end{equation}\] 然后我们算\(L_2{(t+1)}\)的值, \[\begin{equation}P(L_2|L_1^{(t+1)},L_3^{(t)},\ldots,L_N^{(t)},\mathbb{C},\theta_0^{(t)},\theta_1^{(t)};\mu)\end{equation}\] 以此类推直到计算完\(L_N^{(t+1)}\)为止。然后我们计算\(\theta_0\)的值, \[\begin{equation}P(\theta_0^{(t+1)}|L_1^{(t+1)},L_2^{(t+1)},\ldots,L_N^{(t+1)},\mathbb{C},\theta_1^{(t)};\mu)\end{equation}\] 最后是\(\theta_1\) \[\begin{equation}P(\theta_1^{(t+1)}|L_1^{(t+1)},L_2^{(t+1)},\ldots,L_N^{(t+1)},\mathbb{C},\theta_0^{(t)};\mu)\end{equation}\] 在循环\(t\)开始的时候,我们拥有一些信息,这些信息包括:每个文档中词的数目,标签为0的文档数,标签为1的文档数,所有标签为0的文档的词数目,所有标签为1的文档的词数目,每个文档的当前标签,当前的\(\theta_1\)和\(\theta_0\)值,等等。当我们想得到文档\(j\)的新标签时,我们暂时地移除所有当前文档的信息(包括词数目和标签信息),然后通过余下的信息得出\(L_j=0\) 的条件概率和\(L_j=1\)的条件概率,最后根据这俩概率的相对比例采样得到新的\(L_j{(t+1)}\)。对\(\theta\)采样时也是如此。
接下来我们具体地看看那如何对文档标签采样。根据之前的条件概率公式,我们得到 \[\begin{equation} \begin{split} P(L_j|\mathbf{L}^{(-j)},\mathbb{C}^{(-j)},\theta_0,\theta_1;\mu)& =\frac{P(L_j,W_j,\mathbf{L}^{(-j)},\mathbb{C}^{(-j)},\theta_0,\theta_1;\mu)}{P(\mathbf{L}^{(-j)},\mathbb{C}^{(-j)},\theta_0,\theta_1;\mu)} \\ &=\frac{P(\mathbf{L},\mathbb{C},\theta_0,\theta_1;\mu)}{P(\mathbf{L}^{(-j)},\mathbb{C}^{(-j)},\theta_0,\theta_1;\mu)} \end{split} \end{equation}\] \(\mathbf{L}^{(-j)}\)是除了\(L_j\)外所有的文档标签,然后\(\mathbb{C}^{(-j)}\)是除了\(W_j\)外所有的文档集合。这个分布有2个结果,\(L_j=0\)或\(L_j=1\)。 要注意这里分子就是式(32)中的全联合概率分布。而分母仅仅除去了文档\(W_j\) 的信息。然后我们来看看除去了该文档对整个式子造成了什么影响。
式(32)中第一个因式\(\frac{\Gamma(\gamma_{\pi_1}+\gamma_{\pi_0})}{\Gamma(\gamma_{\pi_1})\Gamma(\gamma_{\pi_0})}\)是个常数,与\(W_j\)无关,分子分母都有一个,所以计算的时候被约掉了。第二个式子是 \[\begin{equation} \frac{\Gamma(N+\gamma_{\pi_1}+\gamma_{\pi_0})}{\Gamma(C_1+\gamma_{\pi_1})\Gamma(C_0+\gamma_{\pi_0})} \end{equation}\] 现在我们来看看去掉了一个文档\(W_j\),发生了什么变化。首先,语料的大小从\(N\)减小到\(N-1\)。 如果文档\(L_j=0\),那么\(C_0^{(-j)}=C_0-1,C_1^{(-j)}=C_1\)。反之如果文档\(L_j=1\),那么\(C_1^{(-j)}=C_1-1,C_0^{(-j)}=C_0\)。我们令\(x \in {0,1}\)这样就可以统一以上的情况,\(C_x^{(-j)}=C_x-1\)。然后我们重写分子和分母的这两个式子,从 \[\begin{equation} \frac{\frac{\Gamma(C_1+\gamma_{\pi_1}}{\Gamma(N+\gamma_{\pi_1}+\gamma_{\pi_0}))\Gamma(C_0+\gamma_{\pi_0})}}{\frac{\Gamma(C_1^{(-j)}+\gamma_{\pi_1})\Gamma(C_0^{(-j)}+\gamma_{\pi_0})}{\Gamma(N+\gamma_{\pi_1}+\gamma_{\pi_0}-1)}} \end{equation}\] 到 \[\begin{equation} \frac{\Gamma(C_x+\gamma_{\pi_x})\Gamma(N+\gamma_{\pi_1}+\gamma_{\pi_0}-1)}{\Gamma(N+\gamma_{\pi_1}+\gamma_{\pi_0})\Gamma(C_x+\gamma_{\pi_x}-1)} \end{equation}\] 利用伽马函数\(\Gamma(a+1)=a\Gamma(a)\)的性质,我们简化上面的式子最终得到 \[\begin{equation} \frac{C_x+\gamma_{\pi_x}-1}{N+\gamma_{\pi_1}+\gamma_{\pi_0}-1} \end{equation}\] (注意!!!这里原文又写错了,分子项少减了一个1)这样我们就把伽马函数消去了。再来看剩下的式子 \[\begin{equation} \prod^V_{i=1}\theta_{0,i}^{\mathcal{N}_{\mathbb{C}_0}(i)+\gamma_{\theta_i}-1} \theta_{1,i}^{\mathcal{N}_{\mathbb{C}_1}(i)+\gamma_{\theta_i}-1} \end{equation}\] 当我们去掉了文档\(W_j\)之后,可以发现文档不属于的另一类是不会有变化的,会上下约掉。而文档属于的那一类,\(C_x^{(-j)}=C_x-1\),与文档\(W_j\)无关的都被約掉,只剩下\(W_j\)中的词,最后 \[\begin{equation} \prod^V_{i=1} \frac{\theta_{x,i}^{\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i}-1}}{\theta_{x,i}^{\mathcal{N}_{\mathbb{C}_x^{(-j)}}(i)+\gamma_{\theta_i}-1}}=\prod^V_{i=1} \theta_{x,i}^{W_{ji}} \end{equation}\] 然后把(42)式和(44)式相乘,就得到了最后的公式,对于\(x\in{0,1}\) \[\begin{equation} P(L_j=x|\mathbf{L})^{(-j)},\mathbb{C}^{(-j)},\theta_0,\theta_1;\mu)=\frac{C_x+\gamma_{\pi_x}-1}{N+\gamma_{\pi_1}+\gamma_{\pi_0}-1}\prod^V_{i=1} \theta_{x,i}^{W_{ji}} \end{equation}\] 这个式子清楚地表现了标签是如何被选择的。这个式子中,前半部分其实只有\(C_x\)是变量,所以如果\(C_0\)大,则算出来的\(P(L_j=0)\)的概率就会大一点,所以下一次Lj的值就会倾向于C0,反之就会倾向于C1。 而后半部分,是在判断当前\(\theta\)参数的情况下,这些词\(W_j\)是否符合该参数所对应的分布(表现为似然值更大),然后确定整个文档是更倾向于C0还是C1。
最后(终于结束了!),我们从得到的条件概率中抽样:
令\(value0\)为式(34)\(x=0\)时的值。
令\(value1\)为式(34)\(x=1\)时的值。
令概率分布为\(<\frac{value0}{value0+value1},\frac{value1}{value0+value1}>\)。
根据这个分布进行贝努利实验(投两边概率不同的硬币)得到新的\(L_j^{(t+1)}\)的值。
接下來看看如何对\(\theta_0\)和\(\theta_1\)采样。因为这俩参数都是相互独立的,我们再一次删去他们的下标,统一地看做\(\theta\)。将式(25)中与当前\(\theta\)无关的参数删去,我们可以观察到 \[\begin{equation}P(\theta|\mathbb{C},\mathbf{L});\mu) \propto P(\mathbb{C},\mathbf{L}|\theta)P(\theta|\mu)\end{equation}\] 其实这时候式子里只剩下\(\theta_{x,i}^{\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i}-1}\)而已。可以看到,因为先验分布\(P(\theta|\mu)\)是共轭的Dirichlet分布,所以后验分布也是Dirichlet分布,只是每个词项\(i\)的参数变成了\(\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i}\)而已,我们定义\(V\) 维的向量\(\mathbf{t}\),令\(t_i=\mathcal{N}_{\mathbb{C}_x}(i)+\gamma_{\theta_i}\),就有 \[\begin{equation}\theta \sim Dirichlet(\mathbf{t})\end{equation}\] 那么如何从一个Dirichlet分布采样出\(\theta\)呢?(见的11.1.2的Reject Sampling)为了从参数为\(<\alpha_1,\ldots,\alpha_V>\)的\(V\)维Dirichlet分布中抽样出一个随机向量\(\mathbf{a}=<a_1,\ldots,a_V>\),我们只要从\(V\)个伽马分布中各自采样一个独立的样本\(y_1,\ldots,y_V\),其中每个伽马分布的密度函数为 \[\begin{equation}Gamma(\alpha_i,1)=\frac{y_i^{\alpha_i-1}e^{-y_i}}{\Gamma(\alpha_i)}\end{equation}\] 然后令\(a_i=y_i/\sum^V_{j=1}y_j\)即可。
我们可以利用已经被标签过的文档来,只需要不对这些文档采样新标签即可。这些被标注的文档会作为背景信息为算法服务。
需要注意的是每次新的标签\(L_j\)产生的时候,都会对接下来的文档标签数目统计产生影响,这就是Gibbs Sampler的本质。
Gibbs Sampling在每个循环都会产生变量的值,像之前提到过的那样,在理论上,变量\(Z_i\)可以通过\(T\)次获得的值近似 \[\begin{equation}\frac{1}{T}\sum^T_{t=1}z^{(t)}_i\end{equation}\] 但是实际中一般不直接这样用。
根据选择初始值的不同,Gibbs sampler需要一定的迭代次数才能保证点\(<z_1^{t},z_2^{t},\ldots,z_k^{t}>\)都是从马尔科夫链的平稳分布中生成的(换句话说就是马尔科夫链需要一定的次数才能收敛)。为了避免在这之前的估计对结果产生的影响,一般都丢弃\(t<B\)之前的结果,之前的阶段就被称为“burn-in”阶段,所以取平均值的时候是从\(B+1\)次到\(T\)次的。
式(38)里的近似假设\(Z_i\)的那些样本都是相互独立的,而事实上我们知道他们不是,因为新的点都是从前面的点所给的条件所生成的。这个问题被称作自相关(autocorrelation)。为了避免这个问题,很多Gibbs Sampling在实现的时候取每\(L\)个值的平均值,这个\(L\)被称作滞后(lag,我也不知道怎么翻译)。具体的探讨请见原文。
还有多链问题和超参数的选择问题,以及原文推荐的一些有用的文章,这里就不详述了。
这篇文章基本上是来自于《Gibbs Sampling for the UniniTiated》,说是笔记其实和翻译也差不多了。
整个结构分为上中下三部分:
这篇是上部分,介绍基础参数估计和Gibbs Sampling概念。
很多概率模型的算法并不需要使用积分,只要对概率求和就行了(比如隐马尔科夫链的Baum-Welch算法),那么什么时候用到求积分呢?—— 当为了获得概率密度估计的时候,比如说根据一句话前面部分的文本估计下一个词的概率,根据email的内容估计它是否是垃圾邮件的概率等等。为了估计概率密度,一般有MLE(最大似然估计),MAP(最大后验估计),bayesian estimation(贝叶斯估计)三种方法。
这里举一个例子来讲最大似然估计。假设我们有一个硬币,它扔出正面的概率\(\pi\)不确定,我们扔了10次,结果为HHHHTTTTTT(H为正面,T为反面)。利用最大似然估计的话,很容易得到下一次为正面的概率为0.4,因为它估计的是使观察数据产生的概率最大的参数。
令\(\chi=\{HHHHTTTTTT\}\)代表观察到的数据,\(y\)为下一次抛硬币可能的结果,估计公式如下: \[\begin{equation}\begin{split}\tilde{\pi}_{MLE} &=\arg \max \limits_{\pi}P(\chi|\pi) \\P(y|\chi) & \approx \int_{\pi} p(y|\tilde{\pi}_{MLE})P(\pi|\chi) d\pi = p(y|\tilde{\pi}_{MLE})\end{split}\end{equation}\]
最大似然估计是直接最大化似然函数对参数进行估计。如果我们有一些关于硬币的先验知识的话(比如我们知道参数\(\pi\)服从某个形式的概率分布),那么根据贝叶斯公式,我们就能求得观察到数据之后\(\pi\)的后验概率,令后验概率最大化 \[\begin{equation} \begin{split}\tilde{\pi}_{MAP} & =\arg \max \limits_{\pi}P(\pi|\chi) \\ & =\arg \max \limits_{\pi} \frac{P(\chi|\pi)P(\pi)}{P(\chi)} \\ & =\arg \max \limits_{\pi} P(\chi|\pi)P(\pi) \\P(y|\chi) & \approx \int_{\pi} p(y|\tilde{\pi}_{MAP})P(\pi|\chi) d\pi =p(y|\tilde{\pi}_{MAP}) \\\end{split}\end{equation}\] 这里\(P(\chi)\)与参数\(\pi\)无关就省略了。假设我们取一个令\(P(\pi)\)的期望为0.5的先验分布,那么之后观察到的数据将对之前假设硬币正反概率一样的bias 产生影响。
首先我们可以看到,最大似然估计和最大后验估计都是基于一个假设,即把待估计的参数\(\pi\)看做是一个固定的值,只是其取值未知。而最大似然是最简单的形式,其假定参数虽然未知,但是是确定值,就是找到使得样本对数似然分布最大的参数。而最大后验,只是优化函数为后验概率形式,多了一个先验概率项。 而贝叶斯估计和二者最大的不同在于,它假定参数是一个随机的变量,不是确定值。在样本分布\(P(\pi|\chi)\) 上,\(\pi\)是有可能取从0到1的任意一个值的,只是取到的概率不同。而MAP和MLE只取了整个概率分布\(P(\pi|\chi)\) 上的一个点,丢失了一些观察到的数据\(\chi\)给予的信息(这也就是经典统计学派和贝叶斯学派最大的分歧所在。)
为了利用所有的信息,我们可以对参数的概率分布求期望值。对于一个离散型变量\(z\)的函数\(f(z)\)的期望一般是这样求得 \[\begin{equation} E[f(z)]=\sum_{z\in\mathcal{Z}}f(z)p(z) \end{equation}\] 这里\(\mathcal{Z}\)是所有\(z\)可能取的值,\(p(z)\)是取这个值的概率。如果\(z\) 是个连续型的变量,期望就是求积分而不是求和了: \[\begin{equation} E[f(z)]=\int f(z)p(z) dz \end{equation}\] 对于这里的例子来说,\(z=\pi\),函数\(f(z)=P(y|\pi)\)(这里文章讲的不清楚,这个\(P(y|\pi)\)是模型生成该结果的概率,而\(P(\pi|\chi)\)是使用这个模型的概率,比如说有3个模型,第一个模型生成该数据的概率为0.5,第二个为0.4,第三个为0.3,需要考虑模型的结果),需要取期望的概率分布为\(P(\pi|\chi)\),所以整个期望是模型的所有分布上生成该数据的概率 \[\begin{equation} P(y|\chi)= \int P(y|\pi)P(\pi|\chi)d \pi \end{equation}\] 对\(P(\pi|\chi)\)我们使用贝叶斯公式 \[\begin{equation} P(\pi|\chi)=\frac{P(\chi|\pi)P(\pi)}{P(\chi)}=\frac{P(\chi|\pi)P(\pi)}{\int_\pi P(\chi|\pi)P(\pi)d \pi} \end{equation}\] 要注意这里的后验概率是个函数,而不是像之前的MAP一样是个值,它充分考虑了\(\pi\)的先验知识和根据观察数据\(\chi\)获得的信息,并将它们联系起来。
积分存在的一个问题就是他们很难算。事实上,之前的后验概率里面的分母很可能没有解析解,这个时候就要用抽样的方法获得这个概率分布的具体形式了。
Gibbs 抽样是Markov Chain Monte Carlo(蒙特卡洛方法)的一种。所谓的蒙特卡洛方法就是模拟统计的方法,举一个例子:假设有一个正方形和它的内接圆,然后我们随机地往正方形上撒很多很多的米粒,最后统计那些在圆里面的米粒数据(记作C),然后那些在正方形里的米粒数目(记作S)。可以看到两者之比近似于圆和正方形的面积之比: \[\begin{equation} \frac{C}{S} \approx \frac{\pi(\frac{d}{2})^2}{d^2} \end{equation}\] 这样我们就可以得到\(\pi \approx \frac{4C}{S}\),这是一个典型的通过模拟来积分的例子,这里的圆面积是通过无数个点加和来逼近真实面积的。
在这个例子里,我们是对一个均匀分布采用来求值。回到刚才我们的问题,是要计算期望值\(E_{p(x)}[f(x)]\),这里我们未知的是概率分布\(p(x)\),假设它不是一个均匀分布,而且很难获得解析解。 图2给出了\(f(z)\)和\(p(z)\)的例子。从概念上来说,之前的积分应该是在\(z\)的所有空间上对\(f(z)p(z)\)加和所得到的结果。换一种角度来看,如果我们从\(p(z)\)随机依次抽取\(N\) 个点\(z^{(0)},z^{(1)},z^{(2)},\ldots,z^{(N)}\),当\(N\)趋向于无穷的时候,我们可以通过无数个采样获得的点\(z\) 来逼近它真实的概率分布,就有 \[\begin{equation} E_{p(x)}[f(x)]=\lim_{N\rightarrow \infty}\frac{1}{N}\sum^{N}_{t=1}f(z^{(t)}) \end{equation}\] 当\(z\)是离散变量的时候,\(f(z)\)的期望就是加权平均,每个\(z\)的权值就是它的概率。当\(z\)是连续变量是,我们也可以用类似的想法,对于所有采样得到\(z\),我们都用观察到的频率\(\frac{1}{N}count(z)(N \rightarrow \infty)\)代替真实的概率\(p(z)\),所以\(p(z)\)就隐含在采样得到的样本之中(这个想法是直观上的,因为实际上连续变量统计样本\(z\)出现的次数\(count(z)\)是没有意义的)。很容易可以发现,在整个\(p(z)\) 的分布上,概率大的地方被采样的次数也多。
上面的式子\(N\)是趋向于无穷大的,我们也可以使用有限数目\(T\)的点来获得一个比较近似的值。 \[\begin{equation} E_{p(x)}[f(x)]\approx \frac{1}{T}\sum^{T}_{t=1}f(z^{(t)}) \end{equation}\] 好,现在我们有近似获得积分值的方法了。剩下的问题就是,如何根据\(p(z)\)采样出样本\(z^{(0)},z^{(1)},z^{(2)},\ldots,z^{(T)}\)。这正好是模拟统计所研究的问题,所以有很多很多的采样方法,比如rejection sampling ,adaptive sampling, important sampling等等(见PRML),而我们采样的方法把\(z\) 看做状态空间中的点,用从\(z^{(0)}\) 转移到\(z^{(1)}\) 再转移到\(z^{(2)}\) 这样的方式遍历\(z\) 的状态空间,见图2。
可以看到\(Z\)的状态转移是一条马尔科夫链,这里\(g\)是一个根据转移概率\(P_{trans}(z^{(t+1)}|z^{(0)},z^{(1)},\ldots,z^{(t)})\)来决定下一个状态是什么的函数。由Markov Chain 的性质,我们可以知道下一个状态\(z^{(t+1)}\) 仅仅取决于当前状态\(z^{(t)}\)。 \[\begin{equation} P_{trans}(z^{(t+1)}|z^{(0)},z^{(1)},\ldots,z^{(t)})=P_{trans}(z^{(t+1)}|z^{(t)}) \end{equation}\] 而Markov Chain Monte Carlo方法的核心就在于如何设计这个函数\(g\)使得访问状态\(z\)的概率刚好是\(p(z)\),这就需要转移概率\(P_{trans}\)满足一定的条件(平稳细致条件,详见PRML的第四章),而Gibbs sampling就是满足该条件的抽样方法之一。
假设每个点 \(z=<z_1^{0},\ldots,z_k^{0}>(k>1)\)。Gibbs Sampling 每次在确定下一个状态的时候,并不是一次性地确定所有维度上的值,而是选取一个维度,通过剩下的\(k-1\)个维度来确定这个维度的值,见图2。
通过条件概率的定义我们可以得到 \[\begin{equation} \begin{split} & P(Z_i|z_1^{(t+1)},\ldots,z^{(t+1)}_{i-1},z^{(t)}_{i+1},\ldots,z^{t}_k) \\=&\frac{P(z_1^{(t+1)},\ldots,z^{(t+1)}_{i-1},z^{(t)}_{i},z^{(t)}_{i+1},\ldots,z^{(t)}_k)}{P(z_1^{(t+1)},\ldots,z^{(t+1)}_{i-1},z^{(t)}_{i+1},\ldots,z^{(t)}_k)}\\\end{split} \end{equation}\] 注意右式的分子部分是全联合概率,而分母部分少了\(z^{(t)}_i\)这个维度,也就是我们要估计的这个维度。把这个操作对每个维度都采样一遍我们就得到了下一个新的点\(z^{(t+1)}=g(z^{(t)})=<z_1^{(t+1)},\ldots,z_k^{(t+1)}>\)。要注意的是每次新采样得到的值都可以直接用于下一次采样,所以公式里\(z^{(t)}_{i+1}\)前面的维度上标都是\(t+1\),因为他们都刚刚被采样过。
一般文章对Gibbs Sampling的介绍也就到此为止了,这样的介绍对新手来说(比如我- -)太难了,讲了也不会用。比如以下问题:
对特定的模型Gibbs Sampling条件概率的分布采样到底是咋做的?
连续型的参数变量如何处理?
只做\(T\)次循环怎么确保获得你想要的期望值?
于是这篇文章又生动活泼地举了一个从朴素贝叶斯模型生成Gibbs 采样器的例子。(见中篇)
参考文献:
《Pattern Recognition and Machine Learning》
《LDA数学八卦》
http://www.xperseverance.net/blogs/2013/03/1682/
《Gibbs Sampling for the UniniTiated》
当然只仅仅是默认支持的语言,还有更多的语言需要自己改代码添加(支持语言列表)。 添加的方法请见Adding A New Brush (Language)。
]]>
|
|
注意:
pluskid大神这里最后返回的是px,我觉得非常奇怪,因为PRML里对点做hard assignment时是根据后验概率来判别的。于是我在大神博客上问了一下,他的解释是最大似然和最大后验的区别,前者是挑x被各个模型产生的概率最大的那个,而后者加上了先验知识,各有道理。一句话就茅塞顿开,真大神也~ 然后调用该函数对数据进行聚类,要是数据是二维的或三维的,顺便画个图。
|
|
下面是对鸢尾花数据集聚类的结果。选了部分维度画图 二维图: 三维图:
]]>首先求第\(l\)个模型的\(\mu_l\),对式子1求\(\mu_l\)的偏导,得到式子2: \[\begin{split}& =\nabla_{\mu_l} \sum^m_{i=1}\sum^k_{j=1}w^{(i)}_j\log{\frac{1}{(2\pi)^{D/2}|\Sigma|^{1/2}}\exp(-\frac{1}{2}(x^{(i)}-\mu_j)^T\Sigma_j^{-1}(x^{(i)}-\mu_j))\cdot\phi_j} \\&= -\nabla_{\mu_l}\sum^m_{i=1}\sum^k_{j=1}w^{(i)}_j\frac{1}{2}(x^{(i)}-\mu_j)^T\Sigma_j^{-1}(x^{(i)}-\mu_j) \\&= \frac{1}{2} \sum^m_{i=1}w^{(i)}_l \nabla_{\mu_l}(2\mu_l^T\Sigma^{-1}_l x^{(i)} - \mu_l^T\Sigma^{-1}_j\mu_l)\\&=\sum^m_{i=1}w^{(i)}_l(\Sigma^{-1}x^{(i)}-\Sigma^{-1}\mu_l)\end{split}\] 以上式子推导所需的前提知识有:
\(\Sigma_j\)是对称阵(这里其实\(\Sigma_j\)不一定是对称的,但是在计算之后他和对称阵的效果是一样的,这里CS229上没讲清楚,详见pluskid大神的Regularized Gaussian Covariance Estimation)。因为\(\Sigma_j\)是对称阵,易得\(\Sigma_j^{-1}\)也是对称阵。
\(1 \times 1\)矩阵的转置不变。因为$ x^{(i)} ^{-1}_l _l $是\(1 \times 1\)的矩阵,所以 \[x^{(i)} \Sigma^{-1}_l \mu_l=(x^{(i)} \Sigma^{-1}_l \mu_l)^T=\mu_l^T\Sigma^{-1}_l x^{(i)}\]
矩阵求导的公式(参考1和2)。设\(x,u,v\)为列向量,有以下式子成立: \[\begin{split}\frac{d(x^T)}{dx} &=I \\\frac{d(Ax)^T}{dx} &=A^T \\\frac{d(u^Tv)}{dx} &=\frac{d(u^T)}{dx}v+\frac{d(v^T)}{dx}u^T \\\end{split}\] 所以 \[\begin{split}\frac{d (\mu_l^T\Sigma^{-1}_j\mu_l)}{d u_l}&= \frac{d (\mu_l^T)}{d \mu_l} \Sigma^{-1}_j\mu_l+\frac{d (\Sigma^{-1}_j\mu_l)^T}{d \mu_l} (\mu_l^T)^T \\&= 2 \mu_l^T\Sigma^{-1}_j\mu_l\end{split}\]
令之前的式子2等于0,我们解得 \[\mu_l=\frac{\sum^m_{i=1}w^{(i)}_l x^{(i)}}{\sum^m_{i=1}w^{(i)}_l}\]
然后我们求\(\phi_j\),这个式子1对它偏导之后就形式更加简单: \[\sum^m_{i=1}\sum^k_{j=1} w^{(i)}_j\log{\phi_j}\] 但是需要注意的是,\(\phi_j\)存在一个约束条件\(\sum_{j=1}^K \phi_j =1\),它代表的是取\(k\)个高斯模型中的一个的概率总和为1。为了求得条件极值,我们引入拉格朗日乘子\(\beta\), 设拉格朗日函数为 \[\mathcal{L(\phi)}= \sum^m_{i=1}\sum^k_{j=1} w^{(i)}_j\log{\phi_j}+\beta(\sum^k_{j=1}(\phi_j-1)\] 求导等于0之后我们得到 \[\phi_j=-\frac{\sum^m_{i=1} w^{(i)}_j}{\beta}\] 事情到这里还没完,这个\(\beta\)还能求出来,因为后验概率\(w^{(i)}_j\)之和为1,所以 \[\sum_{j=1}^k \phi_j=-\frac{\sum^m_{i=1} \sum_{j=1}^k w^{(i)}_j}{\beta}=-\frac{\sum^m_{i=1}1}{\beta}=-\frac{m}{\beta}=1\] 得到\(\beta=-m\),最后有 \[\phi_j=\frac{1}{m}\sum^m_{i=1} w^{(i)}_j\]
最后,我们来求$ _j\(。CS229的教材上说求这个\)_j$是“entirely straightforward”,真是高估了像我这样数学不好的人- -。
对式子1求偏导,我们有式子3: \[\begin{split}&= -\nabla_{\Sigma_j}\sum^m_{i=1}w^{(i)}_j(\frac{1}{2}\log{|\Sigma_j|}- \frac{1}{2}(x^{(i)}-\mu_j)^T\Sigma_j^{-1}(x^{(i)}-\mu_j))\\&= \sum^m_{i=1}w^{(i)}_j\Sigma^{-1}_j- \sum^m_{i=1}w^{(i)}_j\Sigma_j^{-1}(x^{(i)}-\mu_j)(x^{(i)}-\mu_j)^T\Sigma_j^{-1}\end{split}\]
1. 需要矩阵求导公式:(wikipedia中对multivariate normal distribution的解释(参考3)以及其第6篇参考文献(参考4),<del>其实不用找,PRML的附录C里有。。。</del>)
\[\begin{split}\frac{ \partial }{\partial \Sigma}\log{|\Sigma|} & =\Sigma^{-1} \\\frac{ \partial }{\partial \Sigma}(x-\mu)^T\Sigma^{-1}(x-\mu) & =-\Sigma^{-1}(x-\mu)^T(x-\mu)\Sigma^{-1} \\\end{split}\] 第二条公式应该是根据以下两个公式推出来的: \[\begin{split}\frac{d(a^T Xb)}{d X} &=ab^T \\\frac{d(Y^{-1})}{d Y} &=-Y^{-1}\frac{d Y}{ d X}Y^{-1} \\\end{split}\] 令式子3等于0,我们求得
\[\Sigma_j=\frac{\sum^m_{i=1}w^{(i)}_j(x^{(i)}-\mu_j)(x^{(i)}-\mu_j)^T}{\sum^m_{i=1}w^{i}_j}\]
把他们写在一起,就得到了高斯混合模型的参数估计: \[ \begin{split} & \mu_j=\frac{\sum^m_{i=1}w^{(i)}_jx^{(i)}}{\sum^m_{i=1}w^{(i)}_j} \\& \phi_j=\frac{1}{m}\sum^{m}_{i=1}w^{(i)}_j \\& \Sigma_j=\frac{\sum^m_{i=1}w^{(i)}_j(x^{(i)}-\mu_j)(x^{(i)}-\mu_j)^T}{\sum^m_{i=1}w^{i}_j} \\\end{split}\] 参考文献: 1.矩阵求导 2.Matrix Reference Manual 3.Estimation of covariance matrices 4.^ Dwyer, Paul S. (June 1967). “Some applications of matrix derivatives in multivariate analysis”. Journal of the American Statistical Association (Journal of the American Statistical Association, Vol. 62, No. 318) 62 (318): 607–625. doi:10.2307/2283988. JSTOR 2283988. 5.stanford的CS229课程
]]>社区,从直观上来看,是指网络中的一些密集群体,每个社区内部的结点间的联系相对紧密,但是各个社区之间的连接相对来说却比较稀疏(图1,当然社区的定义不止有这一种)。这样的社区现象被研究已经很多年了,最早期的记录甚至来自于80年前。
比较经典的社区研究案例包括对空手道俱乐部(karate club),科学家合作网络(Collaboration network) 和斑马群体(zebras) 的社交行为研究等(见图2),其中著名的空手道俱乐部社区已经成为通常检验社区发现算法效果的标准(benchmark)之一。
随着互联网和在线社交网站的兴起,在Twitter,Facebook,Flickr这样的用户生成内容(UCG)网站上使用社区发现的技术已经成为热潮。在这些社区中用户相互的交流与反馈,能为传统的社区带来丰富的内容信息和新的结构,从而使社区发现有了新的发展。
因为社区发现的算法很多很多,下图列出了比较核心的社区发现算法介绍(在参考1给的目录上稍作修改,包含但不限于,五花八门的太多了):
对上图所涉及的算法作简单介绍:
社区可以看做密集子图结构,使用图分割算法来解决。图分割问题的目标是把图中的节点分成\(g\)个预定大小的群组,这些群组之间的边数目最小,这个问题是NP-hard 的。
早期的分割都是二分图,社区发现也是基于二分的,遇到多分的情况就把其中一个子图再分割。比较经典的有谱二分法,利用拉普拉斯矩阵的第二小特征值\(\lambda_2\)对社区二分类,这其实是属于谱方法的一种特例。
KL算法通过基于贪婪优化的启发式过程把网络分解为2个规模已知的社区。该算法为网络的划分引入一个增益函数,定义为两个社区内部的边数与两个社区边数之间的差,寻求Q的最大划分办法。
基于最大流的算法是G.W.Flake提出的。他给网络加了虚拟源节点\(s\)和终点节点\(t\),并证明了经过最大流算法之后,包含源点\(s\)的社区恰好满足社区内节点链接比与社区外的链接要多的性质。
当社区的边非常密集,数目远大于点时,图分割可能就不太好使了,这时候社区发现可能更接近于聚类。我们把社区发现看做一组内容相似的物体集合,使用聚类算法。和图中的社区发现相比,图中的社区点与点之间可以用边来表示联系的紧密,而聚类中的社区,需要定义点之间的相似度,比如说根据邻接关系定义: \[d_{ij}=\sqrt{\sum_{k\neq i,j}(A_{ik}-A_{jk})^2}\] 其中\(A\)为邻接矩阵,\(i\)和\(j\)的邻居越多,节点相似度越高。 聚类算法和网络发现(聚类相关的)算法可以很容易地互相转化。另外,社区发现可以是局部的,而聚类是全网络的。
层次聚类假设社区是存在层次结构的(其实不一定额,可能是中心结构),计算网络中每一对节点的相似度。 然后分为凝聚法和分裂法两种:
分裂法:找出相互关联最弱的节点,并删除他们之间的边,通过这样的反复操作将网络划分为越来越小的组件,连通的网络构成社区。
像k-means(如何弄到欧氏空间中是个问题,可以使用隐含空间模型,比如MDS),k-medoids什么的就很好,可以使用上面的相似度来聚类 。
图分割中的如 Ratio Cut和Normalized Cut其实和谱聚类是等价的(见参考3),所以谱聚类也能用在社区发现上。
这里的分裂法和层次聚类中的类似,区别是前者不计算节点相似度,而是删除是两个社区之间的关联边,这些边上的两点的相似度不一定很低。其中最著名的算法就是Girvan-Newman算法,根据以下假设:社区之间所存在的少数几个连接应该是社区间通信的瓶颈,是社区间通信时通信流量的必经之路。如果我们考虑网络中某种形式的通信并且寻找到具有最高通信流量(比如最小路径条数)的边,该边就应该是连接不同社区的通道。Girvan-Newman算法就是这样,迭代删除边介数(Edge Betweenness)最大的边。
基于谱分析的社区算法基于如下事实,在同一个社区内的节点,它在拉普拉斯矩阵中的特征向量近似。将节点对应的矩阵特征向量(与特征值和特征向量有关的都叫谱)看成空间坐标,将网络节点映射到多维向量空间去,然后就可以运用传统的聚类算法将它们聚集成社团。这种方法不可避免的要计算矩阵的特征值,开销很大,但是因为能直接使用很多传统的向量聚类的成果,灵活性很高。
模块度不仅仅作为优化的目标函数提出,它也是目前是最流行的用来衡量社区结果好坏的标准之一(它的提出被称作社区发现研究历史上的里程碑)。我们知道,社区是节点有意识地紧密联系所造成的,它内部边的紧密程度总比一个随机的网络图来的紧密一些,模块度的定义就是基于此,它表示所有被划分到同一个社区的边所占的比例,再减除掉完全随机情况时被划分到同一个社区的边所占的比例: \[Q=\sum^K_{c=1}[\frac{A(V_i,V_i)}{m}-(\frac{degree(V_i)}{2m})^2]\] 其中\(V_i\)是第\(i\)个社区,\(m\)是整个图中边的数目。模块度的一个优点是好坏与社区中点的数目无关。模块度真是个好东西,第一次对社区这个模糊的概念提出了量化的衡量标准(不过据说对于小粒度的不太准)。所以对模块度的算法优化多种多样,从贪心到模拟退火等应有尽有。
自旋模型和同步算法应该是物理学家提出来的算法(完全看不懂),话说物理学家在社区发现领域十分活跃,发了不少论文。随机游走是基于以下思想:如果存在很强的社区结构,那么随机游走器(random walker)会在社区内部停留更长的时间,因为社区内部的边密度比较高。
基于统计推断的方法包括观察到的数据集和对模型的假设。如果数据集是图,模型假设对节点之间如何联系的描述就要符合真实的图结构。
个人觉得重叠和动态社区都很难成为一个类别,因为具体算法各有不同,用共同点“重叠”或“动态”来作为一类又太广泛了,比较适合作为特征或维度来描述。 而Web社区特指Web页面相互连接而成的集合,这又是一个大类,底下有不少算法。
下面我从不同的角度来描绘社区发现算法的一些特征(叫维度比较好?),这些特征可以用来对社区发现算法进行分类:
有一些社区发现算法比如谱方法,KL算法,以及基于最大流的社区发现方法等,给出明确的的目标函数,并提出算法来最优化目标函数。 常用的优化目标函数有:
如果我们将图划分为\(S\)和\(\bar{S}=V-S\)两个部分,那么\(S\)与图中的剩下部分联系越少,说明\(S\)越独立,越有可能是一个内部紧密的社区。我们用\(cut(S)\)来表示两者 之间的联系数目: \[cut(S)=\sum_{i\in S,j\in \bar{S}}A(i,j)\] 为了避免孤立节点的产生,我们分别除以它的权值(内部度数之和),来达到相对平均一些的分割。这就是Normailized Cut: \[Ncut(S)=\frac{\sum_{i\in S,j\in \bar{S}}A(i,j)}{\sum_{i\in S}degree(i)}+\frac{\sum_{i\in S,j\in\bar{S}}A(i,j)}{\sum_{j\in \bar{S}}degree(j)}\] 连通度(conductance)也是类似的定义: \[ Conductance(S)=\frac{\sum_{i\in S,j\in \bar{S}}A(i,j)}{\min{(\sum_{i\in S}degree(i),\sum_{j\in\bar{S}}degree(j))}}\] 当涉及到多个划分\(V_1,\ldots,V_k\)时,Normalilized Cut和连通度就是它们之和。
KL目标函数旨在使两个相同大小的社区之间的边联系最小: \[KLObj(V_1,\ldots,V_k)=\sum_{i\neq j}A(V_i,V_j)\] 其中\(A(V_i,V_j)=\sum_{u \in V_i,v \in V_j}A(u,v), |V_1|=|V_2|=\ldots=|V_k|\)。
模块度在2.5已提过,这里就不说了。
对于有层次的社区发现算法来说的,比如某些二分社区算法,是通过不断递归的划分子社区来获得预定的社区数目。而某些算法,像层次聚类和MCL,基于概率模型的社区发现算法等,允许用户通过调节参数来间接控制输出社区的数目。
另一些算法,像模块度优化算法,它的社区数目是由优化函数决定的,不需要用户来设定社区的数目。
很多算法在设计的时候,并没有特别地考虑伸缩性,在面对整个Web以及大型社交网络时动辄百万甚至千万个点时效果不佳。比如GN算法,需要计算即通过每条边的最短路径数目(edge betweeness),复杂度相当高,像谱聚类算法,能处理10K个点和70M条边就不错了。
所以,有些算法比如Shingling算法等,使用的方法相对简单,从而能适合大规模的社区发现的运行要求。
所谓的局部社区发现,是指只根据临近的邻居节点发现社区结构,而不考虑全局的网络,这与全局社区发现中对图中的每一个节点都打上社区标签的做法相对应。
在整个网络图很大,数据集不能全部加载到内存时,使用局部社区发现可以只加载图的一部分,发现一个局部社区,然后迭代地调用该方法来逐一地提取社区结构。
很多社区发现算法,比如图分割算法,将整个网络划分为多个独立的社区结构。但是在现实中,许多网络并不存在绝对的彼此独立的社团结构,相反,它们是由许多彼此重叠互相关联的社团构成,比如说在社交网络中,一个人根据兴趣的不同,有可能属于多个不同的小组等。所以,很多类似派系过滤算法(CPM)这样旨在发现重叠社区的算法也被不断地提出来。
在4.1有讲,这里就不讲了。
社区发现算法常用的评价标准有:
一个大规模数据集合中检索文档的时,可把文档分成四组:系统检索到的相关文档(A),系统检索到的不相关文档(B),相关但是系统没有检索到的文档(C),不相关且没有被系统检索到的文档(D): 准确度定义为: \[pr=\frac{A}{A+C}\] 召回率定义为: \[rc=\frac{A}{A+B}\] F-measure是准确率和召回率协调之后的结果,定义为: \[PWF=\frac{2\times pr \times rc}{pr+rc}\] 同理,社区也可以用这个概念。
平均聚类纯度,average cluster purity。假设算法发现了\(C=\{C_1,\ldots,C_K\}\)个社区,我们假设社区\(C_i\)有\(n_i\)个点,每个点分别为\(\{v_{1,i},\ldots,v_{n_i,i}\}\)。令\(M_{l,i}\)为点\(v_{l,i}\) 真实归属的标签,平均聚类纯度为定义为 \[ACP=\frac{1}{k}\sum_{i=1}^k\sum_{l=1}^{n_i}\frac{\delta(dom_i\in M_{l,i})}{n_i}\] 即社区\(C_i\)中主要标签的点占社区所有点的数目比例。
首先来回顾熵的定义,在一个分布内包含的信息为熵: \[H(X)=-\sum_{x \in X}p(x)\log p(x)\] 互信息(mutual information)描述了两个分布之间的相关性 \[I(X;Y)=\sum_{y \in Y}\sum_{x \in X}p(x,y)\log(\frac{p(x,y)}{p(x)p(y)})\] 我们有 \[I(X;Y)=H(X)-H(X|Y)\] 所谓两个事件相关性的量化度量,就是在了解其中一个Y的前提下,对消除另一个X不确定性所提供的信息量。 规范化的互信息定义为 \[NMI(X;Y)=\frac{I(X;Y)}{\sqrt{H(X)H(Y)}}\] 我们将划分当做一个结点落在社区的概率分布吗,然后计算社区划分结果和真实情况的NMI值,具体例子见参考4.
很多社区算法都把社区看做静态的图,但是事实上的社交网络是随着时间逐渐演变的。这些社区如何形成和消解,它们的的动态变化该如何处理,确实是一个研究热点。
日常算法中我们都假定网络中的点和边属于同一类型。但是现实中也有很多异构网络(Heterogeneous Networks)它的点和边的类型不同。比如说IMDB网络,它的实体可能包括电影,导演,演员,而他们之间的关系也不同。如何在这样的网络上做社区发现也是一大挑战。
一般的社区发现都把整个网络当做无向图来处理。但是很多网络它的有向性比较特殊,比如说Web社区,论文之间的引用关系,以及Twitter用户之间的关注关系。简单地忽略这些网络中的方向性,会导致信息的损失,算法可能会得出错误的结果。
像前面说过的一样,新兴社交网络中的关系,不仅仅再是一条有向边,其中可以包括很多内容信息(文本,图像,地理信息),这又将社区发现带向了新的领域——如何联合这些关系和内容信息来发现社区。
伸缩性。比如说并行和分布式算法,利用GPU来运算等。
可视化。如何展示数以十亿计节点,以及如何处理动态信息。
交叉领域上的社区发现。生物学什么的。
做排名。
总而言之结论就是,社区发现(特别是社交网络上的)还是比较新的,还是有一大把理论上和实践上的开放问题可做的。(我才不信呢>_<!)
参考文献:
1. Fortunato, S. (2010). “Community detection in graphs.” Physics Reports 486(3): 75-174.
2.《 Social Network Data Analytics》第四章,DOI 10.1007/978-1-4419-8462-3_4
3.http://blog.pluskid.org/?p=287
4.《社会计算:社区发现和社会媒体挖掘》,Page 58
]]>参数的意思如图2所示:
根据模型,文章m的第n个词t是这样生成的:先从文章m的doc-topic分布中生成一个topic编号\(z_{m,n}\),在根据编号第\(z_{m,n}\)个的topic-word分布中生成这个词,总够有\(K\)个topic,所以总的概率为: \[ p(w_{m,n}=t|\vec{\theta}_m,\underline{\Phi})=\sum^K_{k=1}p(w_{m,n}=t|\vec{\phi}_k)p(z_{m,n}=k|\vec{\theta}_m)\] 如果我们写出这篇文章的complete-data的联合分布(意思就是所以变量都已知的情况下),那么式子就是这样的:
通过对\(\vec{\vartheta_m}\)(doc-topic分布)和\(\underline{\Phi}\)(topic-word分布)积分以及\(z_{m,n}\)求和,我们可以求得\(\vec{w_m}\)的边缘分布:
(实际上这个边缘分布是求不出来的,因为\(z_{m,n}\)是隐藏变量,从而导致\(\underline{\vartheta}\)与\(\underline{\Phi}\)存在耦合现象,无法积分得到。要注意联合分布和边缘分布对Z乘积与加和的区别)
因为一个语料库有很多篇文章,而且文章之间都是相互独立的,所以整个语料库的似然为 \[ p(\mathcal{W}|\vec{\alpha},\vec{\beta})=\prod^{M}_{m=1}p(\vec{w_m}|\vec{\alpha},\vec{\beta})\]
虽然LDA(latent Dirichlet allocation)是个相对简单的模型,对它直接推断一般也是不可行的,所以我们要采用近似推断的方法,比如Gibbs sampling。
Gibbs sampling是MCMC(Markov-chain Monte Carlo)算法的一种特殊情况,经常用于处理高维模型的近似推断。MCMC方法可以通过马尔科夫链的平稳分布模拟高维的概率分布\(p(\vec{x})\)。当马尔科夫链经过了burn-in阶段,消除了初始参数的影响,进入平稳状态之后,它的每次转移都能生成一个\(p(\vec{x})\)的样本。Gibbs samppling 是MCMC的特殊情况,它每次固定一个维度的\(x_i\),然后通过其他维度的数据(\(\vec{x}_{\neg i})\)生成这个维度的样本。算法如下:
choose dimension i(random by permutation)。
sample \(x_i\) from $p(x_i|_{i}) $。
为了构造Gibbs抽样,我们必须知道条件概率\(p(x_i|\vec{x}_{\neg i})\),这个概率可以通过以下公式获得: \[p(x_i|\vec{x}_{\neg i})=\frac{p(x_i,\vec{x}_{\neg i})}{p(\vec{x}_{\neg i})}=\frac{p(x_i,\vec{x}_{\neg i})}{\int{p(\vec{x})d x_i}}\] 对于那些含有隐藏变量\(\vec{z}\)的模型来说,通常需要求得他们的后验概率\(p(\vec{z}|\vec{x})\),对于这样的模型,Gibbs sampler的式子如下: \[ p(z_i|\vec{z}_{\neg i},\vec{x})=\frac{p(\vec{z},\vec{x})}{p(\vec{z}_{\neg i},\vec{x})}=\frac{p(\vec{z},\vec{x})}{\int_z{p(\vec{z},\vec{x})d x_i}}\] 当样本\(\tilde{\vec{z_r}},r\in[1,R]\)的数量足够多时,隐藏变量的后验概率可以用以下式子来估计: \[ p(\vec{z}|\vec{x})=\frac{1}{R}\sum^R_{r=1}\delta(\vec{z}-\tilde{\vec{z_r}})\] 其中Kronecker delta $()={1 $ if \(\vec{u}=0;0\) otherwise $ }$。
为了构造LDA的采样器,我们首先确定模型中的隐含变量为\(z_{m,n}\)。而参数\(\underline{\Theta}\)和\(\underline{\Phi}\)都可以用观察到的\(w_{m,n}\)和对应的\(z_{m,n}\)求积分得到((这个方法叫collapsed Gibbs Sampling,即通过求积分去掉一些未知变量,使Gibbs Sampling的式子更加简单))。贝叶斯推断的目标是分布\(p(\vec{z}|\vec{w})\),它与联合分布成正比: \[p(\vec{z}|\vec{w})=\frac{p(\vec{z},\vec{w})}{p(\vec{w})}=\frac{\prod^W_{i=1}p(z_i,w_i)}{\prod^W_{i=1}\sum^K_{k=1}p(z_i=k,w_i)}\] 这里忽略了超参数(hyperparameter)\(\vec{\alpha}\)和\(\vec{\beta}\)。可以看到分母部分(也就是\(p(\vec{w}|\vec{\alpha},\vec{\beta})\))十分难求,它包括了\(K^W\)个项的求和。所以我们使用Gibbs Sample方法,通过全部的条件分布\(p(z_i|\vec{z}_{\neg i},\vec{w})\)来模拟得到\(p(\vec{z}|\vec{w})\)。
LDA的联合分布可以写成如下的式子(要记得这是个联合分布,所以Z都是已知的,所以\(\underline{\Theta}\)和\(\underline{\Phi}\)都被积分积掉了) \[p(\vec{z},\vec{w}|\vec{\alpha},\vec{\beta})=p(\vec{w}|\vec{z},\vec{\beta})p(\vec{z}|\vec{\alpha})\] 因为式子中的第一部分与\(\alpha\)独立,第二部分与\(\beta\)独立,所以两个式子可以分别处理。先看第一个分布\(p(\vec{w}|\vec{z})\),可以从观察到的词以及其主题的多项分布中生成: \[ p(\vec{w}|\vec{z},\underline{\Phi})=\prod^W_{i=1}p(w_i|z_i)=\prod^W_{i=1}\varphi_{z_i,w_i}\] 意思是,语料中的\(W\)个词是根据主题\(z_i\)观察到的独立多项分布。(我们把每个词看做独立的多项分布产生的结果,忽略顺序因素,所以没有多项分布的系数)。\(\varphi_{z_i,w_i}\)是一个\(K\ast V\)的矩阵,把词划分成主题和词汇表,公式如下: \[ p(\vec{w}|\vec{z},\underline{\Phi})=\prod^K_{k=1}\prod_{i:z_i=k}p(w_i=t|z_i=k)=\prod^K_{k=1}\prod^V_{t=1}\varphi^{n^{(t)}_k}_{k,t}\] \(n^{(t)}_k\)代表了主题\(k\)下词\(t\)出现的次数。目标分布\(p(\vec{w}|\vec{z},\vec{\beta})\)可以通过对\(\underline{\Phi}\)求狄利克雷积分得到:
类似地,主体分布\(p(\vec{z}|\vec{a})\)也可以通过这种方法产生,\(\underline{\Theta}\)为\(D*K\)的矩阵,公式如下: \[p(\vec{z}|\underline{\Theta})=\prod^W_{i=1}p(z_i|d_i)=\prod^M_{m=1}\prod^K_{k=1}p(z_i=k|d_i=m)=\prod^M_{m=1}\prod^K_{k=1}\theta^{n^{(k)}_m}_{m,k}\] \(n^{(k)}_m\)代表了文章\(m\)下主题\(k\)出现的次数。对\(\underline{\Theta}\)求积分,我们得到:
然后联合分布就变成了 \[p(\vec{z},\vec{w}|\vec{\alpha},\vec{\beta})=\prod^K_{z=1}\frac{\Delta(\vec{n_z}+\vec{\beta})}{\Delta(\vec{\beta})}\cdot\prod^M_{m=1}\frac{\Delta(\vec{n_m}+\vec{\alpha})}{\Delta(\vec{\alpha})}\]
我们令\(i=(m,n)\)代表第\(m\)篇文章中的第\(n\)个词,\(\neg i\)代表除去这个词之后剩下的其他词,令\(\vec{w}=\{w_i=t,\vec{w}_{\neg i}\}\),\(\vec{z}=\{z_i=k,\vec{z}_{\neg i}\}\),我们求得
这个式子需要注意的:
因为忽略了\(p(w_i)\)这个常数,所以后来的式子是\(\propto\)成正比。
对于第\(m\)篇文章中的第\(n\)个词,其主题为\(k\)。\(n^{(t)}_k=n^{(t)}_{k,\neg i}+1,n^{(k)}_m=n^{(k)}_{m,\neg i}+1\),对于其他文档和其他主题都没有影响。
这个公式很漂亮,右边是\(p(topic|doc)\cdot p(word|topic)\),这个概率其实就是\(doc\rightarrow topic \rightarrow word\)的路径概率,所以Gibbs Sampling 公式的物理意义就是在K条路径中采样。(图)
根据图3和图4的Dirichlet-Multinomial结构,我们知道\(\vec{\theta_m}\)和\(\vec{\phi_k}\)的后验概率为:(令\(\mathcal{M}=\{\vec{w},\vec{z}\}\))(备注1):
最后,根据狄利克雷分布的期望\(<Dir(\vec{a})>=a_i/\sum_i{a_i}\)(备注2),我们得到 \[\phi_{k,t}=\frac{n^{(t)}_k+\beta_t}{\sum^V_{t=1}n^{(t)}_k+\beta_t}\] \[\theta_{m,k}=\frac{n^{(k)}_m+\alpha_k}{\sum^K_{k=1}n^{(k)}_m+\alpha_k}\]
最后,整个LDA算法的流程图为
2.由于狄利克雷分布为: \[Dir(\vec{p}|\vec{\alpha})=\frac{\Gamma(\sum^K_{k=1}\alpha_k)}{\prod^K_{k=1}\Gamma{(\alpha_k)}}\prod^K_{k=1}p_k^{\alpha_k-1}\] 对于\(\vec{p}\)中一项\(p_i\)的期望为: \[\begin{split} E(p_i) &=\int^1_0 p_i\cdot Dir(\vec{p}|\vec{\alpha})dp \\ &=\frac{\Gamma(\sum^K_{k=1}\alpha_k)}{\Gamma(\alpha_i)}\cdot\frac{\Gamma(\alpha_i+1)}{\Gamma(\sum^K_{k=1}\alpha_k+1)} \\ &=\frac{\alpha_i}{\sum^K_{k=1}\alpha_k} \\\end{split}\] 参考文献: 1.主要来自《Parameter estimation for text analysis》 2.《LDA数学八卦》
]]>在三扇门中的某扇门以后有一个奖品,选中这扇门就能拿到门后的奖品。你选定了一扇门,具体地说,假设你选择了1号门。这时候主持人蒙提·霍尔会打开剩下两扇门的其中一扇,你看到门后没有奖品。这时候他给你一个机会选择要不要换另外一扇没有打开的门。你是选择换还是不换呢?
答:因为我之前就选了,换或者不换机会都是均等的,所以换不换无关紧要╮(╯▽╰)╭。 ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ 真的是这样么?仔细分析一下,游戏过程中你做了2个操作: 第一,你选择了一扇门。第二,你选择了换门或者不换。 定义事件\(A\)为你第一次就选中奖品。 定义事件\(B\)为你换门选中奖品。 那么\(A^c\)为集合A的余集,即第一次没有选中奖品。同理,\(B^c\)为换门没有选中奖品。整个游戏过程中,\(A\)或\(A^c\)先发生,\(B\)或\(B^c\)再发生。 显而易见的是 \[P(A)=1/3,P(A^c)=2/3\] 要注意的是,在第一次操作之后,还有一件事——主持人打开了一扇没有奖品的门。值得注意的是,这里主持人的动作是跟你第一次选择有关系的:
如果你一开始就选中了奖品,即事件\(A\)发生了,那么他就在剩下的两扇没有奖品的门之间任选一门打开。接下来,如果你选择换门,那么抽中的概率为0,不换抽中的概率为1。 即 \[P(B|A)=0,P(B^c|A)=1\] 因为事件\(B\)或\(B^c\)是在事件A发生之后发生的,所以这里的概率是基于事件\(A\)的条件概率。
如果你开始没有选中奖品,即事件\(A^c\)发生了,那么他只能打开另一扇没有奖品的门。这时候,如果你选择换门,那么抽中的概率为1,不换抽中的概率为0。 即 \[P(B|A^c)=1,P(B^c|A^c)=0\] 这里的概率是基于事件\(A^c\)的条件概率。
由上我们可以发现一点,事件\(A\)会影响事件\(B\)的概率,即事件\(A\)和事件\(B\)并不是相互独立的。\(A^c\)和\(B^c\)也是同理。 于是,利用全概率公式,我们可以求得换门选中奖品的概率为 \[P(B)=P(B|A)P(A)+P(B|A^c)P(A^c)=0*1/3+1*2/3=2/3\] \[P(B^c)=P(B^c|A)P(A)+P(B^c|A^c)P(A^c)=1*1/3+0*2/3=1/3\] 所以事实上你换门能得到奖品的概率为2/3,是不换门的2倍(懂点数学真好啊)。是不是和直觉不太一样?个人认为,直观上觉得\(P(B)=1/2\)的原因是忽略了第一次选择时,通过主持人的动作改变了换门的事件概率这一客观过程。 2013年7月3日更新
从信息论的角度来说,B事件的熵为H(B),在A事件发生之后B事件的条件熵为H(B|A),可以证明 \[H(B) \geq H(B|A) \] 也就是说,在给予了A的信息之后,B的不确定性下降了。