Mi pregunta es ¿cuál es un buen umbral de corte para los temas de LDA?
He utilizado el código de esta entrada del blog Modelización de temas con asignación de Dirichlet latente en Python
En ese código, el autor muestra las 8 palabras más importantes de cada tema, pero ¿es esa la mejor opción?
Para cada distribución temática, cada palabra tiene una probabilidad y todas las probabilidades de las palabras suman 1,0
Escribí este código para imprimir hasta un umbral épsilon:
eps=0.01
for i, topic_dist in enumerate(topic_word):
wordindex=np.argsort(topic_dist)[::-1] #rev sort
w=topic_dist[wordindex] ## this is the length of all the unique words 4258
words=[np.array(vocab)[wordindex[j]] for j in range(min(n_top_words,len(wordindex))) if w[j]>eps ]
weights=['{:.3f}'.format(w[j]) for j in range(min(n_top_words,len(wordindex))) if w[j]>eps ]
print('Topic {}: {}; {}'.format(i, ', '.join(words),', '.join(weights)))
Mirando otra biblioteca gensim LdaModel Parece que el LDA no tiene originalmente la suma de las probabilidades a 1,0 así y están normalizadas, ver más abajo:
def show_topic(self, topicid, topn=10):
topic = self.state.get_lambda()[topicid]
topic = topic / topic.sum() # normalize to probability dist
...
Ejecución del código de ejemplo Asignación de Dirichlet Latente (LDA) con Python y llamando a get_lambda, se puede ver que los valores de lambda son a veces superiores a 1,0.
ldamodel.state.get_lambda()[1]
da:
array([ 1.48214337, 1.48168697, 0.50442377, 0.50399559, 0.50400832,
0.5047193 , 0.50375875, 0.50376053, 1.50224118, 0.50376574,
0.5037527 , 0.50377459, 0.50376621, 1.49831418, 1.49832577,
1.49831855, 1.49831883, 1.49831596, 1.51053093, 3.49684196,
1.49832204, 1.49832512, 0.50316907, 0.50321838, 0.50328253,
0.50319543, 0.50317986, 0.50318815, 0.50314213, 0.5031702 ,
1.49635267, 1.49634655])
¿Cuál es el mejor eps para elegir? ¿Es mejor no normalizar la dist. prob. y utilizar el valor original en un corte? ¿Es mejor utilizar el valor máximo de prob en cada tema y basar un corte en él?
¡¡En mis conjuntos de datos reales, a veces un eps de 0,01, realmente crea un tema sin palabras!!
Actualización
Jugando con diferentes números de temas, me di cuenta de que si tengo 2 temas con el load_reuters datos, obtengo esto con un eps=0.01
Topic 0: ;
Topic 1: pope; 0.013
Creo que el Tema 0 se puede interpretar como todo lo demás o que tiene que haber más temas.
arr=[]
for n in (range(2,50)):
model = lda.LDA(n_topics=n, n_iter=20, random_state=1)
model.fit(X)
topic_word = model.topic_word_ # model.components_ also works
arr.append(
(min([max(topic_word[i]) for i in range(model.n_topics)]),
max([max(topic_word[i]) for i in range(model.n_topics)])))
plt.plot(arr)
...
Así que mirando este gráfico, n es demasiado bajo si está por debajo de 5 y se aplana en algún momento después de 20...