Skip to content

Commit

Permalink
Addressing discussion on PR
Browse files Browse the repository at this point in the history
  • Loading branch information
kennethshsu committed May 21, 2024
1 parent 1778de0 commit f1fbb43
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 1 deletion.
12 changes: 11 additions & 1 deletion chainladder/development/development.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,14 @@ def fit(self, X, y=None, sample_weight=None):
from chainladder.utils.utility_functions import num_to_nan

# Triangle must be cumulative and in "development" mode

obj = self._set_fit_groups(X).incr_to_cum().val_to_dev().copy()
xp = obj.get_array_module()

if self.fillna:
tri_array = num_to_nan((obj + self.fillna).values)
else:
tri_array = num_to_nan(obj.values.copy())

average_ = self._validate_assumption(X, self.average, axis=3)[
..., : X.shape[3] - 1
]
Expand All @@ -143,17 +144,20 @@ def fit(self, X, y=None, sample_weight=None):
if hasattr(X, "w_v2_"):
self.w_v2_ = self._set_weight_func(
factor=obj.age_to_age * X.w_v2_,
# secondary_rank=obj.iloc[..., :-1, :-1]
)
else:
self.w_v2_ = self._set_weight_func(
factor=obj.age_to_age,
# secondary_rank=obj.iloc[..., :-1, :-1]
)

self.w_ = self._assign_n_periods_weight(
obj, n_periods_
) * self._drop_adjustment(obj, link_ratio)
w = num_to_nan(self.w_ / (x ** (exponent)))
params = WeightedRegression(axis=2, thru_orig=True, xp=xp).fit(x, y, w)

if self.n_periods != 1:
params = params.sigma_fill(self.sigma_interpolation)
else:
Expand All @@ -162,11 +166,13 @@ def fit(self, X, y=None, sample_weight=None):
"of freedom to support calculation of all regression"
" statistics. Only LDFs have been calculated."
)

params.std_err_ = xp.nan_to_num(params.std_err_) + xp.nan_to_num(
(1 - xp.nan_to_num(params.std_err_ * 0 + 1))
* params.sigma_
/ xp.swapaxes(xp.sqrt(x ** (2 - exponent))[..., 0:1, :], -1, -2)
)

params = xp.concatenate((params.slope_, params.sigma_, params.std_err_), 3)
params = xp.swapaxes(params, 2, 3)
self.ldf_ = self._param_property(obj, params, 0)
Expand All @@ -176,6 +182,7 @@ def fit(self, X, y=None, sample_weight=None):
std = xp.sqrt((1 / num_to_nan(w)) * (self.sigma_**2).values)
resid = resid / num_to_nan(std)
self.std_residuals_ = resid[resid.valuation < obj.valuation_date]

return self

def transform(self, X):
Expand Down Expand Up @@ -205,7 +212,9 @@ def transform(self, X):
]
for item in triangles:
setattr(X_new, item, getattr(self, item))

X_new._set_slicers()

return X_new

def _param_property(self, X, params, idx):
Expand All @@ -220,4 +229,5 @@ def _param_property(self, X, params, idx):
obj.is_cumulative = False
obj.virtual_columns.columns = {}
obj._set_slicers()

return obj
18 changes: 18 additions & 0 deletions chainladder/development/tests/test_development.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,24 @@ def test_new_drop_7(clrd):
)


def test_new_drop_8():
tri = cl.load_sample("prism")["Paid"].sum().grain("OYDQ")

try:
cl.Development(drop_high=False).fit_transform(tri)
except:
assert False

assert (
cl.Development(drop_high=True).fit(tri).cdf_.to_frame().fillna(0).values
== cl.Development(drop_high=1).fit(tri).cdf_.to_frame().fillna(0).values
).all()
assert (
cl.Development(drop_high=True).fit(tri).cdf_.to_frame().fillna(0).values
>= cl.Development(drop_high=2).fit(tri).cdf_.to_frame().fillna(0).values
).all()


def compare_new_drop(dev, tri):
assert np.array_equal(
dev._set_weight_func(tri.age_to_age, tri.age_to_age).values,
Expand Down

0 comments on commit f1fbb43

Please sign in to comment.