2016-08-09 94 views
0

Ich versuche, Nachrichtenschnipsel zu analysieren, um Krisenperioden zu identifizieren. Dazu habe ich bereits in den letzten 7 Jahren Nachrichtenartikel heruntergeladen und diese zur Verfügung gestellt. Jetzt verwende ich ein LDA-Modell (Latent Dirichlet Allocation) für diesen Datensatz, um festzustellen, ob diese Länder Anzeichen einer Wirtschaftskrise aufweisen.Festlegung von "guten"/"schlechten" Fällen in einem LDA-Modell (Verwendung von Gensim in Python)

ich meinen Code auf einem Blog-Eintrag von Jordan Barber (https://rstudio-pubs-static.s3.amazonaws.com/79360_850b2a69980c4488b1db95987a24867a.html) bin stützen - hier ist mein Code so weit:

import os, csv 

#create list with text blocks in rows, based on csv file 
list=[] 

with open('Testfile.csv', 'r') as csvfile: 
    emails = csv.reader(csvfile) 
    for row in emails: 
     list.append(row) 

#create doc_set 
doc_set=[] 

for row in list: 
    doc_set.append(row[0]) 

#import plugins - need to install gensim and stop_words manually for fresh python install 
from nltk.tokenize import RegexpTokenizer 
from stop_words import get_stop_words 
from nltk.stem.porter import PorterStemmer 
from gensim import corpora, models 
import gensim 

tokenizer = RegexpTokenizer(r'\w+') 

# create English stop words list 
en_stop = get_stop_words('en') 

# Create p_stemmer of class PorterStemmer 
p_stemmer = PorterStemmer() 


# list for tokenized documents in loop 
texts = [] 

# loop through document list 
for i in doc_set: 

    # clean and tokenize document string 
    raw = i.lower() 
    tokens = tokenizer.tokenize(raw) 

    # remove stop words from tokens 
    stopped_tokens = [i for i in tokens if not i in en_stop] 

    # stem tokens 
    stemmed_tokens = [p_stemmer.stem(i) for i in stopped_tokens] 

    # add tokens to list 
    texts.append(stemmed_tokens) 


# turn our tokenized documents into a id <-> term dictionary 
dictionary = corpora.Dictionary(texts) 

# convert tokenized documents into a document-term matrix 
corpus = [dictionary.doc2bow(text) for text in texts] 

# generate LDA model 
ldamodel = gensim.models.ldamodel.LdaModel(corpus, num_topics=5, id2word = dictionary, passes=10) 

print(ldamodel.print_topics(num_topics=5, num_words=5)) 

# map topics to documents 
doc_lda=ldamodel[corpus] 

with open('doc_lda.csv', 'w') as outfile: 
    writer = csv.writer(outfile) 
    for row in doc_lda: 
     writer.writerow(row) 

Im Wesentlichen identifiziere ich eine Reihe von Themen (5 in dem obigen Code - zu überprüft werden), und über die letzte Zeile werde ich jedem Nachrichtenartikel eine Punktzahl zuweisen, die die Wahrscheinlichkeit angibt, dass ein Artikel zu einem dieser Themen gehört. Nun kann ich nur manuell eine qualitative Bewertung vornehmen, ob ein bestimmtes Thema mit einer Krise zusammenhängt, was etwas bedauerlich ist. Was ich lieber tun würde, ist, dem Algorithmus zu sagen, ob ein Artikel während einer Krise veröffentlicht wurde und diese zusätzliche Information zu verwenden, um beide Themen für meine "Krisenjahre" sowie für meine "Nicht-Krisenjahre" zu identifizieren. . Es reicht meiner Meinung nach nicht aus, meinen Datensatz einfach aufzuspalten, um nur Themen für meine "Schlechten" (dh nur Krisenjahre) zu berücksichtigen, da ich noch manuell auswählen müsste, welche Themen tatsächlich mit einer Krise zusammenhängen und welche Themen sich ergeben würden up sowieso (Sportnachrichten, ...).

Also gibt es eine Möglichkeit, den Code anzupassen, um a) die Informationen von "Krise" vs "Nicht-Krise" zu integrieren und b) automatisch die optimale Anzahl von Themen/Wörtern zu wählen, um die Vorhersagekraft des zu optimieren Modell?

Vielen Dank im Voraus!

+0

Dies ist nicht ganz geeignet für SO weil es nicht so sehr eine Programmierfrage als eine Datenanalysefrage ist, obwohl ich nicht sicher bin, wo es besser passt ... – drevicko

Antwort

0

Zunächst einige Vorschläge auf Ihre speziellen Fragen:

a) übernehmen die Informationen von „Krise“ vs „nicht-Krise“

Dazu mit einem Standard-LDA-Modell, Ich würde wahrscheinlich für gegenseitige Informationen zwischen Doc-Thema-Proportionen und ob sich Dokumente in einer Krise/Nicht-Krise befinden.

b) automatisch die optimale Anzahl von Themen/Wörtern auswählen, um die Vorhersagekraft des Modells zu optimieren?

Wenn Sie diese richtig machen, experimentieren mit vielen Einstellungen für die Anzahl der Themen und versuchen, die Themenmodelle verwenden Konflikt/nonconflict für hinhielt Unterlagen (einschließlich Unterlagen nicht enthalten im Thema-Modell) zu prognostizieren.

Es gibt viele Themenmodellvarianten, die effektiv die Anzahl der Themen auswählen ("nicht parametrische" Modelle). Es stellt sich heraus, dass die Mallet-Implementierung mit Hyperparameter-Optimierung effektiv dasselbe tut, also würde ich vorschlagen, dies zu verwenden (eine große Anzahl von Themen bereitzustellen - Hyperparameter-Optimierung wird zu vielen Themen mit sehr wenigen zugewiesenen Wörtern führen, diese Themen sind nur Rauschen).

Und einige allgemeine Bemerkungen:

Es gibt viele Themenmodellvarianten gibt, und insbesondere ein paar, die Zeit integrieren. Dies kann eine gute Wahl für Sie sein (da sie Themenänderungen im Laufe der Zeit besser lösen als Standard-LDA - obwohl Standard-LDA ein guter Ausgangspunkt ist).

Ein Modell, das ich besonders gerne verwendet pitman-yor Wort priors (besser zipf verteilen Worte als ein Dirichlet entspricht), entfallen Bursthaftigkeit in Themen und gibt Hinweise auf Junk-Themen: https://github.com/wbuntine/topic-models