回答

10

嘗試在斯坦福解析器標記LDA對於它的價值,LDA作爲分類將是相當弱的,因爲它是一個生成模型,並分類是一種歧視性的問題。有一種稱爲supervised LDA的LDA變體,它使用更加區別性的標準來形成主題(您可以在不同的地方獲得此主題的源代碼),還有一篇文章採用了max margin公式,我不知道源代碼的狀態,代碼明智。除非您確定這是您想要的,否則我會避免使用標記的LDA公式,因爲它會對分類問題中的主題和類別之間的對應關係做出有力的假設。

但是,值得指出的是,這些方法都沒有直接使用主題模型來進行分類。相反,他們需要文檔,而不是使用基於詞的特徵,而是在將它們饋送到分類器(通常是線性SVM)之前,將主題(對文檔的推斷產生的向量)的後驗用作其特徵表示。這爲您提供了一個基於主題模型的降維,其次是一個強大的區分性分類器,這可能是您追求的目標。該流水線在大多數使用流行工具包的語言中都可用 。

+0

可能值得研究的另一種更新的方法是部分標記的LDA。 [鏈接](http://research.microsoft.com/en-us/um/people/sdumais/kdd2011-pldp-final.pdf)它放寬了培訓集中的每個文檔都必須有標籤的要求。 – metaforge

3
+1

謝謝,我會看看!你知道是否有l-LDA的C/C++/Python實現? –

+0

對不起,我最初沒有看到您的消息。我沒有意識到一個C/Python的實現,但我沒有看過。我知道比爾(LDA作者)通常在他的個人網站上發佈他的代碼(C/C++),所以我會檢查一下。 – Steve

+0

這種方法的問題在於它需要一個標籤來與一個主題進行1對1匹配,所以它是非常嚴格的。 – metaforge

3

您可以實現監督LDA與使用都市報樣學潛變量在下面的圖形模型PyMC: sLDA graphical model

訓練庫由10條電影評論(5正和5負)沿與每個文件相關的星級評定。星級評分被稱爲響應變量,它是與每個文檔相關的興趣量。文檔和響應變量共同建模,以找到最能預測未來未標記文檔響應變量的潛在主題。欲瞭解更多信息,請查看original paper。 考慮下面的代碼:

import pymc as pm 
import numpy as np 
from sklearn.feature_extraction.text import TfidfVectorizer 

train_corpus = ["exploitative and largely devoid of the depth or sophistication ", 
       "simplistic silly and tedious", 
       "it's so laddish and juvenile only teenage boys could possibly find it funny", 
       "it shows that some studios firmly believe that people have lost the ability to think", 
       "our culture is headed down the toilet with the ferocity of a frozen burrito", 
       "offers that rare combination of entertainment and education", 
       "the film provides some great insight", 
       "this is a film well worth seeing", 
       "a masterpiece four years in the making", 
       "offers a breath of the fresh air of true sophistication"] 
test_corpus = ["this is a really positive review, great film"] 
train_response = np.array([3, 1, 3, 2, 1, 5, 4, 4, 5, 5]) - 3 

#LDA parameters 
num_features = 1000 #vocabulary size 
num_topics = 4  #fixed for LDA 

tfidf = TfidfVectorizer(max_features = num_features, max_df=0.95, min_df=0, stop_words = 'english') 

#generate tf-idf term-document matrix 
A_tfidf_sp = tfidf.fit_transform(train_corpus) #size D x V 

print "number of docs: %d" %A_tfidf_sp.shape[0] 
print "dictionary size: %d" %A_tfidf_sp.shape[1] 

#tf-idf dictionary  
tfidf_dict = tfidf.get_feature_names() 

K = num_topics # number of topics 
V = A_tfidf_sp.shape[1] # number of words 
D = A_tfidf_sp.shape[0] # number of documents 

data = A_tfidf_sp.toarray() 

#Supervised LDA Graphical Model 
Wd = [len(doc) for doc in data]   
alpha = np.ones(K) 
beta = np.ones(V) 

theta = pm.Container([pm.CompletedDirichlet("theta_%s" % i, pm.Dirichlet("ptheta_%s" % i, theta=alpha)) for i in range(D)]) 
phi = pm.Container([pm.CompletedDirichlet("phi_%s" % k, pm.Dirichlet("pphi_%s" % k, theta=beta)) for k in range(K)])  

z = pm.Container([pm.Categorical('z_%s' % d, p = theta[d], size=Wd[d], value=np.random.randint(K, size=Wd[d])) for d in range(D)]) 

@pm.deterministic 
def zbar(z=z):  
    zbar_list = [] 
    for i in range(len(z)): 
     hist, bin_edges = np.histogram(z[i], bins=K) 
     zbar_list.append(hist/float(np.sum(hist)))     
    return pm.Container(zbar_list) 

eta = pm.Container([pm.Normal("eta_%s" % k, mu=0, tau=1.0/10**2) for k in range(K)]) 
y_tau = pm.Gamma("tau", alpha=0.1, beta=0.1) 

@pm.deterministic 
def y_mu(eta=eta, zbar=zbar): 
    y_mu_list = [] 
    for i in range(len(zbar)): 
     y_mu_list.append(np.dot(eta, zbar[i])) 
    return pm.Container(y_mu_list) 

#response likelihood 
y = pm.Container([pm.Normal("y_%s" % d, mu=y_mu[d], tau=y_tau, value=train_response[d], observed=True) for d in range(D)]) 

# cannot use p=phi[z[d][i]] here since phi is an ordinary list while z[d][i] is stochastic 
w = pm.Container([pm.Categorical("w_%i_%i" % (d,i), p = pm.Lambda('phi_z_%i_%i' % (d,i), lambda z=z[d][i], phi=phi: phi[z]), 
        value=data[d][i], observed=True) for d in range(D) for i in range(Wd[d])]) 

model = pm.Model([theta, phi, z, eta, y, w]) 
mcmc = pm.MCMC(model) 
mcmc.sample(iter=1000, burn=100, thin=2) 

#visualize topics  
phi0_samples = np.squeeze(mcmc.trace('phi_0')[:]) 
phi1_samples = np.squeeze(mcmc.trace('phi_1')[:]) 
phi2_samples = np.squeeze(mcmc.trace('phi_2')[:]) 
phi3_samples = np.squeeze(mcmc.trace('phi_3')[:]) 
ax = plt.subplot(221) 
plt.bar(np.arange(V), phi0_samples[-1,:]) 
ax = plt.subplot(222) 
plt.bar(np.arange(V), phi1_samples[-1,:]) 
ax = plt.subplot(223) 
plt.bar(np.arange(V), phi2_samples[-1,:]) 
ax = plt.subplot(224) 
plt.bar(np.arange(V), phi3_samples[-1,:]) 
plt.show() 

由於訓練數據(觀察到的單詞和響應變量),我們可以瞭解到全球主題(測試版)和迴歸係數(ETA)爲除預測響應變量(Y)以每個文檔的主題比例(theta)。 爲了使的Y的預測給出的教訓β和ETA,我們可以定義一個新的模式,我們不遵守Y和用以前學過的測試和ETA,得到如下結果:

sLDA prediction

在這裏,我們預測了一個正面的評論(大約2給出的評論範圍爲-2到2)的測試語料庫由一個句子組成:「這是一個非常積極的評論,偉大的電影」,如後面的直方圖對。 請參閱ipython notebook以獲得完整的實施。

+0

Hi @ vadim-smolyakov,與Multinomial樸素貝葉斯不同嗎? – laguittemh

+0

是的,sLDA的目的是同時學習全球主題和本地文檔分數(例如電影評分),而Multinomial樸素貝葉斯則更側重於分類。這兩種模式都需要監督(sLDA評分和MNB級別標籤)。我爲伯努利筆記做了一些分析,這可能有幫助:https://github.com/vsmolyakov/experiments_with_python/blob/master/chp01/info_planning.ipynb –

相關問題