2024-10-02 22:15:59 +04:00

67 lines
1.9 KiB
Python

"""
Created on Wed May 04 06:09:18 2011
@author: josef
"""
import numpy as np
def mean_residual_life(x, frac=None, alpha=0.05):
'''empirical mean residual life or expected shortfall
Parameters
----------
x : 1-dimensional array_like
frac : list[float], optional
All entries must be between 0 and 1
alpha : float, default 0.05
FIXME: not actually used.
TODO:
check formula for std of mean
does not include case for all observations
last observations std is zero
vectorize loop using cumsum
frac does not work yet
'''
axis = 0 # searchsorted is 1d only
x = np.asarray(x)
nobs = x.shape[axis]
xsorted = np.sort(x, axis=axis)
if frac is None:
xthreshold = xsorted
else:
xthreshold = xsorted[np.floor(nobs * frac).astype(int)]
# use searchsorted instead of simple index in case of ties
xlargerindex = np.searchsorted(xsorted, xthreshold, side='right')
# TODO:replace loop with cumsum ?
result = []
for i in range(len(xthreshold)-1):
k_ind = xlargerindex[i]
rmean = x[k_ind:].mean()
# this does not work for last observations, nans
rstd = x[k_ind:].std()
rmstd = rstd/np.sqrt(nobs-k_ind) # std error of mean, check formula
result.append((k_ind, xthreshold[i], rmean, rmstd))
res = np.array(result)
crit = 1.96 # TODO: without loading stats, crit = -stats.t.ppf(0.05)
confint = res[:, 1:2] + crit * res[:, -1:] * np.array([[-1, 1]])
return np.column_stack((res, confint))
expected_shortfall = mean_residual_life # alias
if __name__ == "__main__":
rvs = np.random.standard_t(5, size=10)
res = mean_residual_life(rvs)
print(res)
rmean = [rvs[i:].mean() for i in range(len(rvs))]
print(res[:, 2] - rmean[1:])
res_frac = mean_residual_life(rvs, frac=[0.5])
print(res_frac)