Visible Learning: Verbesserungen

This commit is contained in:
2025-10-11 22:04:38 +02:00
parent 08c22f9a35
commit e3b6e73414
6 changed files with 1045 additions and 1015 deletions

View File

@ -25,6 +25,12 @@ import pandas as pd
import plotly.graph_objs as go
import plotly.io as pio
# Headless-Renderer, damit fig.show() ohne Browser-Port funktioniert
try:
pio.renderers.default = "json"
except Exception:
pass
# -----------------------------------------
# Konfiguration laden (identischer Mechanismus)
# -----------------------------------------
@ -94,6 +100,13 @@ def export_json(obj: dict, name: str):
except Exception:
pass
def _safe_show(fig):
"""Verhindert Renderer-Fehler in headless-Umgebungen."""
try:
_safe_show(fig)
except Exception:
pass
# -----------------------------------------
# Daten laden und vorbereiten
# -----------------------------------------
@ -156,6 +169,18 @@ def classify_systems(df: pd.DataFrame, mapping: pd.DataFrame | None = None) -> p
out["Psych"] = 0
out["Sozial"] = 0
# 0) Direkte Angaben aus der CSV nutzen (Spalten System_psychisch / System_sozial / Systemebene)
if "System_psychisch" in out.columns:
out["Psych"] = np.maximum(out["Psych"], pd.to_numeric(out["System_psychisch"], errors="coerce").fillna(0).astype(int))
if "System_sozial" in out.columns:
out["Sozial"] = np.maximum(out["Sozial"], pd.to_numeric(out["System_sozial"], errors="coerce").fillna(0).astype(int))
if "Systemebene" in out.columns:
sys_vals = out["Systemebene"].astype(str).str.lower()
out.loc[sys_vals.str.contains("psych", na=False), "Psych"] = 1
out.loc[sys_vals.str.contains("sozi", na=False), "Sozial"] = 1
# Doppelte Markierung bei zusammengesetzten Labels (z. B. "psychisch & sozial")
out.loc[sys_vals.str.contains("psych", na=False) & sys_vals.str.contains("sozi", na=False), ["Psych", "Sozial"]] = 1
# 1) Mapping-Datei (präzise)
if mapping is not None and not mapping.empty:
sw = out["Stichwort"].astype(str).str.lower()
@ -294,12 +319,17 @@ def compute_coupling_index(df: pd.DataFrame) -> pd.DataFrame:
out = df.copy()
# Soft Scores oder Fallback
hard_p = out.get("Psych", pd.Series(0, index=out.index)).astype(float).clip(0, 1).values
hard_s = out.get("Sozial", pd.Series(0, index=out.index)).astype(float).clip(0, 1).values
if "Psych_Score" in out.columns and "Sozial_Score" in out.columns:
p = out["Psych_Score"].astype(float).values
s = out["Sozial_Score"].astype(float).values
soft_p = out["Psych_Score"].astype(float).values
soft_s = out["Sozial_Score"].astype(float).values
p = np.maximum(soft_p, hard_p)
s = np.maximum(soft_s, hard_s)
else:
p = out.get("Psych", pd.Series(0, index=out.index)).astype(float).clip(0,1).values
s = out.get("Sozial", pd.Series(0, index=out.index)).astype(float).clip(0,1).values
p = hard_p
s = hard_s
# Harmonisches Mittel (numerisch stabil)
denom = p + s
@ -382,7 +412,7 @@ def plot_sign_system_2d(df: pd.DataFrame):
))
fig.update_xaxes(range=[0,1], tickmode="array", tickvals=[0,0.25,0.5,0.75,1.0])
fig.update_yaxes(range=[0,1], tickmode="array", tickvals=[0,0.25,0.5,0.75,1.0])
fig.show()
_safe_show(fig)
export_figure(fig, "sys_erziehung_2d", export_fig_visual, export_fig_png)
def plot_sign_system_3d(df: pd.DataFrame):
@ -423,7 +453,7 @@ def plot_sign_system_3d(df: pd.DataFrame):
xaxis=dict(range=[0,1], tickmode="array", tickvals=[0,0.25,0.5,0.75,1.0]),
yaxis=dict(range=[0,1], tickmode="array", tickvals=[0,0.25,0.5,0.75,1.0])
)
fig.show()
_safe_show(fig)
export_figure(fig, "sys_erziehung_3d", export_fig_visual, export_fig_png)
def plot_rank_tables(df: pd.DataFrame, top_n: int = 15):
@ -447,7 +477,7 @@ def plot_rank_tables(df: pd.DataFrame, top_n: int = 15):
cells=dict(values=values, fill_color=_colors["depthArea"], font=dict(color=_colors["white"]))
)])
fig.update_layout(_layout(title, "", ""))
fig.show()
_safe_show(fig)
export_figure(fig, fname, export_fig_visual, export_fig_png)
top_abs = (df.assign(_absd=lambda t: t["Effektstärke"].abs())