Onderwerpmodellering kan een soort statistische modellering zijn voor het lokaliseren van de abstracte “onderwerpen” die zich voordoen tijdens een verzameling van documenten. Latent Dirichlet Allocation (LDA) is een voorbeeld van een topicmodel en wordt gebruikt om tekst tijdens een document te classificeren naar een specifiek onderwerp. Het bouwt een onderwerp per documentmodel en woorden per onderwerpmodel, gemodelleerd als Dirichlet-distributies.
Hier krijgen we de mogelijkheid om LDA toe te passen op een groep documenten en deze op te splitsen in onderwerpen. Laten we aan de slag gaan!
De gegevens
De dataset die we zullen gebruiken kan een lijst zijn van meer dan een miljoen nieuwsberichten die over een periode van 15 jaar worden gepubliceerd en kan worden gedownload van Kaggle.
importpanda’s als pd
data = pd.read_csv(‘abcnews-date-text.csv’, error_bad_lines=False);
data_text = data[[‘headline_text’]].
data_text[‘index’] = data_text.index
documenten = gegevens_tekst
Neem een kijkje in de info.
print(len(documenten))
afdrukken (documenten[:5])
1048575
Voorbewerking van gegevens
We zullen de volgende stappen uitvoeren:
Tokenisatie: Splits de tekst op in zinnen en dus de zinnen in woorden. Laat de woorden in kleine letters staan en neem de interpunctie weg.
Woorden die minder dan 3 tekens hebben worden verwijderd.
Alle stopwoorden worden verwijderd.
Woorden worden gelmmatiseerd – woorden in persoon worden veranderd in persoon en werkwoorden in het verleden en toekomstige tijden worden aanwezig.
Woorden worden gestampt – woorden worden gereduceerd tot hun stamvorm.
Laden van gensim- en nltk-bibliotheken
importgensim
uit gensim.utils importeren simple_preprocess
van gensim.parsing.preprocessing import STOPWORDS
van nltk.stem import WordNetLemmatizer, SnowballStemmer
van nltk.stem.porter import *
importnummer als np
np.random.seed(2018)
importnetwerk
nltk.download(‘wordnet’)
[nltk_data] Pakket wordnet downloaden naar
C: GebruikersaccountantsAppDataRoamingnltk_data…
[nltk_data] Pakket wordnet is al up-to-date!
Waar
Schrijf een functie voor het uitvoeren van lemmatisering en stamvoorbewerking op de infoset.
def lemmatize_stemming(tekst):
retour stammer.stem(WordNetLemmatizer().lemmatize(tekst, pos=’v’))
def preprocess(tekst):
resultaat = []
voor token in gensim.utils.simple_preprocess(tekst):
indien token niet in gensim.parsing.preprocessing.STOPWORDS en len(token) > 3:
resultaat.append(lemmatize_stemming(token))
terugkeerresultaat
Selecteer een document dat u na de voorbewerking wilt bekijken.
doc_sample = documenten[documenten[‘index’] == 4310].waarden[0][0].
afdrukken (‘origineel document: ‘)
woorden = []
voor woord in doc_sample.split(‘ ‘):
words.append(woord)
afdruk(woorden)
afdrukken…
print(preprocess(doc_sample))
Het originele document:
[‘regen’, ‘helpt’, ‘bevochtigt’, ‘bosbranden’]
gemerkte en gelimatiseerde document:
[‘regen’, ‘help’, ‘dempen’, ‘bushfir’]
Het werkte!
Verwerk de koptekst, sla de resultaten op als ‘processed_docs’.
verwerkte_docs = documenten[‘headline_text’].map(voorbewerking)
verwerkte_docs[:10]
Zakje met woorden op de infoset
Maak een woordenboek aan van ‘processed_docs’ met daarin het aantal keren dat een woord in de trainingsset voorkomt.
woordenboek = gensim.corpora.Dictionary(processed_docs)
tellen = 0
voor k, v in woordenboek.iteritems():
druk(k, v)
tellen += 1
als ze > 10 tellen:
pauze
0-uitzending
1 gemeente
2 besluiten
3 licenc
4 awar
5 smaad
6 verstand
7 oproep
8 infrastructuur
9 beschermen
10 top
Gensim filter_extremen
Filter de penningen uit die in
minder dan 15 documenten (absoluut aantal) of
meer dan 0,5 documenten (fractie van de totale omvang van het corpus, niet het absolute aantal).
Houd na de twee bovenstaande stappen alleen de primaire 100000 meest voorkomende lopers.
woordenboek.filter_extremes(no_below=15, no_above=0.5, keep_n=100000)
Gensim doc2bow
Voor elk document maken we een woordenboek dat rapporteert welk percentage
woorden en de manier waarop die woorden herhaaldelijk verschijnen. Sla dit op in ‘bow_corpus’, controleer dan eerder ons geselecteerde document.
bow_corpus = [woordenboek.doc2bow(doc) voor doc in verwerkte_docs].
boog_corpus[4310]
[(76, 1), (112, 1), (483, 1), (3998, 1)]
Preview Bag Of Words voor ons voorbeelddocument.
bow_doc_4310 = bow_corpus[4310].
voor i in bereik (len(bow_doc_4310)):
print(“Word {} verschijnt “tijd”. “…formaat (bow_doc_4310).
woordenboek[bow_doc_4310[i][0]],
bow_doc_4310[i][1]))
Word 76 (“bushfir”) verschijnt 1 keer.
Word 112 (“help”) verschijnt 1 keer.
Woord 483 (“regen”) verschijnt 1 keer.
Woord 3998 (“dempen”) verschijnt 1 keer.
TF-IDF
Maak tf-idf modelobject met behulp van modellen.TfidfModel op ‘bow_corpus’ en reserveer het aan ‘tfidf’, pas dan transformatie toe op het hele corpus en noem het ‘corpus_tfidf’. Tot slot bekijken we de TF-IDF scores voor ons eerste document.
van gensim importcorpora, modellen
tfidf = modellen.TfidfModel(bow_corpus)
corpus_tfidf = tfidf[bow_corpus].
uit pprint importeren pprint
voor doc in corpus_tfidf:
pprint(doc)
pauze
[(0, 0.5907943557842693),
(1, 0.3900924708457926),
(2, 0.49514546614015836),
(3, 0.5036078441840635)]
Lopende LDA met behulp van Zakje Woorden
Train ons lda-model met behulp van gensim.models.LdaMulticore en reserveer het voor ‘lda_model’.
lda_model = gensim.models.LdaMulticore(bow_corpus, num_topics=10, id2word=dictionary, passes=2, workers=2)
Voor elk onderwerp onderzoeken we de woorden die daarin voorkomen en het relatieve gewicht ervan.
voor idx, onderwerp in lda_model.print_topics(-1):
print(‘Onderwerp: {} \Meneer: {\nWords: }’.format(idx, onderwerp))
Kun je verschillende onderwerpen onderscheiden aan de hand van de woorden in elk onderwerp en de bijbehorende gewichten?
Running LDA met behulp van TF-IDF
lda_model_tfidf = gensim.models.LdaMulticore(corpus_tfidf, num_topics=10, id2word=dictionary, passes=2, workers=4)
voor idx, onderwerp in lda_model_tfidf.print_topics(-1):
print(‘Onderwerp: {} Woord: {}’.formaat (idx, onderwerp))
Nogmaals, kunt u verschillende onderwerpen onderscheiden aan de hand van de woorden in elk onderwerp en de bijbehorende gewichten?
Prestatiebeoordeling door het classificeren van voorbeelddocumenten met behulp van het LDA Bag of Words-model.
We zullen controleren waar ons testdocument zou worden geclassificeerd.
verwerkte_docs[4310]
[‘regen’, ‘help’, ‘dempen’, ‘bushfir’]
voor index, score in gesorteerd(lda_model[bow_corpus[4310]], toets=lambda tup: -1*tup[1]):
print (“NCore: {\nScore: {\nTopic: {\nTopic: \nTopic: \nScore: \nScore: \nScore: \nTopic: {}”.format(score, lda_model.print_topic(index, 10)))
Ons testdocument heeft de grootste kans om deel uit te maken van het onderwerp dat ons model heeft toegewezen, namelijk de nauwkeurige classificatie.
Prestatiebeoordeling door het classificeren van voorbeelddocumenten met behulp van het LDA TF-IDF model.
voor index, score in gesorteerd(lda_model_tfidf[bow_corpus[4310]], key=lambda tup: -1*tup[1]):
print (“NCore: {\nScore: {\nTopic.} {}”.format(score, lda_model_tfidf.print_topic(index, 10)))
Ons testdocument heeft de grootste kans om deel uit te maken van het onderwerp dat ons model heeft toegewezen, namelijk de nauwkeurige classificatie.
Testmodel op ongezien document
unseen_document = ‘Hoe een Pentagon-deal een identiteitscrisis werd voor Google’.
bow_vector = woordenboek.doc2bow(preprocess(unseen_document))
voor index, score in gesorteerd(lda_model[bow_vector], toets=lambda tup: -1*tup[1]):
print (“Score: {\t Onderwerp.”) {}”.format(score, lda_model.print_topic(index, 5)))