2016-06-29 36 views
0

Ich nehme verschiedene Dokumente aus einer Datenbank und überprüfe mit LDA (Gensim), welche Art latenter Themen in diesen Dokumenten enthalten sind. Das funktioniert ziemlich gut. Was ich tun möchte, ist in der Datenbank für jedes Dokument zu speichern, was ist das wahrscheinlichste Thema. Und ich bin mir nicht sicher, was die beste Lösung dafür ist. Ich könnte zum Beispiel am Anfang eine eindeutige ID von jedem Dokument aus der Datenbank zusammen mit der text_column extrahieren und irgendwie bearbeiten, dass ich am Ende weiß, welche ID zu welcher Themennummer gehört. Oder vielleicht sollte ich es im letzten Teil tun, wo ich die Dokumente und ihre Themen drucke. Aber ich weiß nicht, wie ich es an die Datenbank anschließe. Durch den Vergleich der text_column mit dem Dokument und Zuweisung der entsprechenden Themennummer? Wäre für jeden Kommentar dankbar.LDA gensim. Wie aktualisiert man eine Postgres-Datenbank mit der richtigen Themennummer für jedes Dokument?

stop = stopwords.words('english') 

sql = """SELECT text_column FROM table where NULLIF(text_column, '') IS NOT NULL;""" 
cur.execute(sql) 
dbrows = cur.fetchall() 
conn.commit() 

documents = [] 
    for i in dbrows: 
    documents = documents + list(i) 

# remove all the words from the stoplist and tokenize 
stoplist = stopwords.words('english') 

additional_list = set("``;''".split(";")) 

texts = [[word.lower() for word in document.split() if word.lower() not     in stoplist and word not in string.punctuation and word.lower() not in additional_list] 
    for document in documents] 

# remove words that appear less or equal of 2 times 
all_tokens = sum(texts, []) 
tokens_once = set(word for word in set(all_tokens) if all_tokens.count(word) <= 2) 
texts = [[word for word in text if word not in tokens_once] 
    for text in texts] 

dictionary = corpora.Dictionary(texts) 
corpus = [dictionary.doc2bow(text) for text in texts] 
my_num_topics = 10 

# lda itself 
lda = ldamodel.LdaModel(corpus, id2word=dictionary, num_topics=my_num_topics) 
corpus_lda = lda[corpus] 

# print the most contributing words for selected topics 
for top in lda.show_topics(my_num_topics): 
    print top 

# print the most probable topic and the document 
for l,t in izip(corpus_lda,documents): 
    selected_topic = max(l,key=lambda item:item[1]) 
    if selected_topic[1] != 1/my_num_topics: 
     selected_topic_number = selected_topic[0] 
     print selected_topic 
     print t 
+1

Normalerweise würden Sie den PK zusammen mit dem Text aus der Datenbank auswählen, wie 'SELECT id, text_column FROM table wo ...'. In Python könnten Sie dann die key-> value-Paare in ein dict (mit id als Schlüssel) oder in ein Set/Array von 2-Tupeln setzen. – wildplasser

+0

Vielen Dank! Ich habe nur Dinge in meinem Kopf überkomprimiert. Arbeitete perfekt mit 'documents.append (i)' in der ersten Schleife. Die Art und Weise, wie ich es vorher getan habe ('Dokumente = Dokumente + Liste (i)') begann Wörter auf Buchstaben zu trennen, als ich eine ID zu der ausgewählten Abfrage hinzufügte. – student

+0

Und diese Zeile ist anders, nur für den Fall, dass jemand den Code 'texts = [[word.lower() für Word in Dokument [1] .split() wenn word.lower() nicht in der Stoppliste und Wort nicht in der Zeichenfolge benötigt .punctuation und word.lower() not in additional_list] für Dokument in Dokumenten] ' – student

Antwort

0

Da wildplasster kommentiert hat, musste ich nur die ID zusammen mit der text_column auswählen. Ich habe es vorher versucht, aber mit der Art, wie ich die Daten an die Liste angehängt habe, war es nicht für die weitere Verarbeitung geeignet. Der folgende Code funktioniert und erstellt eine Tabelle mit der ID und einer Nummer des wahrscheinlichsten Themas.

stop = stopwords.words('english') 

sql = """SELECT id, text_column FROM table where NULLIF(text_column, '') IS NOT NULL;""" 
cur.execute(sql) 
dbrows = cur.fetchall() 
conn.commit() 

documents = [] 
    for i in dbrows: 
    documents.append(i) 

# remove all the words from the stoplist and tokenize 
stoplist = stopwords.words('english') 

additional_list = set("``;''".split(";")) 

texts = [[word.lower() for word in document[1].split() if word.lower() not     in stoplist and word not in string.punctuation and word.lower() not in additional_list] 
for document in documents] 

# remove words that appear less or equal of 2 times 
all_tokens = sum(texts, []) 
tokens_once = set(word for word in set(all_tokens) if all_tokens.count(word) <= 2) 
texts = [[word for word in text if word not in tokens_once] 
for text in texts] 

dictionary = corpora.Dictionary(texts) 
corpus = [dictionary.doc2bow(text) for text in texts] 
my_num_topics = 10 

# lda itself 
lda = ldamodel.LdaModel(corpus, id2word=dictionary, num_topics=my_num_topics) 
corpus_lda = lda[corpus] 

# print the most contributing words for selected topics 
for top in lda.show_topics(my_num_topics): 
    print top 

# print the most probable topic and the document 
lda_topics = [] 
for l,t in izip(corpus_lda,documents): 
    selected_topic = max(l,key=lambda item:item[1]) 
    if selected_topic[1] != 1/my_num_topics: 
     selected_topic_number = selected_topic[0] 
     lda_topics.append((selected_topic[0],int(t[0]))) 

cur.execute("""CREATE TABLE table_topic (id bigint PRIMARY KEY, topic int);""") 
for j in lda_topics: 
    my_id = j[1] 
    topic = j[0] 
    cur.execute("INSERT INTO table_topic (id, topic) VALUES (%s, %s)", (my_id,topic)) 
    conn.commit()