LSA(Latent semantic analysis,隐性语义分析)、pLSA(Probabilistic latent semantic analysis,概率隐性语义分析)和 LDA(Latent Dirichlet allocation,隐狄利克雷分配)这三种模型都可以归类到话题模型(Topic model,或称为主题模型)中。相对于比较简单的向量空间模型,主题模型通过引入主题这个概念,更进一步地对文本进行语义层面上的理解。
LSA 模型就是对词-文档共现矩阵进行SVD,从而得到词和文档映射到抽象出的topic上的向量表示,之前的一篇博客稍微提到过一点。LSA 通过将词映射到topic上得到distributional representation(词的分布表示),进而缓解文档检索、文档相似度计算等任务中所面临的同义词(多词一义)问题:比如我搜索“Java 讲义”,如果系统只是用字符匹配来检索的话,是不会返回一篇出现了“Java 课件”但通篇没出现“讲义”这个词的文档的。所以说,单纯地从词-文档共现矩阵取出词向量表示和文档向量表示的向量空间模型,尽管利用了大规模文档集的统计信息,仍然是无法直接从“语义”这个层面上去理解文本的。但是 LSA 这种将词映射到topic上的向量表示,很难去应对一词多义问题:比如“Java”这个词既可能指编程语言,也可能指爪哇岛,即使这两种含义的“Java”都在文档集里出现过,得到的 LSA 模型也无法很好地区分。
pLSA 模型是有向图模型,将主题作为隐变量,构建了一个简单的贝叶斯网,采用EM算法估计模型参数。相比于 LSA 略显“随意”的SVD,pLSA 的统计基础更为牢固。
相比于 LDA 模型里涉及先验分布,pLSA 模型相对简单:观测变量为文档 d m ∈ D d_m\in\mathbb D dm∈D(文档集共 M 篇文档)、词 w n ∈ W w_n\in\mathbb W wn∈W(设词汇表共有 V 个互不相同的词),隐变量为主题 z k ∈ Z z_k\in\mathbb Z zk∈Z(共 K 个主题)。在给定文档集后,我们可以得到一个词-文档共现矩阵,每个元素 n ( d m , w n ) n(d_m,w_n) n(dm,wn) 表示的是词 w n w_n wn 在文档 d m d_m dm 中的词频。也就是说,pLSA 模型也是基于词-文档共现矩阵的,不考虑词序
pLSA 模型通过以下过程来生成文档(记号里全部省去了对参数的依赖):
(1) 以概率 P ( d m ) P(d_m) P(dm) 选择一篇文档 d m d_m dm
(2) 以概率 P ( z k ∣ d m ) P(z_k|d_m) P(zk∣dm) 得到一个主题 z k z_k zk
(3) 以概率 P ( w n ∣ z k ) P(w_n|z_k) P(wn∣zk) 生成一个词 w n w_n wn
概率图模型如下所示
图里面的浅色节点代表不可观测的隐变量,方框是指变量重复(plate notation),内部方框表示的是文档 d m d_m dm 的长度是 N,外部方框表示的是文档集共 M 篇文档。pLSA 模型的参数 θ \theta θ 显而易见就是: K × M K\times M K×M 个 P ( z k ∣ d m ) P(z_k|d_m) P(zk∣dm) 、 V × K V\times K V×K 个 P ( w n ∣ z k ) P(w_n|z_k) P(wn∣zk) 。 P ( z k ∣ d m ) P(z_k|d_m) P(zk∣dm) 表征的是给定文档在各个主题下的分布情况,文档在全部主题上服从多项式分布(共 M 个); P ( w n ∣ z k ) P(w_n|z_k) P(wn∣zk) 则表征给定主题的词语分布情况,主题在全部词语上服从多项式分布(共 K 个)。
拿到贝叶斯网当然先要看看联合分布咯。这个贝叶斯网表达的是如下的联合分布:
P ( d m , z k , w n ) = P ( d m ) P ( z k ∣ d m ) P ( w n ∣ z k ) P(d_m,z_k,w_n)=P(d_m)P(z_k|d_m)P(w_n|z_k) P(dm,zk,wn)=P(dm)P(zk∣dm)P(wn∣zk)
P ( d m , w n ) = P ( d m ) P ( w n ∣ d m ) P(d_m,w_n)=P(d_m)P(w_n|d_m) P(dm,wn)=P(dm)P(wn∣dm)
假设有一篇文档为 w ⃗ = ( w 1 , w 2 , . . . , w N ) \vec{w}=(w_1,w_2,...,w_N) w=(w1,w2,...,wN) ,生成它的概率就是 P ( w ⃗ ∣ d m ) = ∏ n = 1 N P ( w n ∣ d m ) P(\vec{w}|d_m)=\prod_{n=1}^N P(w_n|d_m) P(w∣dm)=n=1∏NP(wn∣dm)
我们看一下 P ( w n ∣ d m ) P(w_n|d_m) P(wn∣dm) 的表达式。如果不考虑随机变量之间的条件独立性的话,有
P ( w n ∣ d m ) = ∑ k P ( z k ∣ d m ) P ( w n ∣ z k , d m ) P(w_n|d_m)=\sum_k P(z_k|d_m)P(w_n|z_k,d_m) P(wn∣dm)=k∑P(zk∣dm)P(wn∣zk,dm)
但是观察图模型中的 d 、z 、w 可以知道,它们三个是有向图模型里非常典型的 head-to-tail 的情况:当 z 已知时,d 和 w 条件独立,也就是
P ( w n ∣ z k , d m ) = P ( w n ∣ z k ) P(w_n|z_k,d_m)=P(w_n|z_k) P(wn∣zk,dm)=P(wn∣zk)
进而有
P ( w n ∣ d m ) = ∑ k P ( z k ∣ d m ) P ( w n ∣ z k ) P(w_n|d_m)=\sum_k P(z_k|d_m)P(w_n|z_k) P(wn∣dm)=k∑P(zk∣dm)P(wn∣zk)
所以最终的联合分布表达式为
P ( d m , w n ) = P ( d m ) ∑ k P ( z k ∣ d m ) P ( w n ∣ z k ) P(d_m,w_n)=P(d_m)\sum_k P(z_k|d_m)P(w_n|z_k) P(dm,wn)=P(dm)k∑P(zk∣dm)P(wn∣zk)
这样的话,我们要做的事就是从文档集里估计出上面的参数。pLSA 是频率学派的方法,将模型参数看作具体值,而不是有先验的随机变量。所以,考虑最大化对数似然函数:
L ( θ ) = ln ∏ m = 1 M ∏ n = 1 N P ( d m , w n ) n ( d m , w n ) = ∑ m ∑ n n ( d m , w n ) ln ; P ( d m , w n ) = ∑ m ∑ n n ( d m , w n ) ( ln P ( d m ) + ln P ( w n ∣ d m ) ) = ∑ m ∑ n n ( d m , w n ) ln P ( w n ∣ d m ) + ∑ m ∑ n n ( d m , w n ) ln P ( d m ) \begin{aligned} L(\theta)&=\ln \prod_{m=1}^M\prod_{n=1}^N P(d_m,w_n)^{n(d_m,w_n)}\\ &=\sum_m\sum_n n(d_m,w_n)\ln;P(d_m,w_n)\\ &=\sum_m\sum_n n(d_m,w_n)(\ln P(d_m)+\ln P(w_n|d_m))\\ &=\sum_m\sum_n n(d_m,w_n)\ln P(w_n|d_m)+\sum_m\sum_n n(d_m,w_n)\ln P(d_m) \end{aligned} L(θ)=lnm=1∏Mn=1∏NP(dm,wn)n(dm,wn)=m∑n∑n(dm,wn)ln;P(dm,wn)=m∑n∑n(dm,wn)(lnP(dm)+lnP(wn∣dm))=m∑n∑n(dm,wn)lnP(wn∣dm)+m∑n∑n(dm,wn)lnP(dm)
第二项可以直接去掉,那么不妨直接记:
L ( θ ) = ∑ m ∑ n n ( d m , w n ) ln P ( w n ∣ d m ) = ∑ m ∑ n n ( d m , w n ) ln [ ∑ k P ( z k ∣ d m ) P ( w n ∣ z k ) ] \begin{aligned} L(\theta)&=\sum_m\sum_n n(d_m,w_n)\ln P(w_n|d_m)\\ &=\sum_m\sum_n n(d_m,w_n)\ln \bigl[\sum_k P(z_k|d_m)P(w_n|z_k)\bigr]\end{aligned} L(θ)=m∑n∑n(dm,wn)lnP(wn∣dm)=m∑n∑n(dm,wn)ln[k∑P(zk∣dm)P(wn∣zk)]
参数估计:EM算法迭代求解
由于参数全部在求和号里被外层的log套住,所以很难直接求偏导数估计参数。到了这里,就轮到EM算法闪亮登场了。之前的一篇简单介绍EM的博客里解决的是这样的问题:观测变量 y ,隐变量 z ,参数 θ \theta θ ,目标函数 L ( θ ) = ln P ( y ) = ln ∑ k P ( z k ) P ( y ∣ z k ) L(\theta)=\ln P(y)=\ln \sum_k P(z_k)P(y|z_k) L(θ)=lnP(y)=ln∑kP(zk)P(y∣zk) (省略 θ \theta θ依赖),Q函数 Q ( θ ; θ t ) = E z ∣ y ; θ t [ ln P ( y , z ) ] = ∑ k P ( z k ∣ y ; θ t ) ln P ( y , z ) Q(\theta;\theta_t)=\mathbb E_{z|y;\theta_t}[\ln P(y,z)]=\sum_k P(z_k|y;\theta_t)\ln P(y,z) Q(θ;θt)=Ez∣y;θt[lnP(y,z)]=∑kP(zk∣y;θt)lnP(y,z) ,进而有 θ t + 1 = arg max θ Q ( θ ; θ t ) \theta_{t+1}=\arg\max_{\theta}Q(\theta;\theta_t) θt+1=argmaxθQ(θ;θt) 来迭代求取。
我们来看看PLSA和LDA生成文档的方式。在PLSA中,生成文档的方式如下:
LDA 中,生成文档的过程如下:
α ⃗ → θ ⃗ m → ζ m , n \vec \alpha \to \vec \theta_m \to \zeta_{m, n} α→θm→ζm,n, 这个过程表示在生成第m篇文档的时候,先从抽取了一个doc-topic骰子 θ ⃗ m \vec \theta_m θm, 然后投掷这个骰子生成了文档中第n个词的topic编号 ζ m , n \zeta_{m, n} ζm,n;
β ⃗ → ϕ ⃗ k → ω m , n ∣ = ζ m , n \vec \beta \to \vec \phi_k \to \omega_{m, n}\mid = \zeta_{m ,n} β→ϕk→ωm,n∣=ζm,n, 这个过程表示,从K个topic-word骰子 ϕ ⃗ k \vec \phi_k ϕk中,挑选编号为 k = ζ m , n k = \zeta_{m, n} k=ζm,n的骰子进行投掷,然后生成词汇 ω m , n \omega_{m , n} ωm,n;
在LDA中,也是采用词袋模型,M篇文档会对应M个独立Dirichlet-Multinomial共轭结构;K个topic会对应K个独立的Dirichlet-Multinomial共轭结构。
上面的LDA的处理过程是一篇文档一篇文档的过程来处理,并不是实际的处理过程。文档中每个词的生成都要抛两次骰子,第一次抛一个doc-topic骰子得到 topic, 第二次抛一个topic-word骰子得到 word,每次生成每篇文档中的一个词的时候这两次抛骰子的动作是紧邻轮换进行的。如果语料中一共有 N 个词,则上帝一共要抛 2N次骰子,轮换的抛doc-topic骰子和 topic-word骰子。但实际上有一些抛骰子的顺序是可以交换的,我们可以等价的调整2N次抛骰子的次序:前N次只抛doc-topic骰子得到语料中所有词的 topics,然后基于得到的每个词的 topic 编号,后N次只抛topic-word骰子生成 N 个word。此时,可以得到:
p ( w ⃗ , z ⃗ ∣ α ⃗ , β ⃗ ) = p ( w ⃗ ∣ z ⃗ , β ⃗ ) p ( z ⃗ ∣ α ⃗ ) = ∏ k = 1 K Δ ( ϕ ⃗ K + β ⃗ ) Δ ( β ⃗ ) ∏ m = 1 M Δ ( θ ⃗ m + α ⃗ ) α ⃗ \begin{aligned} p(\vec w , \vec z \mid \vec \alpha, \vec \beta) & = p(\vec w \mid \vec z, \vec \beta) p(\vec z \mid \vec \alpha) \\ & = \prod_{k=1}^K\frac{\Delta(\vec \phi_K + \vec \beta)}{\Delta (\vec \beta)} \prod_{m=1}^M \frac{\Delta(\vec \theta_m + \vec \alpha)}{\vec \alpha} \end{aligned} p(w,z∣α,β)=p(w∣z,β)p(z∣α)=k=1∏KΔ(β)Δ(ϕK+β)m=1∏MαΔ(θm+α)
根据上一小节中的联合概率分布 p ( ω ⃗ , z ⃗ ) p(\vec \omega, \vec z) p(ω,z), 我们可以使用Gibbs Sampling对其进行采样。
语料库 z ⃗ \vec z z中的第i个词我们记为 z i z_i zi, 其中i=(m,n)是一个二维下标,对应于第m篇文档的第n个词,用 ¬ i \lnot i ¬i 表示去除下标为i的词。根据第二小节中的Gibbs Sampling 算法,我们需要求任一个坐标轴 i 对应的条件分布 p ( z i = k ∣ z ⃗ ¬ i , ω ⃗ ) p(z_i=k|\vec z_{\lnot i}, \vec \omega) p(zi=k∣z¬i,ω) 。假设已经观测到的词 ω i = t \omega_i=t ωi=t, 则由贝叶斯法则,我们容易得到:
p ( z i = k ∣ z ⃗ ¬ i , ω ⃗ ) a m p ; ∝ p ( z i = k , ω i = t ∣ z ⃗ ¬ i , ω ⃗ ¬ i ) \begin{aligned} p(z_i = k \mid \vec z_{\lnot i}, \vec \omega) & ∝ p(z_i = k, \omega_i = t \mid \vec z_{\lnot i}, \vec \omega_{\lnot i}) \end{aligned} p(zi=k∣z¬i,ω)amp;∝p(zi=k,ωi=t∣z¬i,ω¬i)
由于 z i = k , w i = t z_i=k,w_i=t zi=k,wi=t 只涉及到第 m 篇文档和第k个 topic,所以上式的条件概率计算中, 实际上也只会涉及到与之相关的两个Dirichlet-Multinomial 共轭结构,其它的 M+K−2 个 Dirichlet-Multinomial 共轭结构和 z i = k , w i = t z_i=k,w_i=t zi=k,wi=t是独立的。去掉一个词汇,并不会改变M + K 个Dirichlet-Multinomial共轭结构,只是某些地方的计数减少而已。于是有:
p ( θ ⃗ m ∣ z ⃗ ¬ i , ω ⃗ ¬ i ) a m p ; = D i r ( θ ⃗ m ∣ n ⃗ m , ¬ i + α ⃗ ) p ( φ ⃗ k ∣ z ⃗ ¬ i , ω ⃗ ¬ i ) a m p ; = D i r ( φ ⃗ k ∣ n ⃗ k , ¬ i + β ⃗ ) \begin{aligned} p(\vec \theta_m \mid \vec z_{\lnot i}, \vec \omega_{\lnot i}) & = Dir(\vec \theta_m \mid \vec n_{m, \lnot i} + \vec \alpha) \\ p(\vec \varphi_k \mid \vec z_{\lnot i}, \vec \omega_{\lnot i}) & = Dir(\vec \varphi_k \mid \vec n_{k, \lnot i} + \vec \beta) \end{aligned} p(θm∣z¬i,ω¬i)p(φk∣z¬i,ω¬i)amp;=Dir(θm∣nm,¬i+α)amp;=Dir(φk∣nk,¬i+β)
下面进行本篇文章最终的核心数学公式推导:
p ( z i = k ∣ z ⃗ ¬ i , ω ⃗ ) a m p ; ∝ p ( z i = k , ω i = t ∣ z ⃗ ¬ i , ω ⃗ ¬ i ) = ∫ p ( z i = k , ω i = t , θ ⃗ m , φ ⃗ k ∣ z ⃗ ¬ i , ω ⃗ ¬ i ) d θ ⃗ m d φ ⃗ k = ∫ p ( z i = k , θ ⃗ m , ∣ z ⃗ ¬ i , ω ⃗ ¬ i ) ⋅ p ( ω i = t , φ ⃗ k , ∣ z ⃗ ¬ i , ω ⃗ ¬ i ) d θ ⃗ m d φ ⃗ k = ∫ p ( z i = k ∣ θ ⃗ m ) p ( θ ⃗ m ∣ z ⃗ ¬ i , ω ⃗ ¬ i ) ⋅ p ( ω i = t ∣ φ ⃗ k ) p ( φ ⃗ k ∣ z ⃗ ¬ i , ω ⃗ ¬ i ) d θ ⃗ m d φ ⃗ k = ∫ p ( z i = k ∣ θ ⃗ m ) D i r ( θ ⃗ m ∣ n ⃗ m , ¬ i + α ⃗ ) d θ ⃗ m ⋅ p ( ω i = t ∣ φ ⃗ k ) D i r ( φ ⃗ k ∣ n ⃗ k , ¬ i + β ⃗ ) d φ ⃗ k = ∫ θ m k D i r ( θ ⃗ m ∣ n ⃗ m , ¬ i + α ⃗ ) d θ ⃗ m ⋅ ∫ φ k t D i r ( φ ⃗ k ∣ n ⃗ k , ¬ i + β ⃗ ) d φ ⃗ k = E ( θ m k ) ⋅ E ( φ k t ) = θ ^ m k ⋅ φ ^ k t \begin{aligned} p(z_i = k \mid \vec z_{\lnot i}, \vec \omega) & \propto p(z_i = k, \omega_i = t \mid \vec z_{\lnot i}, \vec \omega_{\lnot i}) \\ & = \int p(z_i = k, \omega_i = t, \vec \theta_m, \vec \varphi_k \mid \vec z_{\lnot i}, \vec \omega_{\lnot i})d\vec \theta_m d \vec \varphi_k \\ & = \int p(z_i = k, \vec \theta_m, \mid \vec z_{\lnot i}, \vec \omega_{\lnot i}) \cdot p(\omega_i = t, \vec \varphi_k, \mid \vec z_{\lnot i}, \vec \omega_{\lnot i}) d\vec \theta_m d \vec \varphi_k \\ & = \int p(z_i = k \mid \vec \theta_m) p(\vec \theta_m \mid \vec z_{\lnot i}, \vec \omega_{\lnot i}) \cdot p(\omega_i = t \mid \vec \varphi_k)p(\vec \varphi_k \mid \vec z_{\lnot i}, \vec \omega_{\lnot i}) d\vec \theta_m d \vec \varphi_k \\ & = \int p(z_i = k \mid \vec \theta_m) Dir(\vec \theta_m \mid \vec n_{m, \lnot i} + \vec \alpha) d \vec \theta_m \cdot p(\omega_i = t \mid \vec \varphi_k) Dir(\vec \varphi_k \mid \vec n_{k, \lnot i} + \vec \beta) d \vec \varphi_k \\ & = \int \theta_{mk} Dir(\vec \theta_m \mid \vec n_{m, \lnot i} + \vec \alpha) d \vec \theta_m \cdot \int \varphi_{kt} Dir(\vec \varphi_k \mid \vec n_{k, \lnot i} + \vec \beta) d \vec \varphi_k \\ & = E(\theta_{mk}) \cdot E(\varphi_{kt}) \\ & = \hat \theta_{mk} \cdot \hat \varphi_{kt} \end{aligned} p(zi=k∣z¬i,ω)amp;∝p(zi=k,ωi=t∣z¬i,ω¬i)=∫p(zi=k,ωi=t,θm,φk∣z¬i,ω¬i)dθmdφk=∫p(zi=k,θm,∣z¬i,ω¬i)⋅p(ωi=t,φk,∣z¬i,ω¬i)dθmdφk=∫p(zi=k∣θm)p(θm∣z¬i,ω¬i)⋅p(ωi=t∣φk)p(φk∣z¬i,ω¬i)dθmdφk=∫p(zi=k∣θm)Dir(θm∣nm,¬i+α)dθm⋅p(ωi=t∣φk)Dir(φk∣nk,¬i+β)dφk=∫θmkDir(θm∣nm,¬i+α)dθm⋅∫φktDir(φk∣nk,¬i+β)dφk=E(θmk)⋅E(φkt)=θ^mk⋅φ^kt
最终得到的 θ ^ m k ⋅ φ ^ k t \hat \theta_{mk} \cdot \hat \varphi_{kt} θ^mk⋅φ^kt 就是对应的两个 Dirichlet 后验分布在贝叶斯框架下的参数估计。借助于前面介绍的Dirichlet 参数估计的公式 ,有:
θ ^ m k a m p ; = n m , ¬ i ( k ) + α k ∑ k = 1 K ( n m , ¬ i ( k ) + α k ) φ ^ k t a m p ; = n k , ¬ i ( t ) + β t ∑ t = 1 V ( n k , ¬ i ( t ) + β t ) \begin{aligned} \hat{\theta}_{mk} &= \frac{n_{m,\neg i}^{(k)} + \alpha_k}{\sum_{k=1}^K (n_{m,\neg i}^{(k)} + \alpha_k)} \\ \hat{\varphi}_{kt} &= \frac{n_{k,\neg i}^{(t)} + \beta_t}{\sum_{t=1}^V (n_{k,\neg i}^{(t)} + \beta_t)} \end{aligned} θ^mkφ^ktamp;=∑k=1K(nm,¬i(k)+αk)nm,¬i(k)+αkamp;=∑t=1V(nk,¬i(t)+βt)nk,¬i(t)+βt
最终,我们得到LDA 模型的 Gibbs Sampling 公式为:
p ( z i = k ∣ z → ¬ i , w → ) ∝ n m , ¬ i ( k ) + α k ∑ k = 1 K ( n m , ¬ i ( k ) + α k ) ⋅ n k , ¬ i ( t ) + β t ∑ t = 1 V ( n k , ¬ i ( t ) + β t ) \begin{aligned} p(z_i = k|\overrightarrow{\mathbf{z}}_{\neg i}, \overrightarrow{\mathbf{w}}) \propto \frac{n_{m,\neg i}^{(k)} + \alpha_k}{\sum_{k=1}^K (n_{m,\neg i}^{(k)} + \alpha_k)} \cdot \frac{n_{k,\neg i}^{(t)} + \beta_t}{\sum_{t=1}^V (n_{k,\neg i}^{(t)} + \beta_t)} \end{aligned} p(zi=k∣z¬i,w)∝∑k=1K(nm,¬i(k)+αk)nm,¬i(k)+αk⋅∑t=1V(nk,¬i(t)+βt)nk,¬i(t)+βt
根据上一小节中的公式,我们的目标有两个:
有了 LDA 的模型,对于新来的文档 doc, 我们只要认为 Gibbs Sampling 公式中的 φ ⃗ k t \vec \varphi_{kt} φkt 部分是稳定不变的,是由训练语料得到的模型提供的,所以采样过程中我们只要估计该文档的 topic 分布 θ \theta θ就好了. 具体算法如下:
懂 LDA 的面试官通常会询问求职者,LDA 中主题数目如何确定?
在 LDA 中,主题的数目没有一个固定的最优解。模型训练时,需要事先设置主题数,训练人员需要根据训练出来的结果,手动调参,有优化主题数目,进而优化文本分类结果。
修改之前 SVM与贝叶斯分类中提取特征的部分即可
from scipy.sparse import hstack
def tf_LDA_deal_cnews(input_file_name,out_file_name):
bunch=_read_bunch(input_file_name)#读取数据
stop_words=get_stop_words()#得到停用词
#实例化bunch对象
#tmd(权重列表)
#vocabulary(词典索引)
space_bunch=Bunch(targets=bunch.targets,filename=bunch.filenames,labels=bunch.labels,tmd=[],vocabulary={
})
#使用特征提取函数TfidfVectorizer初始化向量空间模型
tf_vector=TfidfVectorizer(stop_words=stop_words,sublinear_tf=True,max_df=0.5,max_features=10000)#提取函数的初始化,啥数据都没有处理。选择能代表新闻特征、独一无二的词汇,词频大于50%的就被过滤掉???如果过大、过小会如何?
tf_features=tf_vector.fit_transform(bunch.contents)
## lda
lda = LatentDirichletAllocation(n_topics=10, max_iter=5,
learning_method='online',
learning_offset=50.,
random_state=0)
cnt_vector =CountVectorizer(stop_words=stop_words,max_df=0.5,max_features=10000)
cntTf = cnt_vector.fit_transform(bunch.contents)
LDA_features = lda.fit_transform(cntTf)
print(tf_features.shape)
print(LDA_features.shape)
space_bunch.tmd= hstack((tf_features,LDA_features))
print(space_bunch.tmd.shape)
space_bunch.vocabulary=tf_vector.vocabulary_#词典索引,统计词频
'''
print(space_bunch.vocabulary)输出格式如下:
{'黄蜂': 834, 'vs': 38, '湖人': 557, '首发': 820, '科比': 609, '带伤': 352, '保罗': 156,
'''
_write_bunch(space_bunch,out_file_name)#写入文件
pLSA模型
一文详解LDA主题模型