Archive for the ‘Statistics 1 2 3’ Category.

用GibbsLDA做Topic Modeling

Topic Modeling是一种文本挖掘的方法。将文本视作一个由许多许多词组成的数据库,就能通过分析哪些词经常在一起出现,哪些词出现的多,等等手段来探测文本中隐含的主题。比如,有一万篇文章,人工对这些文章进行分类,提取主题是十分浩大的工程。但是如果能用计算机来实现的话,对于社会科学研究者,尤其是注重对文本分析的传播学者来说,是个非常值得应用的工具。

简单来说,Topic Modeling就是干这么个活。把一堆文字放进去,你告诉计算机,你要多少个主题(比如,5),每个主题包含多少个字(比如,10),然后让计算机跑跑跑,过一会儿,计算机就告诉你5个主题,每个主题10个字分别是什么。

听起来有点玄乎,但是如果你能明白传统的因子分析(Factor Analysis),基本上就能明白Topic Modeling。核心思想无非就是降维度。对于因子分析来说,可以从100个变量,降维提出5个因子。对于Topic Modeling来说,可以通过100篇文章(可能包含100,000个字/词),降维提出5个主题。

具体到对Topic Modeling的操作,那就千变万化了。计算机科学(Computer Science)领域专门有人做这个,发展出各种算法。

我只介绍一种,叫做GibbsLDA。这其实就是Gibbs Sampling(一种抽样方法)跟Latent Dirichlet Allocation (LDA,一种算法/模型)的结合。这玩意儿太深奥了。我也解释不清楚。反正如果你google的话,有人用这两种东西的结合GibbsLDA写了文章,发了,貌似影响不小。是可行的,靠谱的。LDA最早是由David Blei提出的。

D. Blei, A. Ng, and M. Jordan: Latent Dirichlet Allocation, Journal of Machine Learning Research (2003).

更多的文章可以看看这里。也可以google下列文章:

l Finding scientific topics.

l The author-topic model for authors and documents.

l Bibliometric Impact Measures Leveraging Topic Analysis.

l Detecting Topic Evolution in Scientific Literature: How CanCitations Help?

这个GibbsLDA有很多的软件版本,比如C++版,Java版,Python版,MatLab版。各种版本对输入数据的要求可能还不一样。就我使用的情况来看,C++版本最稳定,运算速度也最快。

但是呢,C++版本一般在Linux上运行,如在Windows下运行,还得按照个Visual Studio。工程浩大。

Windows上装个Linux其实不难,搞个Wubi,在C盘上分出一个空间(10G左右),傻瓜都能搞定。这个Wubi给装的Linux是Ubuntu版本。不难用。Wubi其实是给你的电脑上傻瓜式地装上了一个虚拟Linux系统。开机时会让你选进Linux还是Windows。进了Linux也不怕,搞个天翻地覆,也就在你分给它的那点硬盘(比如10G)里,坏不了大事。当然,你舍不得搞复杂你的Windows的话,可以想办法搞个Linux的机器来玩玩。

累死了。简单来说,怎么安装使用GibbsLDA++看这里就可以了。不过我还是多罗嗦几句吧。

好了,从现在开始,就进入到安装GibbsLDA++了。

第一步:下载GibbsLDA++

第二步:把下载的文件放到一个文件夹。对于没接触过Linux的同学来说,你可以放到,,,比如说/home/user(你的用户名)/LDA/ 下面。对于在Windows上用虚拟Ubuntu的同学来说,在你找的地方,随便造个文件夹装下这文件就好了。

第三步:解压缩及安装。对于没用过Linux的同学来说,没有右键解压缩这个故事是很痛苦的。好吧,慢慢来。比如你这个狗屁文件放到了/home/user/LDA/下面。而你甚至连你在什么文件夹下都不知道。你可以这样。在Terminal(也就是一个黑屏幕,只能输入命令的那种)里面输入(下面的$表示一行命令的开始,不用输入)

$ cd /home/user/LDA/

就行了。然后,解压缩。输入

$ gunzip GibbsLDA++-0.2.tar.gz(这个gunzip后面是你刚下载的文件的文件名,我下的是GibbsLDA++-0.2)

$ tar -xf GibbsLDA++-0.2.tar

