The following Formulas are typeset with the help of https://alexanderrodin.com/github-latex-markdown/.
Applying expectation on the model yields
This means, the model applied to the expectation values is exact.
Inserting the model into this brings up
Derive for the unknown scalar value
and setting to zero shows
or simpler and explicit
Inserting the result from the variation we get from the expectation
and folling explicit
Putting all together shows we should model as
with the error variance
def plotwithlinreguncertainty(data: pandas.DataFrame,
x: str,
y: str,
res: int = 150,
ci=.95,
globalmodell: bool = True,
**pltopts):
assert 2 * res <= len(data), f"Zu hohe Auflösung {res} für {len(data)} Werte. Zwei Einträge pro Block für Kovarianz nötig."
import matplotlib.pyplot
import numpy
import scipy.special
sigmafactor = scipy.special.erfinv(ci) * numpy.sqrt(2)
wrkdata = data[[x, y]].sort_values(x).reset_index(drop=True)
assert (wrkdata[x].is_monotonic)
fg = matplotlib.pyplot.figure(**pltopts)
ax = matplotlib.pyplot.gca()
grpcol = res*wrkdata.index.to_series() // len(wrkdata)
grpobj = wrkdata.groupby(by=grpcol)
pltdata = grpobj.mean()
Vx = grpobj.cov().xs(y, level=1)[y]
Cxy = grpobj.cov().xs(x, level=1)[y]
Vy = grpobj.cov().xs(x, level=1)[x]
if globalmodell:
covges = wrkdata.cov()
a = covges.loc[y, x] / covges.loc[x, x]
else:
a = Cxy / Vx
delta = numpy.sqrt(Vy - 2 * a * Cxy +
a * a * Vx) # Could be into if/else - Performance?
# Create Plots
lines, = ax.plot([], [])
fillcol = lines.get_color()
lines.remove()
ax.plot(pltdata[x], pltdata[y], color=fillcol)
ax.fill_between(pltdata[x],
pltdata[y] - sigmafactor * delta,
pltdata[y] + sigmafactor * delta,
facecolor=fillcol,
alpha=.15)
ax.set_xlabel(x)
ax.set_ylabel(y)
ax.set_title(f'Mean and {100*ci} % confidence bands')