114 lines
3.1 KiB
Python
114 lines
3.1 KiB
Python
from dataclasses import dataclass
|
|
import numpy as np
|
|
from scipy import stats
|
|
from scipy.stats import norm
|
|
import pandas as pd
|
|
|
|
@dataclass
|
|
class Zuverlaessigkeit:
|
|
|
|
def gesamtredundanz(n, u):
|
|
r = n - u
|
|
return r
|
|
|
|
|
|
def berechne_R(Q_vv, P):
|
|
R = Q_vv @ P
|
|
return R #Redundanzmatrix
|
|
|
|
|
|
def berechne_ri(R):
|
|
ri = np.diag(R)
|
|
EVi = 100.0 * ri
|
|
return ri, EVi #Redundanzanteile
|
|
|
|
|
|
def klassifiziere_ri(ri): #Klassifizierung der Redundanzanteile
|
|
if ri < 0.01:
|
|
return "nicht kontrollierbar"
|
|
elif ri < 0.10:
|
|
return "schlecht kontrollierbar"
|
|
elif ri < 0.30:
|
|
return "ausreichend kontrollierbar"
|
|
elif ri < 0.70:
|
|
return "gut kontrollierbar"
|
|
else:
|
|
return "nahezu vollständig redundant"
|
|
|
|
|
|
def globaltest(r_gesamt, sigma0_apost, sigma0_apriori, alpha):
|
|
T_G = (sigma0_apost ** 2) / (sigma0_apriori ** 2)
|
|
F_krit = stats.f.ppf(1 - alpha, r_gesamt, 10 ** 9)
|
|
H0 = T_G < F_krit
|
|
|
|
if H0:
|
|
interpretation = (
|
|
"Nullhypothese H₀ angenommen.\n"
|
|
)
|
|
else:
|
|
interpretation = (
|
|
"Nullhypothese H₀ verworfen!\n"
|
|
"Dies kann folgende Gründe haben:\n"
|
|
"→ Es befinden sich grobe Fehler im Datenmaterial.\n"
|
|
"→ Das funktionale Modell ist fehlerhaft.\n"
|
|
"→ Das stochastische Modell ist zu optimistisch."
|
|
)
|
|
|
|
return {
|
|
"r_gesamt": r_gesamt,
|
|
"sigma0_apost": sigma0_apost,
|
|
"sigma0_apriori": sigma0_apriori,
|
|
"alpha": alpha,
|
|
"T_G": T_G,
|
|
"F_krit": F_krit,
|
|
"H0_angenommen": H0,
|
|
"Interpretation": interpretation,
|
|
}
|
|
|
|
|
|
def lokaltest_innere_Zuverlaessigkeit(v, Q_vv, ri, labels, s0_apost, alpha, beta):
|
|
v = np.asarray(v, float).reshape(-1)
|
|
Q_vv = np.asarray(Q_vv, float)
|
|
ri = np.asarray(ri, float).reshape(-1)
|
|
labels = list(labels)
|
|
|
|
# Grobfehlerabschätzung:
|
|
ri_ = np.where(ri == 0, np.nan, ri)
|
|
GF = -v / ri_
|
|
|
|
# Standardabweichungen der Residuen
|
|
qv = np.diag(Q_vv).astype(float)
|
|
s_vi = float(s0_apost) * np.sqrt(qv)
|
|
|
|
# Normierte Verbesserung NV
|
|
NV = np.abs(v) / s_vi
|
|
|
|
# Quantile k und kA (zweiseitig),
|
|
k = float(norm.ppf(1 - alpha / 2))
|
|
kA = float(norm.ppf(1 - beta)) # (Testmacht 1-β)
|
|
|
|
# Nichtzentralitätsparameter δ0
|
|
nzp = k + kA
|
|
|
|
# Grenzwert für die Aufdeckbarkeit eines GF (GRZW)
|
|
GRZW_i = (s_vi / ri_) * nzp
|
|
|
|
auffaellig = NV > nzp
|
|
|
|
Lokaltest_innere_Zuv = pd.DataFrame({
|
|
"Beobachtung": labels,
|
|
"v_i": v,
|
|
"r_i": ri,
|
|
"s_vi": s_vi,
|
|
"k": k,
|
|
"NV_i": NV,
|
|
"auffaellig": auffaellig,
|
|
"GF_i": GF,
|
|
"GRZW_i": GRZW_i,
|
|
"alpha": alpha,
|
|
"beta": beta,
|
|
"kA": kA,
|
|
"δ0": nzp,
|
|
})
|
|
return Lokaltest_innere_Zuv
|