然后进到你刚解压出来的那个文件夹(假设你现在还是在/home/user/LDA/下面)。输入

$ cd \GibbsLDA++-0.2

现在,你已经在/home/user/LDA/GibbsLDA++-0.2/ 这个文件夹下面了已然后安装GibsLDA。输入

$ make clean

$ make all

到目前为止,你已经大功告成了。安装完成。

第四步:准备你要让计算机去做Topic Modeling的文件。在C++的环境里,Topic Modeling需要这样的一个文件。文件格式是dat。这是最原始的txt文件。你也可以用任何软件存成txt文件之后,直接把后缀改成dat就行。比如,你的文件包含1,000篇文章。那你的文件就是这样的

第1行是你总共的文章篇数,在我们的例子里面是1000

第2行到第1001行就是你的那些文章,每篇文章占一行。对于英文来说,每个词之间已经用空格分开了,但是中文不行,所以你要先对文章进行切词。切词这事儿,就不归我这篇小臭长文管了。

第五步:运行GibbsLDA++,得到你要的结果。

将你要跑的文件,比如就叫test.dat吧。将文件放到/home/user/LDA/ 下面,也就是/home/user/LDA/test.dat

然后进入到你装了GibbsLDA++的文件夹,也就是/home/user/LDA/GibbsLDA++-0.2/,然后运行指令。其实就是在Terminal里面输入

$ cd /home/user/LDA/GibbsLDA++-0.2/

$ lda -est [-alpha <double>] [-beta <double>] [-ntopics <int>] [-niters <int>] [-savestep <int>] [-twords <int>] -dfile <string>

这句话“$ lda -est [-alpha <double>] [-beta <double>] [-ntopics <int>] [-niters <int>] [-savestep <int>] [-twords <int>] -dfile <string>”里面其实是GibbsLDA进行估算的各种参数设计,你实际输入的指令可能是:

$ src/lda -est -alpha 0.5 -beta 0.1 -ntopics 100 -niters 1000 -savestep 100 -twords 20 -dfile /home/luheng/LDA/test.dat

这意思是,参数alpha是0.5(这个可以先不管),参数beta是0.1(这个也可以先不管),产生100个topic,运算迭代1000次,每迭代100次之后的结果都保存出来,每个topic包含20个词,要运算的文件是/home/luheng/LDA/test.dat

第六步:看结果。

好了,如果你顺利走到这一步,就去看结果吧。结果文件存在你的测试文件所在的目录。在这个案例中,就是/home/luheng/LDA/ 下面。

会产生类似这样的文件,不同的后缀表示不同的结果。所有这些文件都可以用记事本打开。newdocs.dat.others
newdocs.dat.phi
newdocs.dat.tassign
newdocs.dat.theta
newdocs.dat.twords

其中最直接的是.twords文件。这个文件里面就是你要的n个topic,以及每个topic下面包含的具体的字词。

.others里面是各种你设置的参数

.theta里面是每篇文章对应你设置的n个topic的“因子载荷”(factor loading)

.phi里面是每个topic对应每篇文章的“因子载荷”(factor loading)

.theta 和 .phi 里面的数据其实是一回事,互为转置罢(transpose)了。

.tassign是个啥玩意儿我暂时还没去搞明白。反正除此以外的那几个文件里面的东西已经够我用了。

一些提醒:

计算机很聪明也很笨,你给什么它都帮你算,所以你准备的文件一定要想清楚。比如,是不是所有字词都放心去,那些a, the, of啊,那些华丽丽的形容词啊,是拿掉还是放心去。或者是不是只放名词进去。这事儿只能自己决定,计算机帮不了你。

你选多少个主题,每个主题要多少字,迭代多少步。这玩意儿没有一定的规定。你就试吧。撞大运吧。虽然GibbsLDA靠谱,可终究还是跟因子分析一样,充满了arbitrary!

要听他连续说多少次“我爱你”才能相信

要听他连续说多少次“我爱你”才能相信

——怎样判断一枚硬币是不是公平的?

(有些公式神马的看不到,见PDF版本)

PDF Version Here: 要听他连续说多少次我爱你

