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

https://miro.medium.com/max/487/1*9QcQgSW5CAlsJB1YiJMA2Q.png

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]

https://miro.medium.com/max/610/1*pjav3VLRNQIFe1eWAqsHRA.png

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))

https://miro.medium.com/max/1355/1*yCd5BcHDDWMFF7emZu1VcA.png

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))

https://miro.medium.com/max/1382/1*_HZ-9HChNGIOBcWmOD5Pnw.png

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)))

https://miro.medium.com/max/1361/1*Z15r4Z41s63arOH4grauoA.png

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)))