Now we wan't to perform topic modelling with unsupervised learning and train a modell for prediction of news category labels without using the provided labels in the corpus. We use the LDA classifier on the combined feature 'title_description_text' feature and assume 7 topics.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import joblib
import pyLDAvis.lda_model
# from wordcloud
from wordcloud import WordCloud
import warnings
warnings.filterwarnings( "ignore")
train = pd.read_csv('../../data/01_train_nosplit_preprocessed.csv')
train.head()
| date | title | description | category | text | source | title_description_text | title_cleaned | title_description_text_cleaned | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 2022-06-01 00:13:42 | Preise: Grüne halten Senkung der Spritsteuer f... | Heute tritt die Steuersenkung auf Kraftstoffe ... | Other | NaN | stern | Preise: Grüne halten Senkung der Spritsteuer f... | Preis grüne halten Senkung Spritsteuer falsch ... | Preis grüne halten Senkung Spritsteuer falsch ... |
| 1 | 2022-06-01 01:55:03 | Biden warnt Putin: USA liefern moderne Raketen... | Die USA rüsten die Ukraine mit fortschrittlich... | Other | NaN | stern | Biden warnt Putin: USA liefern moderne Raketen... | Biden warnen Putin USA liefern modern Raketens... | Biden warnen Putin USA liefern modern Raketens... |
| 2 | 2022-06-01 02:04:08 | Soziale Medien: FDP-Politiker Kuhle: Internet-... | Eine «ZDF Magazin Royale»-Recherche beschäftig... | Other | NaN | stern | Soziale Medien: FDP-Politiker Kuhle: Internet-... | sozial Medium FDP-Politiker Kuhle Internet-Str... | sozial Medium FDP-Politiker Kuhle Internet-Str... |
| 3 | 2022-06-01 02:26:58 | Liveblog: ++ Zwei von drei ukrainischen Kinder... | Rund zwei von drei Mädchen und Jungen in der U... | Missing | NaN | Tagesschau | Liveblog: ++ Zwei von drei ukrainischen Kinder... | Liveblog ukrainisch Kind vertreiben | Liveblog ukrainisch Kind vertreiben rund Mädch... |
| 4 | 2022-06-01 02:31:43 | Finanzen: Dänemark stimmt über EU-Verteidigung... | Vorbehalt verteidigen oder Verteidigung ohne V... | Other | NaN | stern | Finanzen: Dänemark stimmt über EU-Verteidigung... | Finanz Dänemark stimmen EU-Verteidigungsvorbehalt | Finanz Dänemark stimmen EU-Verteidigungsvorbeh... |
stop_words = pd.read_csv('german_stopwords.txt', header=None)[0].values.tolist()
#print(stop_words)
# append words to stopwords that contain no information
stop_words += ['wegen', 'melden', 'meldet', 'können', 'könnte', 'könnten', 'update', 'neu', 'neue', 'neues', 'ohne', 'letzte', 'letzter',
'letztes', 'eins', 'zwei', 'drei', 'vier', 'fünf', 'sechs', 'sieben', 'acht', 'neun', 'zehn',
'gehen', 'geht', 'wollen', 'wollte', 'wollt', 'jahr', 'jahre', 'fordern', 'fordert',
'warnen', 'warnt', 'frühjahr', 'frühling', 'sommer', 'herbst', 'winter', 'erneut', 'deutlich', 'schwer', 'jahren', 'woche',
'wochen', 'monat', 'monate', 'tag', 'tage', 'stunden', 'stunde', 'minuten', 'minuten', 'ende', 'beenden', 'endet']
from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer(max_df=0.95, min_df=3, stop_words=stop_words)
# create Document-Term-Matrix
dtm = cv.fit_transform(train['title_description_text_cleaned'])
dtm
<67513x29998 sparse matrix of type '<class 'numpy.int64'>' with 1026097 stored elements in Compressed Sparse Row format>
from sklearn.decomposition import LatentDirichletAllocation
lda = LatentDirichletAllocation(n_components=7, random_state=42)
lda.fit(dtm)
LatentDirichletAllocation(n_components=7, random_state=42)In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
LatentDirichletAllocation(n_components=7, random_state=42)
len(cv.get_feature_names_out())
29998
#cv.get_feature_names_out()
len(lda.components_)
7
#lda.components_
len(lda.components_[0])
29998
for index, topic in enumerate(lda.components_):
print(f'Die TOP-15 Wörter für das Thema #{index}')
print([cv.get_feature_names_out()[i] for i in topic.argsort()[-15:]])
print('\n')
Die TOP-15 Wörter für das Thema #0 ['präsident', 'kreml', 'westen', 'baerbock', 'focus', 'online', 'usa', 'moskau', 'un', 'russisch', 'china', 'krieg', 'ukraine', 'putin', 'russland'] Die TOP-15 Wörter für das Thema #1 ['team', 'spiel', 'sieg', 'erster', 'dfb', 'partei', 'fc', 'bundesliga', 'frau', 'gewinnen', 'deutsch', 'fußball', 'bayern', 'wm', 'afd'] Die TOP-15 Wörter für das Thema #2 ['heute', 'stehen', 'deutschland', 'groß', 'cdu', 'geben', 'wahl', 'kanzler', 'gut', 'spd', 'deutsch', 'online', 'focus', 'scholz', 'berlin'] Die TOP-15 Wörter für das Thema #3 ['präsident', 'gipfel', 'zahl', 'generation', 'usa', 'land', 'steigen', 'biden', 'deutschland', 'pandemie', 'eu', 'geben', 'türkei', 'us', 'corona'] Die TOP-15 Wörter für das Thema #4 ['geben', 'weit', 'tote', 'iran', 'regierung', 'sterben', 'gericht', 'ex', 'usa', 'polizei', 'protest', 'trump', 'mensch', 'präsident', 'us'] Die TOP-15 Wörter für das Thema #5 ['gut', 'fdp', 'groß', 'bundesregierung', 'grüne', 'land', 'deutsch', 'gas', 'hoch', 'geben', 'ampel', 'habeck', 'eu', 'euro', 'deutschland'] Die TOP-15 Wörter für das Thema #6 ['deutschland', 'nato', 'entwicklung', 'angriff', 'putin', 'präsident', 'liveblog', 'eu', 'selenskyj', 'kiew', 'ukrainisch', 'russland', 'krieg', 'russisch', 'ukraine']
topic_results = lda.transform(dtm)
topic_results.shape
(67513, 7)
topic_results[0].round(5)
array([0.00623, 0.00622, 0.10575, 0.08399, 0.00622, 0.78537, 0.00622])
topic_results[0].argmax()
5
# save topic to train dataset
train['topic'] = topic_results.argmax(axis=1)
train.head()
| date | title | description | category | text | source | title_description_text | title_cleaned | title_description_text_cleaned | topic | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 2022-06-01 00:13:42 | Preise: Grüne halten Senkung der Spritsteuer f... | Heute tritt die Steuersenkung auf Kraftstoffe ... | Other | NaN | stern | Preise: Grüne halten Senkung der Spritsteuer f... | Preis grüne halten Senkung Spritsteuer falsch ... | Preis grüne halten Senkung Spritsteuer falsch ... | 5 |
| 1 | 2022-06-01 01:55:03 | Biden warnt Putin: USA liefern moderne Raketen... | Die USA rüsten die Ukraine mit fortschrittlich... | Other | NaN | stern | Biden warnt Putin: USA liefern moderne Raketen... | Biden warnen Putin USA liefern modern Raketens... | Biden warnen Putin USA liefern modern Raketens... | 6 |
| 2 | 2022-06-01 02:04:08 | Soziale Medien: FDP-Politiker Kuhle: Internet-... | Eine «ZDF Magazin Royale»-Recherche beschäftig... | Other | NaN | stern | Soziale Medien: FDP-Politiker Kuhle: Internet-... | sozial Medium FDP-Politiker Kuhle Internet-Str... | sozial Medium FDP-Politiker Kuhle Internet-Str... | 2 |
| 3 | 2022-06-01 02:26:58 | Liveblog: ++ Zwei von drei ukrainischen Kinder... | Rund zwei von drei Mädchen und Jungen in der U... | Missing | NaN | Tagesschau | Liveblog: ++ Zwei von drei ukrainischen Kinder... | Liveblog ukrainisch Kind vertreiben | Liveblog ukrainisch Kind vertreiben rund Mädch... | 6 |
| 4 | 2022-06-01 02:31:43 | Finanzen: Dänemark stimmt über EU-Verteidigung... | Vorbehalt verteidigen oder Verteidigung ohne V... | Other | NaN | stern | Finanzen: Dänemark stimmt über EU-Verteidigung... | Finanz Dänemark stimmen EU-Verteidigungsvorbehalt | Finanz Dänemark stimmen EU-Verteidigungsvorbeh... | 3 |
pyLDAvis.enable_notebook()
panel = pyLDAvis.lda_model.prepare(lda, dtm, cv, mds='tsne')
panel
def generate_wordclouds(nmb_terms, lda, count_vect):
for index, topic in enumerate(lda.components_):
print(f'Die TOP-{nmb_terms} Wörter für das Thema #{index}')
print([count_vect.get_feature_names_out()[index] for index in topic.argsort()[-nmb_terms:]])
print('\n')
abs_topic = abs(topic)
#print(abs_topic)
topic_terms = [[count_vect.get_feature_names_out()[i],topic[i]] for i in abs_topic.argsort()[:-nmb_terms-1:-1]]
#print(topic_terms)
topic_terms_sorted = [[count_vect.get_feature_names_out()[i], topic[i]] for i in abs_topic.argsort()[:-nmb_terms-1:-1]]
#print(topic_terms)
topic_words = []
for i in range(nmb_terms):
topic_words.append(topic_terms_sorted[i][0])
#print(','.join( word for word in topic_words))
#print("")
dict_word_frequency = {}
for i in range(nmb_terms):
dict_word_frequency[topic_terms_sorted[i][0]] = topic_terms_sorted[i][1]
wcloud = WordCloud(background_color="white",mask=None, max_words=100,
max_font_size=60,min_font_size=10,
prefer_horizontal=0.9,
contour_width=3,contour_color='black')
wcloud.generate_from_frequencies(dict_word_frequency)
plt.figure()
plt.imshow(wcloud, interpolation='bilinear')
plt.axis("off")
plt.show()
# show 15 most important words of topics
generate_wordclouds(15, lda, cv)
Die TOP-15 Wörter für das Thema #0 ['präsident', 'kreml', 'westen', 'baerbock', 'focus', 'online', 'usa', 'moskau', 'un', 'russisch', 'china', 'krieg', 'ukraine', 'putin', 'russland']
Die TOP-15 Wörter für das Thema #1 ['team', 'spiel', 'sieg', 'erster', 'dfb', 'partei', 'fc', 'bundesliga', 'frau', 'gewinnen', 'deutsch', 'fußball', 'bayern', 'wm', 'afd']
Die TOP-15 Wörter für das Thema #2 ['heute', 'stehen', 'deutschland', 'groß', 'cdu', 'geben', 'wahl', 'kanzler', 'gut', 'spd', 'deutsch', 'online', 'focus', 'scholz', 'berlin']
Die TOP-15 Wörter für das Thema #3 ['präsident', 'gipfel', 'zahl', 'generation', 'usa', 'land', 'steigen', 'biden', 'deutschland', 'pandemie', 'eu', 'geben', 'türkei', 'us', 'corona']
Die TOP-15 Wörter für das Thema #4 ['geben', 'weit', 'tote', 'iran', 'regierung', 'sterben', 'gericht', 'ex', 'usa', 'polizei', 'protest', 'trump', 'mensch', 'präsident', 'us']
Die TOP-15 Wörter für das Thema #5 ['gut', 'fdp', 'groß', 'bundesregierung', 'grüne', 'land', 'deutsch', 'gas', 'hoch', 'geben', 'ampel', 'habeck', 'eu', 'euro', 'deutschland']
Die TOP-15 Wörter für das Thema #6 ['deutschland', 'nato', 'entwicklung', 'angriff', 'putin', 'präsident', 'liveblog', 'eu', 'selenskyj', 'kiew', 'ukrainisch', 'russland', 'krieg', 'russisch', 'ukraine']
#Save result to csv
train.to_csv('evaluation/train_lda_combined_7.csv')
# Dump countvectorizer
joblib.dump(cv, 'models/cv_combined.jl')
['models/cv_combined.jl']
# Dump LDA model
joblib.dump(lda, 'models/lda_model_7_topics_combined.jl')
['models/lda_model_7_topics_combined.jl']