抛硬币是生活中最常被拿来举例子的Bernoulli(贝努力)试验。这也是一个最简单的概率事件,只有两个选项,正面或者反面(假设不存在立着的情况)。这个例子也可以推广到很多二分变量(binary variables)的取值概率问题。支持或者反对,使用或者不用等等。

一枚硬币如果是公平的话,每次抛硬币得到正反面的机会各等于二分之一。现在我们假定说抛硬币得到正面的概率是p,得到反面的概率是q=(1-p)。

现在我们有一枚硬币,抛了100次,得到了55次正面。那么,我们知道,在这100次里面,我们得到正面的概率是55/100=.55。但我们都抛了100次了,知道了p=.55,又怎么样呢?我们想知道的是,下次以及每次抛这个硬币,得到正面的概率p的估计值p-hat是多少。

这么想的话,上面所说的p=.55是指我们抛了的100次我们知道的抛硬币得到正面的概率是.55,也就是我们的样本(sample)里的p=.55。我们想知道的是通过我们的样本推测到总体(population)的抛这枚硬币得正面的估计值p-hat是多少呢?

从样本统计量p推算总体估计值p-hat就要考虑置信区间(Confidence Interval)。下面这枚公式就能推算,从我们这个抛了100次的样本,估计抛这枚硬币得正面的概率是:

(公式一)

这里的n就是我们抛的次数,也就是样本量(sample size)。这里的是一个统计量,根据不同的置信度(Confidence Level, 如90%,95%,99%等)有不同的固定的取值。这个是另外一个故事了。有兴趣的同学可以去维基百科看“Confidence Interval(置信区间)”这个词条http://en.wikipedia.org/wiki/Confidence_interval。当然了,这个取值还隐藏了另外一个关于正态分布的假设,那也是另一个故事了。

如果我们采用95%的置信度,对应的就等于1.96。我们这100次硬币来估算这枚硬币被抛得正面的概率就是一个区间(.452, .648)。也就是说,如果我们再抛100次硬币,我们有95%的机会得到正面的次数在45次到65次之间。

好吧好吧。我承认我有些罗嗦了。上面这些其实不是我想说的重点。我想说的重点是,我们要连续抛多少次正面,在95%的置信度上,才有根据不否定硬币是不公平的(有点绕,嘿嘿)?

下面就是一个假设检验的问题了。假设检验的一般就得提出一个零假设(Null Hypothesis, H0)和一个备择假设(Alternative Hypothesis,H1)。

我们这里的零假设就是硬币是公平的,也就是每次抛硬币得到正面的概率是1/2。

H0:p-hat=.5

我们这里的备择假设就是硬币是不公平的,也就是每次抛硬币得到正面的概率不是1/2。

H1:p-hat<>.5

我们说的每次抛多少次正面才够的意思是,我们已经确定了p1=1,我们想知道的是n的最小值。我们的问题可以等价地转换成我们估算的p-hat1和假定硬币公平的p-hat2之间的差,怎么就等于0。

这里,H0可以等价地转换为p-hat1-p-hat2=0。

H1可以等价地转换为p-hat1-p-hat2<>0。

怎么算两个比例之差p1-p2的区间估计呢?我们要用到下面这个公式:

(公式二)

这里,我们的p1=1,p2=.5是知道的,在95%的置信度条件下=1.96,代入公式二,就可以得到区间是:

我们的零假设也就转换成:

0必须落在这个区间内。也就是:

通过计算,也就说是n<=3.92的时候,零假设才可能成立。只要n>3.92的时候,我们就可以拒绝零假设,然后在置信度95%的条件下,认为这枚倒霉的硬币是不公平的。

哈哈哈哈。

最后,再让我来说一下so what的问题。如果我们假定你的男人跟你说“我爱你”和说“我不爱你”是等概率事件,机会各一半一半。那么,如果你的男人连续四次跟你说“我爱你”。你选择相信他这句话。你应该有95%的把握。哈哈。可是,你会觉得你男人说“我爱你”和说“我不爱你”不是等概率事件。好吧。那你觉得概率多大你才满意?p=.999999999? 好吧,你还说,置信度95%不够,要99%才差不多。我告诉你,在99%的置信度条件下=2.56。这样的话,你能算出,你男人要连续说多少次“我爱你”,你才能相信他(说“我爱你”不是偶然的)了吧???