This repository has been archived on 2025-10-27. You can view files and clone it, but cannot push or open issues or pull requests.
Files
literaturanalyse/analyse_korrelation.py

746 lines
30 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
# Terminal leeren
os.system('cls' if os.name == 'nt' else 'clear')
from ci_template import plotly_template
from datetime import datetime
import bibtexparser
import pandas as pd
import numpy as np
from scipy.stats import pearsonr
import subprocess
from slugify import slugify
# Machine Learning Tools
from sklearn.cluster import DBSCAN, AgglomerativeClustering, KMeans
from sklearn.metrics import silhouette_score
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.manifold import TSNE
from sklearn.metrics import silhouette_score
# Visualization
import plotly.express as px
import matplotlib.pyplot as plt
# Debugging and Output
from tabulate import tabulate
theme = "light" # "light" oder "dark"
# Name der BibTeX-Datei für Exportzwecke
bib_filename = "Suchergebnisse.bib"
# Zentrale Steuerung für Export-Flags
export_fig_visual = False
# Export-Flags für Visualisierungen
export_fig_clusteranalyse = export_fig_visual
export_fig_correlation_suchbegriffe_kategorien = export_fig_visual
export_fig_correlation_fu_kategorien = export_fig_visual
export_fig_correlation_fu_suchbegriffe = export_fig_visual
export_fig_correlation_indizes_kategorien = export_fig_visual
export_fig_correlation_indizes_suchbegriffe = export_fig_visual
export_fig_correlation_fu_indizes = export_fig_visual
export_fig_correlation_fu_fu = export_fig_visual
export_fig_correlation_suchbegriffe_suchbegriffe = export_fig_visual
export_fig_correlation_kategorien_kategorien = export_fig_visual
export_fig_correlation_indizes_indizes = export_fig_visual
export_fig_summary_plot = export_fig_visual
# Universelle Hilfsfunktion für Export und Titelmanipulation
def prepare_figure_export(fig, name):
# Titel ergänzen
if fig.layout.title and fig.layout.title.text:
if f"| Quelle: {bib_filename.replace('.bib', '')}" not in fig.layout.title.text:
fig.update_layout(title_text=f"{fig.layout.title.text} | Quelle: {bib_filename.replace('.bib', '')}")
# Dateiname generieren
safe_filename = slugify(f"{name}_{bib_filename.replace('.bib', '')}")
return f"{safe_filename}.html"
# Zentrale Exportfunktion
def export_and_transfer_figure(fig, function_name, export_flag):
# Plot immer anzeigen, unabhängig vom Exportflag
fig.show(config={"responsive": True})
print(f"🔄 Exportversuch: {function_name} | Aktiv: {export_flag}")
if export_flag:
export_path = prepare_figure_export(fig, function_name)
try:
fig.write_html(export_path, full_html=True, include_plotlyjs="cdn")
print(f"HTML gespeichert unter: {export_path}")
remote_path = "jochen-hanisch@sternenflottenakademie.local:/mnt/deep-space-nine/public/plot/promotion/"
result = subprocess.run(["scp", export_path, remote_path], check=True, capture_output=True, text=True)
print("✅ Übertragung erfolgreich")
# Nach erfolgreichem scp Transfer lokale Datei löschen
os.remove(export_path)
print(f"🗑️ Lokale Datei '{export_path}' wurde gelöscht.")
except Exception as e:
print(f"❌ Fehler: {str(e)}")
# BibTeX-Datei laden
bib_path = os.path.join("Research", "Charité - Universitätsmedizin Berlin", "Systematische Literaturrecherche", "Bibliothek", bib_filename)
with open(bib_path, encoding='utf-8') as bibtex_file:
bib_database = bibtexparser.load(bibtex_file)
# Template aktivieren und Farben/Styles setzen
plotly_template.set_theme(theme)
from ci_template.plotly_template import get_colors, get_plot_styles, get_standard_layout
colors = get_colors()
plot_styles = get_plot_styles()
# Aktuelles Datum
current_date = datetime.now().strftime("%Y-%m-%d")
# Suchbegriffe
tags_to_search = [
'#0:Zeitschriftenartikel:digital:learning',
'#0:Buch:digital:learning',
'#0:Buchteil:digital:learning',
'#0:Konferenz-Paper:digital:learning',
'#1:Zeitschriftenartikel:learning:management:system',
'#1:Buch:learning:management:system',
'#1:Buchteil:learning:management:system',
'#1:Konferenz-Paper:learning:management:system',
'#2:Zeitschriftenartikel:online:Lernplattform',
'#2:Buch:online:Lernplattform',
'#2:Buchteil:online:Lernplattform',
'#2:Konferenz-Paper:online:Lernplattform',
'#3:Zeitschriftenartikel:online:Lernumgebung',
'#3:Buch:online:Lernumgebung',
'#3:Buchteil:online:Lernumgebung',
'#3:Konferenz-Paper:online:Lernumgebung',
'#4:Zeitschriftenartikel:MOOC',
'#4:Buch:MOOC',
'#4:Buchteil:MOOC',
'#4:Konferenz-Paper:MOOC',
'#5:Zeitschriftenartikel:e-learning',
'#5:Buch:e-learning',
'#5:Buchteil:e-learning',
'#5:Konferenz-Paper:e-learning',
'#6:Zeitschriftenartikel:Bildung:Technologie',
'#6:Buch:Bildung:Technologie',
'#6:Buchteil:Bildung:Technologie',
'#6:Konferenz-Paper:Bildung:Technologie',
'#7:Zeitschriftenartikel:digital:Medien',
'#7:Buch:digital:Medien',
'#7:Buchteil:digital:Medien',
'#7:Konferenz-Paper:digital:Medien',
'#8:Zeitschriftenartikel:blended:learning',
'#8:Buch:blended:learning',
'#8:Buchteil:blended:learning',
'#8:Konferenz-Paper:blended:learning',
'#9:Zeitschriftenartikel:digital:lernen',
'#9:Buch:digital:lernen',
'#9:Buchteil:digital:lernen',
'#9:Konferenz-Paper:digital:lernen',
'#a:Zeitschriftenartikel:online:lernen',
'#a:Buch:online:lernen',
'#a:Buchteil:online:lernen',
'#a:Konferenz-Paper:online:lernen',
'#b:Zeitschriftenartikel:online:learning',
'#b:Buch:online:learning',
'#b:Buchteil:online:learning',
'#b:Konferenz-Paper:online:learning'
]
tags_to_search_processed = [tag.lower().replace('\\#', '#').strip() for tag in tags_to_search]
# Indizes
index_terms = [
'Lernsystemarchitektur',
'Bildungstheorien',
'Lehr- und Lerneffektivität',
'Kollaboratives Lernen',
'Bewertungsmethoden',
'Technologieintegration',
'Datenschutz und IT-Sicherheit',
'Systemanpassung',
'Krisenreaktion im Bildungsbereich',
'Forschungsansätze'
]
index_terms_processed = [term.lower().strip() for term in index_terms]
# Forschungsunterfragen
research_questions = {
'promotion:fu1': 'Akzeptanz und Nützlichkeit (FU1)',
'promotion:fu2a': 'Effekt für Lernende (FU2a)',
'promotion:fu2b': 'Effekt-Faktoren für Lehrende (FU2b)',
'promotion:fu3': 'Konzeption und Merkmale (FU3)',
'promotion:fu4a': 'Bildungswissenschaftliche Mechanismen (FU4a)',
'promotion:fu4b': 'Technisch-gestalterische Mechanismen (FU4b)',
'promotion:fu5': 'Möglichkeiten und Grenzen (FU5)',
'promotion:fu6': 'Beurteilung als Kompetenzerwerbssystem (FU6)',
'promotion:fu7': 'Inputs und Strategien (FU7)'
}
research_questions_processed = list(research_questions.keys())
# Kategorien
categories = {
'promotion:argumentation': 'Argumentation',
'promotion:kerngedanke': 'Kerngedanke',
'promotion:weiterführung': 'Weiterführung',
'promotion:schlussfolgerung': 'Schlussfolgerung'
}
categories_processed = list(categories.keys())
# Daten sammeln
data = []
# Verarbeiten der Einträge aus der BibTeX-Datenbank
for entry in bib_database.entries:
if 'keywords' in entry:
# Extrahieren und Verarbeiten der Schlagwörter
entry_keywords = set(map(str.lower, map(str.strip, entry['keywords'].replace('\\#', '#').split(','))))
row = {}
# Zuordnung der Schlagwörter zu Tags
row.update({tag: int(tag in entry_keywords) for tag in tags_to_search_processed})
# Zuordnung der Schlagwörter zu Index-Begriffen
row.update({index: int(index in entry_keywords) for index in index_terms_processed})
# Zuordnung der Schlagwörter zu Forschungsfragen
row.update({rq: int(rq in entry_keywords) for rq in research_questions_processed})
# Zuordnung der Schlagwörter zu Kategorien
row.update({cat: int(cat in entry_keywords) for cat in categories_processed})
# Titel des Eintrags hinzufügen
row['title'] = entry.get('title', 'No Title')
# Zeile zur Datenliste hinzufügen
data.append(row)
# Daten in ein DataFrame umwandeln
df = pd.DataFrame(data).fillna(0).set_index('title')
# Debugging: Zeige die ersten Zeilen des DataFrames
print("Erste Zeilen des DataFrames:")
print(df.head())
# Funktion zur Berechnung und Visualisierung bivariater Korrelationen mit Interpretation
def interpret_correlation(x_term, y_term, correlation, min_corr, max_corr):
if min_corr == max_corr:
return "Keine Variation"
third = (max_corr - min_corr) / 3
if correlation > min_corr + 2 * third:
return "Stark verbunden"
elif correlation > min_corr + third:
return "Schwach verbunden"
else:
return "Negativ verbunden"
def visualize_bivariate_correlation(df, x_terms, y_terms, title, x_label, y_label, export_flag):
"""
Visualisiert bivariate Korrelationen und zeigt Interpretationen sowie Signifikanz im Tooltip an.
Args:
df (DataFrame): Der DataFrame mit den Daten.
x_terms (list): Liste der Variablen für die x-Achse.
y_terms (list): Liste der Variablen für die y-Achse.
title (str): Titel der Visualisierung.
x_label (str): Beschriftung der x-Achse.
y_label (str): Beschriftung der y-Achse.
"""
correlations = []
for x_term in x_terms:
for y_term in y_terms:
if x_term != y_term and x_term in df.columns and y_term in df.columns:
# Daten für x und y extrahieren
x_data = df[x_term]
y_data = df[y_term]
# Robuster Prüf- und Berechnungsblock für Korrelation und Signifikanz (p-Wert)
if len(x_data) > 1 and len(y_data) > 1:
x_data = pd.to_numeric(x_data, errors='coerce')
y_data = pd.to_numeric(y_data, errors='coerce')
valid = x_data.notna() & y_data.notna()
x_valid, y_valid = x_data[valid], y_data[valid]
if x_valid.nunique() > 1 and y_valid.nunique() > 1:
corr, p_value = pearsonr(x_valid, y_valid)
if pd.notnull(corr):
abs_corr = abs(corr)
significance = 'Signifikant' if p_value < 0.05 else 'Nicht signifikant'
hover_color = colors['brightArea'] if p_value < 0.05 else colors['depthArea']
correlations.append({
'x_term': x_term,
'y_term': y_term,
'correlation': corr,
'abs_correlation': abs_corr,
'p_value': p_value,
'significance': significance,
'hover_color': hover_color,
'interpretation': (
f"Die Korrelation zwischen '{x_term}' und '{y_term}' beträgt {corr:.2f}. "
f"p-Wert: {p_value:.3e} ({significance})"
)
})
correlation_df = pd.DataFrame(correlations)
if correlation_df.empty:
print(f"⚠️ Keine exportierbare Visualisierung für: {title} DataFrame ist leer.")
return
# Berechnung des min und max Korrelationswerts
min_corr = correlation_df['correlation'].min()
max_corr = correlation_df['correlation'].max()
# Sicherstellen, dass 0 innerhalb des Bereichs von min_corr und max_corr liegt
if min_corr > 0:
min_corr = 0
if max_corr < 0:
max_corr = 0
# Berechnung des zero_position
zero_position = (0 - min_corr) / (max_corr - min_corr)
# Dynamische Farbskala, die sicherstellt, dass 0 immer weiß ist
color_scale = [
[0.0, colors['negativeHighlight']], # Start bei min_corr
[zero_position, colors['white']], # Weiß bei 0
[1.0, colors['positiveHighlight']] # Ende bei max_corr
]
# Tabelle im Terminal ausgeben
print(f"Korrelationen für: {title}")
print(tabulate(correlation_df[['x_term', 'y_term', 'correlation', 'p_value', 'significance']],
headers=['Variable X', 'Variable Y', 'Korrelation', 'p-Wert', 'Signifikanz'],
tablefmt='grid'))
# Export als CSV-Datei
csv_filename = f"Research/Charité - Universitätsmedizin Berlin/Systematische Literaturrecherche/Tabellen/correlations_{title.replace(' ', '_')}.csv"
correlation_df[['x_term', 'y_term', 'correlation', 'p_value', 'significance']].to_csv(csv_filename, index=False)
print(f"Die Ergebnisse wurden als CSV-Datei gespeichert: {csv_filename}")
# Visualisierung
fig = px.scatter(
correlation_df,
x='x_term',
y='y_term',
size='abs_correlation',
color='correlation',
hover_data={
'correlation': True,
'p_value': True,
'significance': True,
'interpretation': True, # Interpretation im Tooltip anzeigen
},
title=f'{title} (n={len(correlation_df)}, Stand: {current_date}) | Quelle: {bib_filename.replace(".bib", "")}',
labels={'x_term': x_label, 'y_term': y_label, 'correlation': 'Korrelation'},
color_continuous_scale=color_scale # Dynamische Farbskala
)
fig.update_traces(
marker=dict(
line=dict(width=1, color=colors['background'])
),
hovertemplate=(
'<b>%{customdata[0]}</b><br>'
'Korrelation: %{marker.color:.2f}<br>'
'p-Wert: %{customdata[1]:.3e}<br>'
'Signifikanz: %{customdata[2]}'
),
customdata=correlation_df[['x_term', 'p_value', 'significance']].to_numpy()
)
# Standardlayout verwenden und ggf. ergänzen, Margin dynamisch für Responsivität
fig.update_layout(
get_standard_layout(
title=f'{title} (n={len(correlation_df)}, Stand: {current_date}) | Quelle: {bib_filename.replace(".bib", "")}',
x_title=x_label,
y_title=y_label
),
xaxis=dict(
tickangle=-45,
automargin=True
), # Einheitlicher Winkel für X-Achsenbeschriftungen
yaxis=dict(
automargin=True
),
coloraxis_colorbar=dict(title='Korrelationswert'),
autosize=True,
margin=dict(l=0, r=0, t=60, b=60),
height=None,
width=None
)
export_and_transfer_figure(
fig,
title.replace(" ", "_"),
export_flag
)
# --- Einzelne Visualisierungsfunktionen für jede bivariate Korrelation ---
def visualize_suchbegriffe_vs_kategorien(export_flag):
visualize_bivariate_correlation(
df, tags_to_search_processed, categories_processed,
'Korrelation zwischen Suchbegriffen und Kategorien',
'Suchbegriffe', 'Kategorien',
export_flag
)
def visualize_forschungsunterfragen_vs_kategorien(export_flag):
visualize_bivariate_correlation(
df, research_questions_processed, categories_processed,
'Korrelation zwischen Forschungsunterfragen und Kategorien',
'Forschungsunterfragen', 'Kategorien',
export_flag
)
def visualize_forschungsunterfragen_vs_suchbegriffe(export_flag):
visualize_bivariate_correlation(
df, research_questions_processed, tags_to_search_processed,
'Korrelation zwischen Forschungsunterfragen und Suchbegriffen',
'Forschungsunterfragen', 'Suchbegriffe',
export_flag
)
def visualize_indizes_vs_kategorien(export_flag):
visualize_bivariate_correlation(
df, index_terms_processed, categories_processed,
'Korrelation zwischen Indizes und Kategorien',
'Indizes', 'Kategorien',
export_flag
)
def visualize_indizes_vs_suchbegriffe(export_flag):
visualize_bivariate_correlation(
df, index_terms_processed, tags_to_search_processed,
'Korrelation zwischen Indizes und Suchbegriffen',
'Indizes', 'Suchbegriffe',
export_flag
)
def visualize_forschungsunterfragen_vs_indizes(export_flag):
visualize_bivariate_correlation(
df, research_questions_processed, index_terms_processed,
'Korrelation zwischen Forschungsunterfragen und Indizes',
'Forschungsunterfragen', 'Indizes',
export_flag
)
def visualize_forschungsunterfragen_vs_forschungsunterfragen(export_flag):
visualize_bivariate_correlation(
df, research_questions_processed, research_questions_processed,
'Korrelation zwischen Forschungsunterfragen',
'Forschungsunterfragen', 'Forschungsunterfragen',
export_flag
)
def visualize_suchbegriffe_vs_suchbegriffe(export_flag):
visualize_bivariate_correlation(
df, tags_to_search_processed, tags_to_search_processed,
'Korrelation zwischen Suchbegriffen',
'Suchbegriffe', 'Suchbegriffe',
export_flag
)
def visualize_kategorien_vs_kategorien(export_flag):
visualize_bivariate_correlation(
df, categories_processed, categories_processed,
'Korrelation zwischen Kategorien',
'Kategorien', 'Kategorien',
export_flag
)
def visualize_indizes_vs_indizes(export_flag):
visualize_bivariate_correlation(
df, index_terms_processed, index_terms_processed,
'Korrelation zwischen Indizes',
'Indizes', 'Indizes',
export_flag
)
#======================================
cluster_colors = {
"0": colors['primaryLine'], # Cluster 0
"1": colors['secondaryLine'], # Cluster 1
"2": colors['depthArea'], # Cluster 2
"3": colors['brightArea'] # Cluster 3
}
# Vorbereitung: Positionierung entlang deduktiver Dimensionen
df['X_Dimension'] = df[[tag for tag in tags_to_search_processed if tag in df.columns]].sum(axis=1)
df['Y_Dimension'] = df[[cat for cat in categories_processed if cat in df.columns]].sum(axis=1)
df['Z_Dimension'] = df[[rq for rq in research_questions_processed if rq in df.columns]].sum(axis=1)
# Clusteranalyse mit K-Means basierend auf den deduktiven Dimensionen
features = df[['X_Dimension', 'Y_Dimension', 'Z_Dimension']]
scaler = StandardScaler()
scaled_features = scaler.fit_transform(features)
# Clusteranalyse mit K-Means basierend auf den deduktiven Dimensionen
# Prüfung auf konstante deduktive Dimensionen
if df[['X_Dimension', 'Y_Dimension', 'Z_Dimension']].nunique().eq(1).all():
print("⚠️ Alle deduktiven Dimensionen sind konstant. K-Means-Clustering wird übersprungen.")
df['KMeans_Cluster'] = 'Nicht gültig'
silhouette_avg = None
else:
try:
features = df[['X_Dimension', 'Y_Dimension', 'Z_Dimension']]
scaler = StandardScaler()
scaled_features = scaler.fit_transform(features)
# Prüfen, ob genügend Datenpunkte für das Clustering vorliegen
if len(features) < 2:
raise ValueError("Zu wenige Datenpunkte für die Clusteranalyse. Mindestens zwei Punkte erforderlich.")
# K-Means ausführen
kmeans = KMeans(n_clusters=4, random_state=42)
df['KMeans_Cluster'] = kmeans.fit_predict(scaled_features)
# Cluster als Strings umwandeln (kategorisch)
df['KMeans_Cluster'] = df['KMeans_Cluster'].astype(str)
# Dynamische Punktgröße basierend auf Wertigkeit (Summen der Dimensionen), mit klarer Klammerung und Skalierung
df['Point_Size'] = (df['X_Dimension'] + df['Y_Dimension'] + df['Z_Dimension']) * 100
# Statistik der Punktgröße ausgeben
print("Statistik der Punktgrößen:")
print(df['Point_Size'].describe())
# Silhouette-Analyse zur Bewertung der Clusterqualität
silhouette_avg = silhouette_score(scaled_features, df['KMeans_Cluster'].astype(int))
print(f"Silhouette-Score: {silhouette_avg:.4f}")
# Speichern der Clusterdaten als CSV-Datei
output_path = "Research/Charité - Universitätsmedizin Berlin/Systematische Literaturrecherche/Tabellen/cluster_data.csv"
df.to_csv(output_path, index=False)
print(f"Clusterdaten wurden als CSV gespeichert: {output_path}")
except ValueError as e:
# Fehler aufgrund unsauberer Daten
print(f"Fehler bei der Clusteranalyse: {e}")
print("Bitte überprüfen Sie die Eingabedaten. Die Clusteranalyse konnte nicht durchgeführt werden.")
# Optionale Handlung, z.B. einen Default-Wert setzen oder den Prozess erneut starten
df['KMeans_Cluster'] = 'Nicht gültig'
silhouette_avg = None
except Exception as e:
# Allgemeiner Fehler
print(f"Ein unerwarteter Fehler ist aufgetreten: {e}")
df['KMeans_Cluster'] = 'Fehler'
silhouette_avg = None
num_clusters = df['KMeans_Cluster'].nunique() if 'KMeans_Cluster' in df.columns else 0
plot_title = f"3D-deduktiv-statistische Clusteranalyse (K-Means) (n={len(df)}, Cluster={num_clusters})"
if silhouette_avg is not None:
plot_title += f" | Silhouette-Score: {silhouette_avg:.4f}"
# Relevante Spalten für die Clusterbeschreibung
relevant_columns = tags_to_search_processed + index_terms_processed + research_questions_processed + list(categories.keys())
# Cluster-Beschriftungen basierend auf den Top-Merkmalen mit Umbrüchen
cluster_means = df[relevant_columns + ['KMeans_Cluster']].groupby('KMeans_Cluster').mean()
cluster_labels = {}
for cluster in cluster_means.index:
# Sortiere relevante Spalten nach höchsten Mittelwerten
top_features = cluster_means.loc[cluster].sort_values(ascending=False).head(3)
# Erstelle die Beschriftung mit HTML-Zeilenumbrüchen
label = "<br>".join([col for col in top_features.index]) # Zeilenumbrüche einfügen
cluster_labels[str(cluster)] = label
# Statische Cluster-Beschriftungen in den DataFrame einfügen
df['Cluster_Label'] = df['KMeans_Cluster'].map(cluster_labels)
# Ausgabe der statischen Cluster-Beschriftungen
print("Cluster-Beschriftungen (inhaltlich):")
for cluster, label in cluster_labels.items():
print(f"Cluster {cluster}: {label.replace('<br>', ', ')}") # Umbrüche für die Ausgabe ersetzen
# Plotly 3D-Scatter-Plot mit deduktiven Dimensionen und dynamischer Punktgröße
plot_title += f" | Quelle: {bib_filename.replace('.bib', '')}"
fig_cluster = px.scatter_3d(
df,
x='X_Dimension',
y='Y_Dimension',
z='Z_Dimension',
color='Cluster_Label',
size='Point_Size',
size_max=100,
color_discrete_sequence=list(cluster_colors.values()),
hover_data={
'Cluster_Label': True,
'X_Dimension': True,
'Y_Dimension': True,
'Z_Dimension': True,
'Point_Size': True
},
title=plot_title,
labels={
'X_Dimension': 'Suchbegriffe',
'Y_Dimension': 'Kategorien',
'Z_Dimension': 'Forschungsfragen',
'Point_Size': 'Punktgröße',
'Cluster_Label': 'Cluster-Beschreibung'
}
)
# Layout mit Standardlayout und individuellen Ergänzungen
layout_cluster = get_standard_layout(
title=plot_title,
x_title='Suchbegriffe',
y_title='Kategorien'
)
fig_cluster.update_layout(
**layout_cluster
)
export_and_transfer_figure(
fig_cluster,
"clusteranalyse_kmeans_deduktiv",
export_fig_clusteranalyse
)
# Berechnung der Korrelationen und Erstellung der Übersicht
def analyze_correlation_quality(df, x_terms, y_terms):
"""
Berechnet die Signifikanz und Qualität der Korrelationen zwischen zwei Gruppen von Variablen.
Args:
df (DataFrame): Der DataFrame mit den Daten.
x_terms (list): Liste der Variablen für die x-Achse.
y_terms (list): Liste der Variablen für die y-Achse.
Returns:
dict: Eine strukturierte Zusammenfassung der Korrelationsergebnisse.
"""
correlation_data = []
for x_term in x_terms:
for y_term in y_terms:
if x_term != y_term and x_term in df.columns and y_term in df.columns:
x_data = df[x_term]
y_data = df[y_term]
if len(x_data) > 1 and len(y_data) > 1:
x_data = pd.to_numeric(x_data, errors='coerce')
y_data = pd.to_numeric(y_data, errors='coerce')
valid = x_data.notna() & y_data.notna()
x_valid, y_valid = x_data[valid], y_data[valid]
if x_valid.nunique() > 1 and y_valid.nunique() > 1:
corr, p_value = pearsonr(x_valid, y_valid)
if pd.notnull(corr):
correlation_data.append({
"x_term": x_term,
"y_term": y_term,
"correlation": corr,
"p_value": p_value
})
correlation_df = pd.DataFrame(correlation_data)
if correlation_df.empty:
print("Keine signifikanten Korrelationen gefunden.")
return {}
# Berechnung von Metriken
significant_count = correlation_df[correlation_df["p_value"] < 0.05].shape[0]
highly_significant_count = correlation_df[correlation_df["p_value"] < 0.01].shape[0]
very_highly_significant_count = correlation_df[correlation_df["p_value"] < 0.001].shape[0]
total_count = correlation_df.shape[0]
correlation_quality_results = {
"total_count": total_count,
"significant_count": significant_count,
"highly_significant_count": highly_significant_count,
"very_highly_significant_count": very_highly_significant_count,
"significant_ratio": significant_count / total_count if total_count > 0 else 0,
"highly_significant_ratio": highly_significant_count / total_count if total_count > 0 else 0,
"very_highly_significant_ratio": very_highly_significant_count / total_count if total_count > 0 else 0,
"avg_correlation": correlation_df["correlation"].mean(),
"non_significant_ratio": (total_count - significant_count) / total_count if total_count > 0 else 0,
}
return correlation_quality_results
# Berechnung für verschiedene Korrelationstypen
correlation_quality_results = {
"Forschungsunterfragen & Kategorien": analyze_correlation_quality(df, research_questions_processed, categories_processed),
"Forschungsunterfragen & Suchbegriffe": analyze_correlation_quality(df, research_questions_processed, tags_to_search_processed),
"Forschungsunterfragen & Indizes": analyze_correlation_quality(df, research_questions_processed, index_terms_processed),
"Indizes & Kategorien": analyze_correlation_quality(df, index_terms_processed, categories_processed),
"Indizes & Suchbegriffe": analyze_correlation_quality(df, index_terms_processed, tags_to_search_processed),
"Suchbegriffe & Kategorien": analyze_correlation_quality(df, tags_to_search_processed, categories_processed),
"Indizes & Indizes": analyze_correlation_quality(df, index_terms_processed, index_terms_processed),
"Suchbegriffe & Suchbegriffe": analyze_correlation_quality(df, tags_to_search_processed, tags_to_search_processed),
"Kategorien & Kategorien": analyze_correlation_quality(df, categories_processed, categories_processed),
}
# Entferne leere Einträge aus dem Dictionary
correlation_quality_results = {k: v for k, v in correlation_quality_results.items() if v}
summary_df = pd.DataFrame({
"Korrelationstyp": correlation_quality_results.keys(),
"Gesamtanzahl": [res["total_count"] for res in correlation_quality_results.values()],
"Signifikante Korrelationen (%)": [res["significant_ratio"] * 100 for res in correlation_quality_results.values()],
"Hoch signifikante Korrelationen (%)": [res["highly_significant_ratio"] * 100 for res in correlation_quality_results.values()],
"Sehr hoch signifikante Korrelationen (%)": [res["very_highly_significant_ratio"] * 100 for res in correlation_quality_results.values()],
"Durchschnittliche Korrelation": [res["avg_correlation"] for res in correlation_quality_results.values()],
"Nicht signifikante Korrelationen (%)": [res["non_significant_ratio"] * 100 for res in correlation_quality_results.values()],
})
# Plotly-Version für interaktive Darstellung
def plot_average_correlation_plotly(summary_df):
fig = px.bar(
summary_df,
x="Korrelationstyp",
y="Durchschnittliche Korrelation",
title=f"Durchschnittliche Korrelationen pro Korrelationstyp (n={len(summary_df)}, Stand: {current_date}) | Quelle: {bib_filename.replace('.bib', '')}",
labels={"Korrelationstyp": "Korrelationstyp", "Durchschnittliche Korrelation": "Durchschnittliche Korrelation"},
color="Durchschnittliche Korrelation",
color_continuous_scale=[
[0.0, colors['negativeHighlight']],
[0.5, colors['white']],
[1.0, colors['positiveHighlight']]
]
)
fig.update_layout(
get_standard_layout(
title=f"Durchschnittliche Korrelationen pro Korrelationstyp (n={len(summary_df)}, Stand: {current_date}) | Quelle: {bib_filename.replace('.bib', '')}",
x_title="Korrelationstyp",
y_title="Durchschnittliche Korrelation"
),
xaxis=dict(
tickangle=-45,
automargin=True
),
yaxis=dict(
automargin=True
),
coloraxis_colorbar=dict(title="Korrelationswert"),
autosize=True,
margin=dict(l=60, r=40, t=80, b=80),
height=None,
width=None
)
export_and_transfer_figure(
fig,
"summary_plot",
export_fig_summary_plot
)
#============================
# Aufruf Alle möglichen bivariaten Korrelationen visualisieren
visualize_suchbegriffe_vs_kategorien(export_flag=export_fig_correlation_suchbegriffe_kategorien)
visualize_forschungsunterfragen_vs_kategorien(export_flag=export_fig_correlation_fu_kategorien)
visualize_forschungsunterfragen_vs_suchbegriffe(export_flag=export_fig_correlation_fu_suchbegriffe)
visualize_indizes_vs_kategorien(export_flag=export_fig_correlation_indizes_kategorien)
visualize_indizes_vs_suchbegriffe(export_flag=export_fig_correlation_indizes_suchbegriffe)
visualize_forschungsunterfragen_vs_indizes(export_flag=export_fig_correlation_fu_indizes)
visualize_forschungsunterfragen_vs_forschungsunterfragen(export_flag=export_fig_correlation_fu_fu)
visualize_suchbegriffe_vs_suchbegriffe(export_flag=export_fig_correlation_suchbegriffe_suchbegriffe)
visualize_kategorien_vs_kategorien(export_flag=export_fig_correlation_kategorien_kategorien)
visualize_indizes_vs_indizes(export_flag=export_fig_correlation_indizes_indizes)
plot_average_correlation_plotly(summary_df)