def get_tail_factor(self, colname_sep='-'):
"""Estimate tail factor, idea from Thomas Mack:
Returns a tail factor based off of an exponential fit to the LDFs. This will
fail if the product of 2nd and 3rd to last LDF < 1.0001. This also fails if
the estimated tail is larger than 2.0. In other areas, exponential fit is
rejected if the slope parameter p-value >0.5. This is currently representative
of the R implementation of this package, but may be enhanced in the future to be
p-value based.
Parameters:
colname_sep : str
text to join the names of two adjacent columns representing the
age-to-age factor column name.
Returns:
Pandas.Series of the tail factor.
"""
LDF = np.array(self.get_LDF()[:self.triangle.ncol-1])
if self.tail==False:
tail_factor=1
elif len(LDF[LDF>1]) < 2:
warn("Not enough factors larger than 1.0 to fit an exponential regression.")
tail_factor = 1
elif (LDF[-3] * LDF[-2] > 1.0001):
y = Series(LDF)
x = sm.add_constant((y.index+1)[y>1])
y = LDF[LDF>1]
n, = np.where(LDF==y[-1])[0]
tail_model = sm.OLS(np.log(y-1),x).fit()
tail_factor = np.product(np.exp(tail_model.params[0] + np.array([i+2 for i in range(n,n+100)]) * tail_model.params[1]).astype(float) + 1)
if tail_factor > 2:
warn("The estimate tail factor was bigger than 2 and has been reset to 1.")
tail_factor = 1
if tail_model.f_pvalue > 0.05:
warn("The p-value of the exponential tail fit is insignificant and tail has been set to 1.")
tail_factor = 1
else:
warn("LDF[-2] * LDF[-1] is not greater than 1.0001 and tail has been set to 1.")
tail_factor = 1
return Series(tail_factor, index = [self.triangle.data.columns[-1] + colname_sep + 'Ult'])
评论列表
文章目录