Sie implementieren können LDA überwacht mit PyMC, den Metropolis-Sampler verwendet die latenten Variablen in dem folgende grafischen Modell zu lernen:
Der Trainingskorpus besteht aus 10 Filmkritiken (5 positiven und 5 negativ) entlang mit der zugehörigen Sternbewertung für jedes Dokument. Die Sternbewertung ist als eine Antwortvariable bekannt, bei der es sich um eine Menge von Interesse handelt, die jedem Dokument zugeordnet ist. Die Dokumente und Antwortvariablen werden gemeinsam modelliert, um latente Themen zu finden, die die Antwortvariablen für zukünftige unmarkierte Dokumente am besten vorhersagen. Weitere Informationen finden Sie unter original paper. Betrachten Sie den folgenden Code ein:
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()
die Trainingsdaten (beobachtete Worte und Antwortvariablen) Da können wir die globalen Themen (beta) und Regressionskoeffizienten (eta) zur Vorhersage der Reaktion Größe (Y) zusätzlich lernen zu den Proportionen für jedes Dokument (Theta). Um Vorhersagen von Y gegeben der gelernte Beta und eta zu machen, können wir ein neues Modell definieren, wo wir beobachten Y nicht und verwenden Sie die zuvor gelernten Beta und eta das folgende Ergebnis zu erhalten:
Hier haben wir für den Testkorpus eine positive Bewertung (ca. 2 Bewertungspunkte von -2 bis 2) aus einem Satz vorhergesagt: "Das ist eine wirklich positive Bewertung, toller Film", wie der Modus des posterioren Histogramms am Recht. Eine vollständige Implementierung finden Sie unter ipython notebook.
Der andere und neuere Ansatz, der sich zu untersuchen lohnt, ist die partiell beschriftete LDA. [link] (http://research.microsoft.com/en-us/um/people/sdumais/kdd2011-pldp-final.pdf) Es entspannt die Anforderung, dass jedes Dokument im Trainingssatz ein Label haben muss. – metaforge