-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtopic_miner.py
More file actions
143 lines (115 loc) · 5.33 KB
/
topic_miner.py
File metadata and controls
143 lines (115 loc) · 5.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import numpy as np
from gensim.models.ldamodel import LdaModel
from gensim.corpora.dictionary import Dictionary
from gensim.corpora import MmCorpus
import plotly.graph_objects as go
import plotly.io as pio
import networkx as nx
import matplotlib.pyplot as plt
if __name__ == "__main__":
# Modelle und Daten laden
model = LdaModel.load('data_outputs/topic_models/topic_model_t29.lda')
dictionary = Dictionary.load('data_outputs/topic_models/dictionary.dict')
loaded_corpus = MmCorpus('data_outputs/topic_models/bow_corpus.mm')
# Themen und ihre Top-Wörter ausgeben
for topic_id in range(model.num_topics):
words = model.show_topic(topic_id, topn=10)
topic_words = ', '.join([word for word, prob in words])
print(f"Thema {topic_id + 1}: {topic_words}")
# -------------------
# Korrelationen berechnen
# Themenverteilungen extrahieren.
topic_distributions = [model.get_document_topics(bow, minimum_probability=0) for bow in loaded_corpus]
# Nullmatrix initialisieren.
data_matrix = np.zeros((len(loaded_corpus), model.num_topics))
# Wahrscheinlichkeit, dass Thema x in Dokument y auftaucht, in die Matrix einschreiben.
for doc_id, dist in enumerate(topic_distributions):
for topic_id, prob in dist:
data_matrix[doc_id, topic_id] = prob
# Pearson-Korrelationen berechnen und als Matrix abspeichern.
correlation_matrix = np.corrcoef(data_matrix, rowvar=False)
topic_correlations = {}
label_id_map = {
1: "Gesetzgebung",
2: "Covid-19-Pandemie_I",
3: "Medizinische Versorgung",
4: "Covid-19-Pandemie_II",
5: "Kultur",
6: "Justizwesen",
7: "Hochschulwesen",
8: "Landesfinanzen_I",
9: "(Erneuerbare) Energie",
10: "Covid-19-Pandemie_III",
11: "Barrierefreiheit",
12: "ÖRR",
13: "Europäische Union",
14: "Verwaltung im Landtag_I",
15: "Gewalt/Polizei*",
16: "Familie",
17: "Wirtschaft",
18: "Russisch-ukrainischer Krieg",
19: "Landesfinanzen_II",
20: "Kommunalwesen",
21: "Verwaltung im Landtag_II",
22: "**_I",
23: "Wohnraum",
24: "Terrorismus",
25: "Migration und Asyl",
26: "Demokratie",
27: "Schulwesen",
28: "**_II",
29: "Vereinswesen"
}
# Die Indizes werden auf die Bezeichner abgebildet.
for i in range(model.num_topics):
for j in range(i + 1, model.num_topics):
key = f"{label_id_map[i + 1]}, {label_id_map[j + 1]}"
topic_correlations[key] = correlation_matrix[i, j]
# Ausgabe der Korrelationen
print(topic_correlations)
# Wir trennen Schlüssel und Werte des Dictionaries auf und speichern sie in zwei Listen.
labels, values = zip(*topic_correlations.items())
# Berechnung der Perzentile
lower_whisker = np.percentile(values, 2.5)
upper_whisker = np.percentile(values, 97.5)
print(upper_whisker, lower_whisker)
# -------------------
# Boxplot erstellen:
fig = go.Figure()
# Datensatz hinzufügen und die optischen Eigenschaften definieren.
fig.add_trace(go.Box(y=values,
boxpoints='all', # Alle Punkte anzeigen
jitter=0.5, # Punkte horizontal streuen
pointpos=-1.8, # Position der Punkte relativ zum Boxplot
# hovertemplate= f"{label, value for label, value in zip(labels, values)}",
hovertext=[f'{label}: {value}' for label, value in zip(labels, values)], # Hovertext definieren.
marker_color='blue',
name="Pearson-Korrelation"))
# Layout-Anpassungen
fig.update_layout(
title='Korrelationen zwischen Themen',
yaxis_title='Pearson-Korrelationskoeffizient',
showlegend=False
)
# Diagramm anzeigen und serialisieren
pio.write_html(fig, file='docs/correlation_boxplot.html')
#-------------------
# Das Netzwerk bedeutsamer, positiver Korrelationen erstellen:
# Wir durchsuchen das Dictionary nach allen Korrelationen, die größer als das .975-Perzentil sind.
outliers = {key: value for key, value in topic_correlations.items() if value >= upper_whisker}
# Wir instanziieren das Netzwerk und fügen die Kanten hinzu.
G = nx.Graph()
for (topic_pair, correlation) in outliers.items():
topic1, topic2 = topic_pair.split(", ")
G.add_edge(topic1, topic2, weight=correlation)
# Wir berechnen das Layout und definieren die optischen Eigenschaften.
pos = nx.spring_layout(G, seed=450, k=0.3) # Diese Parametrisierung ergab die beste "Lesbarkeit" des Netzwerks.
plt.figure(figsize=(12, 10))
edges = nx.draw_networkx_edges(G, pos, edge_color='lightblue', width=2)
nodes = nx.draw_networkx_nodes(G, pos, node_size=700, node_color='orange', edgecolors='none', linewidths=0)
labels = nx.draw_networkx_labels(G, pos, font_size=12, font_color='black')
# Wir fügen die Kantengewichte hinzu und runden sie bis auf die zweite Nachkommastelle.
edge_labels = nx.get_edge_attributes(G, 'weight')
formatted_edge_labels = {(n1, n2): f'{weight:.2f}' for (n1, n2), weight in edge_labels.items()}
nx.draw_networkx_edge_labels(G, pos, edge_labels=formatted_edge_labels, font_color='black')
plt.show()