示例#1
0
    def fit(self, X, y=None, sample_weight=None):
        """Fit the model with X.

        Parameters
        ----------
        X : Triangle-like
            Set of LDFs to which the tail will be applied.
        y : Ignored
        sample_weight : Ignored

        Returns
        -------
        self : object
            Returns the instance itself.
        """
        super().fit(X, y, sample_weight)
        xp = cp.get_array_module(X.values)
        tail = self.tail
        if self.attachment_age:
            attach_idx = xp.min(xp.where(X.ddims >= self.attachment_age))
        else:
            attach_idx = len(X.ddims) - 1
        self = self._apply_decay(X, tail, attach_idx)
        obj = Development().fit_transform(X) if 'ldf_' not in X else X
        xp = cp.get_array_module(X.values)
        if xp.max(self.tail) != 1.0:
            sigma, std_err = self._get_tail_stats(obj)
            self.sigma_.values[..., -1] = sigma[..., -1]
            self.std_err_.values[..., -1] = std_err[..., -1]
        return self
示例#2
0
 def _get_tail_prediction(self, tail_ldf):
     xp = cp.get_array_module(tail_ldf)
     accum_point = self.ldf_.shape[-1] - 1
     ave = 1 + tail_ldf[..., :accum_point]
     all = xp.prod(1 + tail_ldf[..., accum_point:], -1)[..., None]
     tail = xp.concatenate((ave, all), -1)
     return tail
示例#3
0
    def predict(self, X, sample_weight=None):
        """Predicts the chainladder ultimate on a new triangle **X**

        Parameters
        ----------
        X : Triangle
            The data used to compute the mean and standard deviation
            used for later scaling along the features axis.
        sample_weight : Triangle
            For exposure-based methods, the exposure to be used for predictions

        Returns
        -------
        X_new: Triangle

        """
        obj = copy.deepcopy(X)
        xp = cp.get_array_module(obj.values)
        obj.ldf_ = self.ldf_
        if obj.ldf_.shape[0] != obj.shape[0]:
            obj.ldf_.values = xp.repeat(obj.ldf_.values, len(obj.index), 0)
            obj.ldf_.kdims = obj.kdims
            obj.ldf_.key_labels = obj.key_labels
        obj.ultimate_ = self._get_ultimate(obj, sample_weight)
        return obj
示例#4
0
    def fit(self, X, y=None, sample_weight=None):
        """Fit the model with X.

        Parameters
        ----------
        X : Triangle-like
            Set of LDFs to which the munich adjustment will be applied.
        y : Ignored
        sample_weight : Ignored

        Returns
        -------
        self : object
            Returns the instance itself.
        """
        obj = copy.copy(X)
        xp = cp.get_array_module(obj.values)
        obj.values = xp.ones(X.shape)[..., :-1]
        ldf = xp.array([float(self.patterns[item]) for item in obj.ddims[:-1]])
        if self.style == 'cdf':
            ldf = xp.concatenate((ldf[:-1] / ldf[1:], xp.array([ldf[-1]])))
        ldf = ldf[xp.newaxis, xp.newaxis, xp.newaxis, ...]
        obj.values = obj.values * ldf
        obj.ddims = X.link_ratio.ddims
        obj.valuation = obj._valuation_triangle(obj.ddims)
        obj.nan_override = True
        obj._set_slicers()

        self.ldf_ = obj
        self.cdf_ = self._get_cdf(self)
        self.sigma_ = self.ldf_ * 0 + 1
        self.std_err_ = self.ldf_ * 0 + 1
        return self
示例#5
0
    def to_frame(self, *args, **kwargs):
        """ Converts a triangle to a pandas.DataFrame.  Requires an individual
        index and column selection to appropriately grab the 2D DataFrame.

        Returns
        -------
            pandas.DataFrame representation of the Triangle.
        """
        xp = cp.get_array_module(self.values)
        axes = [num for num, item in enumerate(self.shape) if item > 1]
        if self.shape[:2] == (1, 1):
            return self._repr_format()
        elif len(axes) == 2 or len(axes) == 1:
            tri = xp.squeeze(self.values)
            axes_lookup = {
                0: self.kdims,
                1: self.vdims,
                2: self.origin,
                3: self.ddims
            }
            if len(axes) == 2:
                return pd.DataFrame(tri,
                                    index=axes_lookup[axes[0]],
                                    columns=axes_lookup[axes[1]]).fillna(0)
            if len(axes) == 1:
                return pd.Series(tri, index=axes_lookup[axes[0]]).fillna(0)
        else:
            raise ValueError('len(index) and len(columns) must be 1.')
示例#6
0
 def agg_func(self, axis=None, *args, **kwargs):
     obj = copy.deepcopy(self)
     if axis is None:
         axis = min([num for num, _ in enumerate(obj.shape) if _ != 1])
     else:
         axis = self._get_axis(axis)
     xp = cp.get_array_module(obj.values)
     func = getattr(xp, v)
     kwargs.update({'keepdims': True})
     obj.values = func(obj.values, axis=axis, *args, **kwargs)
     if axis == 0 and obj.values.shape[axis] == 1:
         obj.kdims = np.array([None])
         obj.key_labels = [None]
     if axis == 1 and obj.values.shape[axis] == 1:
         obj.vdims = np.array([None])
     if axis == 2 and obj.values.shape[axis] == 1:
         obj.odims = np.array([None])
     if axis == 3 and obj.values.shape[axis] == 1:
         obj.ddims = np.array([None])
     obj._set_slicers()
     obj.values = obj.values * obj._expand_dims(obj._nan_triangle())
     obj.values[obj.values == 0] = np.nan
     if obj.shape == (1, 1, 1, 1):
         return obj.values[0, 0, 0, 0]
     else:
         return obj
示例#7
0
 def _get_hat(self, X, exp_incr_triangle):
     """ The hat matrix adjustment (Shapland eq3.23)"""
     xp = cp.get_array_module(X.values)
     weight_matrix = xp.diag(
         pd.DataFrame(exp_incr_triangle).unstack().dropna().values)
     design_matrix = self.design_matrix_
     hat = xp.matmul(
         xp.matmul(
             xp.matmul(
                 design_matrix,
                 xp.linalg.inv(
                     xp.matmul(design_matrix.T,
                               xp.matmul(weight_matrix, design_matrix)))),
             design_matrix.T), weight_matrix)
     hat = xp.diagonal(
         xp.sqrt(xp.divide(1, abs(1 - hat), where=(1 - hat) != 0)))
     total_length = X._nan_triangle().shape[0]
     reshaped_hat = xp.reshape(hat[:total_length], (1, total_length))
     indices = xp.nansum(X._nan_triangle(), axis=0).cumsum().astype(int)
     for num, item in enumerate(indices[:-1]):
         col_length = int(indices[num + 1] - indices[num])
         col = xp.reshape(hat[int(indices[num]):int(indices[num + 1])],
                          (1, col_length))
         nans = xp.repeat(xp.expand_dims(xp.array([xp.nan]), 0),
                          total_length - col_length,
                          axis=1)
         col = xp.concatenate((col, nans), axis=1)
         reshaped_hat = xp.concatenate((reshaped_hat, col), axis=0)
     return reshaped_hat.T
示例#8
0
 def infer_x_w(self):
     xp = cp.get_array_module(self.y)
     if self.w is None:
         self.w = xp.ones(self.y.shape)
     if self.x is None:
         self.x = xp.cumsum(xp.ones(self.y.shape), self.axis)
     return self
示例#9
0
 def _mack_recursion(self, est):
     obj = copy.copy(self.X_)
     xp = cp.get_array_module(obj.values)
     nans = self.X_._nan_triangle()[xp.newaxis, xp.newaxis]
     nans = nans * xp.ones(self.X_.shape)
     nans = xp.concatenate((nans, xp.ones(
         (*self.X_.shape[:3], 1)) * xp.nan), 3)
     nans = 1 - xp.nan_to_num(nans)
     properties = self.full_triangle_
     obj.valuation = properties.valuation
     obj.ddims = np.concatenate((properties.ddims[:len(self.X_.ddims)],
                                 np.array([properties.ddims[-1]])))
     obj.nan_override = True
     risk_arr = xp.zeros((*self.X_.shape[:3], 1))
     if est == 'param_risk':
         obj.values = self._get_risk(nans, risk_arr, obj.std_err_.values)
         obj._set_slicers()
         self.parameter_risk_ = obj
     elif est == 'process_risk':
         obj.values = self._get_risk(nans, risk_arr,
                                     self.full_std_err_.values)
         obj._set_slicers()
         self.process_risk_ = obj
     else:
         risk_arr = risk_arr[..., 0:1, :]
         obj.values = self._get_tot_param_risk(risk_arr)
         obj.odims = ['Total param risk']
         obj._set_slicers()
         self.total_parameter_risk_ = obj
示例#10
0
 def mack_std_err_(self):
     obj = copy.copy(self.parameter_risk_)
     xp = cp.get_array_module(obj.values)
     obj.values = xp.sqrt(self.parameter_risk_.values**2 +
                          self.process_risk_.values**2)
     obj._set_slicers()
     return obj
示例#11
0
 def link_ratio(self):
     xp = cp.get_array_module(self.values)
     obj = copy.deepcopy(self)
     if hasattr(obj, '_nan_triangle_'):
         del obj._nan_triangle_
     temp = obj.values.copy()
     temp[temp == 0] = np.nan
     val_array = obj.valuation.values.reshape(obj.shape[-2:], order='f')[:,
                                                                         1:]
     obj.values = temp[..., 1:] / temp[..., :-1]
     obj.ddims = np.array([
         '{}-{}'.format(obj.ddims[i], obj.ddims[i + 1])
         for i in range(len(obj.ddims) - 1)
     ])
     # Check whether we want to eliminate the last origin period
     if xp.max(xp.sum(~xp.isnan(self.values[..., -1, :]), 2) - 1) == 0:
         obj.values = obj.values[..., :-1, :]
         obj.odims = obj.odims[:-1]
         val_array = val_array[:-1, :]
     obj.valuation = pd.DatetimeIndex(
         pd.DataFrame(val_array).unstack().values).to_period(
             self._lowest_grain())
     if hasattr(obj, 'w_'):
         obj = obj * obj.w_[..., 0:1, :len(obj.odims), :]
     return obj
示例#12
0
    def predict(self, X, sample_weight=None):
        """Predicts the chainladder ultimate on a new triangle **X**

        Parameters
        ----------
        X : Triangle
            The data used to compute the mean and standard deviation
            used for later scaling along the features axis.
        sample_weight : Triangle
            For exposure-based methods, the exposure to be used for predictions

        Returns
        -------
        X_new: Triangle

        """
        obj = copy.copy(self)
        xp = cp.get_array_module(X.values)
        obj.X_ = copy.copy(X)
        obj.sample_weight = sample_weight
        if xp.unique(self.cdf_.values, axis=-2).shape[-2] == 1:
            obj.cdf_.values = xp.repeat(
                xp.unique(self.cdf_.values, axis=-2),
                len(X.odims), -2)
            obj.ldf_.values = xp.repeat(
                xp.unique(self.ldf_.values, axis=-2),
                len(X.odims), -2)
            obj.cdf_.odims = obj.ldf_.odims = obj.X_.odims
            obj.cdf_.valuation = obj.ldf_.valuation = \
                Development().fit(X).cdf_.valuation
        obj.cdf_._set_slicers()
        obj.ldf_._set_slicers()
        return obj
示例#13
0
 def _get_full_triangle_(self):
     obj = copy.copy(self.X_)
     xp = cp.get_array_module(obj.values)
     w = 1-xp.nan_to_num(obj._nan_triangle())
     extend = len(self.ldf_.ddims) - len(self.X_.ddims)
     ones = xp.ones((w.shape[-2], extend))
     w = xp.concatenate((w, ones), -1)
     obj.nan_override = True
     e_tri = \
         xp.repeat(self.ultimate_.values, self.cdf_.values.shape[3], 3) / \
         xp.unique(self.cdf_.values, axis=-2)
     e_tri = e_tri * w
     zeros = obj._expand_dims(ones - ones)
     properties = self.full_expectation_
     obj.valuation = properties.valuation
     obj.valuation_date = properties.valuation_date
     obj.ddims = properties.ddims
     obj.values = \
         xp.concatenate((xp.nan_to_num(obj.values), zeros), -1) + e_tri
     obj.values = xp.concatenate((obj.values,
                                  self.ultimate_.values), 3)
     obj.values[obj.values==0] = xp.nan
     obj._set_slicers()
     if hasattr(self.X_, '_get_process_variance'):
         obj = self.X_._get_process_variance(obj)
         self.ultimate_.values = obj.values[..., -1:]
     return obj
示例#14
0
    def fit(self, X, y=None, sample_weight=None):
        """Fit the model with X.

        Parameters
        ----------
        X : Triangle-like
            Set of LDFs to which the tail will be applied.
        y : Ignored
        sample_weight : Ignored

        Returns
        -------
        self : object
            Returns the instance itself.
        """
        super().fit(X, y, sample_weight)
        xp = cp.get_array_module(X.values)
        decay_range = self.ldf_.shape[-1]-X.shape[-1]+1
        ldfs = 1+self._get_initial_ldf(xp)*(self.decay**xp.arange(1000))
        ldfs = ldfs[:decay_range]
        ldfs[-1] = self.tail/xp.prod(ldfs[:-1])
        ldfs = X._expand_dims(ldfs[xp.newaxis])
        self.ldf_.values[..., -decay_range:] = \
            self.ldf_.values[..., -decay_range:]*ldfs
        self.cdf_ = DevelopmentBase._get_cdf(self)
        return self
示例#15
0
 def __eq__(self, other):
     xp = cp.get_array_module(self.values)
     if xp.all(xp.nan_to_num(self.values) ==
        xp.nan_to_num(other.values)):
         return True
     else:
         return False
示例#16
0
    def broadcast_axis(self, axis, value):
        """ Broadcasts (i.e. repeats) triangles along an axis.  The axis to be
        broadcast must be of length 1.

        Parameters
        ----------
        axis : str or int
            the axis to be broadcast over.
        value : axis-like
            The value of the new axis.

        TODO: Should convert value to a primitive type
        """
        obj = copy.deepcopy(self)
        axis = self._get_axis(axis)
        xp = cp.get_array_module(self.values)
        if self.shape[axis] != 1:
            raise ValueError('Axis to be broadcast must be of length 1')
        elif axis > 1:
            raise ValueError('Only index and column axes are supported')
        else:
            obj.values = xp.repeat(obj.values, len(value), axis)
            if axis == 0:
                obj.key_labels = list(value.columns)
                obj.kdims = value.values
                obj.index = value
            if axis == 1:
                obj.vdims = value.values
                obj.columns = value
        return obj
示例#17
0
 def munich_full_triangle_(self):
     full_paid = self.p_to_i_X_[0][..., 0:1]
     xp = cp.get_array_module(full_paid)
     full_incurred = self.p_to_i_X_[1][..., 0:1]
     for i in range(self.p_to_i_X_[0].shape[-1] - 1):
         paid = (self.p_to_i_ldf_[0][..., i:i + 1] +
                 self.lambda_coef_[0] * self.p_to_i_sigma_[0][..., i:i + 1]
                 / self.rho_sigma_[0][..., i:i + 1] *
                 (full_incurred[..., -1:] / full_paid[..., -1:] -
                  self.q_f_[0][..., i:i + 1])) * full_paid[..., -1:]
         inc = (self.p_to_i_ldf_[1][..., i:i + 1] +
                self.lambda_coef_[1] * self.p_to_i_sigma_[1][..., i:i + 1] /
                self.rho_sigma_[1][..., i:i + 1] *
                (full_paid[..., -1:] / full_incurred[..., -1:] -
                 self.q_f_[1][..., i:i + 1])) * full_incurred[..., -1:]
         full_incurred = xp.concatenate(
             (full_incurred,
              xp.nan_to_num(self.p_to_i_X_[1][..., i + 1:i + 2]) +
              (1 - xp.nan_to_num(self.p_to_i_X_[1][..., i + 1:i + 2] * 0 +
                                 1)) * inc),
             axis=3)
         full_paid = xp.concatenate(
             (full_paid,
              xp.nan_to_num(self.p_to_i_X_[0][..., i + 1:i + 2]) +
              (1 - xp.nan_to_num(self.p_to_i_X_[0][..., i + 1:i + 2] * 0 +
                                 1)) * paid),
             axis=3)
     return self._p_to_i_concate(full_paid, full_incurred)
示例#18
0
 def _predict_tail(self, slope, intercept, extrapolate):
     xp = cp.get_array_module(extrapolate)
     if self.curve == 'exponential':
         tail_ldf = xp.exp(slope * extrapolate + intercept)
     if self.curve == 'inverse_power':
         tail_ldf = xp.exp(intercept) * (extrapolate**slope)
     return self._get_tail_prediction(tail_ldf)
示例#19
0
 def _get_ultimate_(self, X, sample_weight, obj):
     ult = copy.copy(obj.X_)
     xp = cp.get_array_module(ult.values)
     origin, development = -2, -1  # Set axes by name
     latest = X.latest_diagonal.values
     if self.apriori_sigma != 0:
         random_state = xp.random.RandomState(self.random_state)
         apriori = random_state.normal(
             self.apriori, self.apriori_sigma, X.shape[0])
         apriori = apriori.reshape(X.shape[0],-1)[..., np.newaxis, np.newaxis]
         apriori = sample_weight.values * apriori
     else:
         apriori = sample_weight.values*self.apriori
     ult.values = \
         obj.cdf_.values[..., :ult.shape[development]]*(ult.values*0+1)
     cdf = ult.latest_diagonal.values
     cdf = (1-1/cdf)[xp.newaxis]
     exponents = xp.arange(self.n_iters+1)
     exponents = xp.reshape(exponents, tuple([len(exponents)]+[1]*4))
     cdf = cdf**exponents
     ult.values = xp.sum(cdf[:-1, ...], 0)*latest+cdf[-1, ...]*apriori
     ult.values[~xp.isfinite(ult.values)] = xp.nan
     ult.ddims = np.array([None])
     ult.valuation = pd.DatetimeIndex([pd.to_datetime('2262-04-11')] *
                                      ult.shape[origin])
     ult._set_slicers()
     return ult
示例#20
0
    def fit(self, X, y=None, sample_weight=None):
        """Fit the model with X.

        Parameters
        ----------
        X : Triangle-like
            Set of LDFs to which the tail will be applied.
        y : Ignored
        sample_weight : Triangle-like
            Exposure vector used to invoke the Cape Cod method.

        Returns
        -------
        self : object
            Returns the instance itself.
        """
        super().fit(X, y, sample_weight)
        model = ClarkLDF(growth=self.growth).fit(X,
                                                 sample_weight=sample_weight)
        xp = cp.get_array_module(X.values)
        age_offset = {'Y': 6., 'Q': 1.5, 'M': 0.5}[X.development_grain]
        tail = 1 / model.G_(
            xp.array([
                item * self._ave_period[1] + X.ddims[-1] - age_offset
                for item in range(self._ave_period[0] + 1)
            ]))
        tail = xp.concatenate((tail.values[..., :-1] / tail.values[..., -1],
                               tail.values[..., -1:]), -1)
        self.ldf_.values = xp.concatenate(
            (X.ldf_.values, xp.repeat(tail, X.shape[2], 2)), -1)
        self.cdf_ = DevelopmentBase._get_cdf(self)
        return self
示例#21
0
    def append(self, other):
        """ Append rows of other to the end of caller, returning a new object.

        Parameters
        ----------
        other : Triangle
            The data to append.

        Returns
        -------
            New Triangle with appended data.
        """
        xp = cp.get_array_module(self.values)
        return_obj = copy.deepcopy(self)
        return_obj.kdims = (return_obj.index.append(other.index)).values
        try:
            return_obj.values = xp.concatenate(
                (return_obj.values, other.values), axis=0)
        except:
            # For misaligned triangle support
            self.values = xp.concatenate(
                (return_obj.values,
                 (return_obj.iloc[:, 0] * 0 + other.values).values),
                axis=1)

        return_obj._set_slicers()
        return return_obj
示例#22
0
 def __init__(self, old_obj, by):
     xp = cp.get_array_module(old_obj.values)
     self.orig_obj = copy.deepcopy(old_obj)
     if xp == sp:
         if by != -1:
             self.idx = self.orig_obj.index.iloc[
                 self.orig_obj.values.coords[0]].reset_index(drop=True)
         else:
             self.idx = pd.DataFrame(np.repeat(
                 np.repeat(np.array([['All']]),
                           old_obj.values.coords.shape[1], 0),
                 len(old_obj.key_labels), 1),
                                     columns=old_obj.key_labels)
             by = old_obj.key_labels
         groupby = pd.concat(
             (pd.DataFrame(self.orig_obj.values.coords[1:].T,
                           columns=[1, 2, 3]), self.idx),
             axis=1)
         groupby['values'] = self.orig_obj.values.data
         by = [by] if type(by) is str else by
         self.obj = groupby.groupby(by + [1, 2, 3])
     else:
         if by != -1:
             self.idx = self.orig_obj.index.set_index(by).index
         else:
             self.idx = pd.DataFrame(np.repeat(
                 np.repeat(np.array([['All']]), old_obj.shape[0], 0),
                 len(old_obj.key_labels), 1),
                                     columns=old_obj.key_labels).set_index(
                                         old_obj.key_labels).index
             by = old_obj.key_labels
         groupby = pd.DataFrame(self.orig_obj.values.reshape(
             (self.orig_obj.shape[0], 1, 1, -1))[:, 0, 0, :],
                                index=self.idx)
         self.obj = groupby.reset_index().groupby(by)
示例#23
0
    def quantile(self, q, axis=1, *args, **kwargs):
        """ Return values at the given quantile over requested axis.  If
            Triangle is convertible to DataFrame then pandas quantile
            functionality is used instead.

        Parameters
        ----------
        q: float or array-like, default 0.5 (50% quantile)
            Value between 0 <= q <= 1, the quantile(s) to compute.
        axis:  {0, 1, ‘index’, ‘columns’} (default 1)
            Equals 0 or ‘index’ for row-wise, 1 or ‘columns’ for column-wise.

        Returns
        -------
            Triangle

        """
        xp = cp.get_array_module(self.obj.values)
        x = self.obj.values * self.old_k_by_new_k
        ignore_vector = xp.sum(xp.isnan(x), axis=1, keepdims=True) == \
            x.shape[1]
        x = xp.where(ignore_vector, 0, x)
        self.obj.values = \
            getattr(xp, 'nanpercentile')(x, q*100, axis=1, *args, **kwargs)
        self.obj.values[self.obj.values == 0] = np.nan
        return self.obj
示例#24
0
 def agg_func(self, axis=1, *args, **kwargs):
     obj = copy.deepcopy(self.obj)
     xp = cp.get_array_module(self.orig_obj.values)
     obj = getattr(self.obj, v)(*args, **kwargs)
     if xp == sp:
         obj = obj.reset_index()
         new_idx = obj[obj.columns[:-4]].drop_duplicates().reset_index(
             drop=True).reset_index().set_index(list(obj.columns[:-4]))
         obj = obj.set_index(list(obj.columns[:-4])).merge(new_idx,
                                                           how='inner',
                                                           left_index=True,
                                                           right_index=True)
         self.orig_obj.values.coords = obj[['index', 1, 2, 3]].values.T
         self.orig_obj.values.data = obj['values'].values
         self.orig_obj.values.shape = tuple(
             [len(new_idx)] + list(self.orig_obj.values.shape[1:]))
         self.orig_obj.kdims = np.array(new_idx.index)
         self.orig_obj.key_labels = list(new_idx.index.names)
     else:
         self.orig_obj.values = obj.values.reshape(len(self.idx.unique()),
                                                   *self.orig_obj.shape[1:])
         self.orig_obj.values[self.orig_obj.values == 0] = np.nan
         self.orig_obj.kdims = np.array(obj.index)
         self.orig_obj.key_labels = list(self.idx.names)
     return self.orig_obj
示例#25
0
 def _repr_format(self):
     if type(self.odims[0]) == np.datetime64:
         origin = pd.Series(self.odims).dt.to_period(self.origin_grain)
     else:
         origin = pd.Series(self.odims)
     if len(self.ddims) == 1 and self.ddims[0] is None:
         ddims = list(self.vdims)
     else:
         ddims = self.ddims
     if cp.get_array_module(self.values).__name__ == 'cupy':
         out = cp.asnumpy(self.values[0, 0])
     else:
         out = self.values[0, 0]
     out = pd.DataFrame(out, index=origin, columns=ddims)
     if str(out.columns[0]).find('-') > 0 and not \
        isinstance(out.columns, pd.PeriodIndex):
         out.columns = [
             item.replace('-9999', '-Ult') for item in out.columns
         ]
         if len(out.drop_duplicates()) != 1:
             return out
         else:
             return out.drop_duplicates().set_index(pd.Index(['(All)']))
     else:
         return out
示例#26
0
 def link_ratio(self):
     xp = cp.get_array_module(self.values)
     obj = copy.deepcopy(self)
     temp = obj.values.copy()
     val_array = obj.valuation.values.reshape(obj.shape[-2:], order='f')[:,
                                                                         1:]
     obj.ddims = np.array([
         '{}-{}'.format(obj.ddims[i], obj.ddims[i + 1])
         for i in range(len(obj.ddims) - 1)
     ])
     if xp != sp:
         temp[temp == 0] = np.nan
         obj.values = temp[..., 1:] / temp[..., :-1]
         # Check whether we want to eliminate the last origin period
         if xp.max(xp.sum(~xp.isnan(self.values[..., -1, :]), 2) - 1) <= 0:
             obj.values = obj.values[..., :-1, :]
     else:
         temp.fill_value = np.nan
         temp = temp[..., 1:] / temp[..., :-1]
         temp.fill_value = 0.0
         temp.coords = temp.coords[:, temp.data != 0]
         temp.data = temp.data[temp.data != 0]
         temp.shape = tuple(temp.coords.max(1) + 1)
         obj.values = sp(temp)
     obj.odims = obj.odims[:obj.values.shape[2]]
     if hasattr(obj, 'w_'):
         if obj.shape == obj.w_[..., 0:1, :len(obj.odims), :].shape:
             obj = obj * obj.w_[..., 0:1, :len(obj.odims), :]
     return obj
示例#27
0
 def _align_cdf(self, ultimate):
     """ Vertically align CDF to ultimate vector """
     xp = cp.get_array_module(ultimate.values)
     ultimate.values = \
         self.cdf_.values[..., :ultimate.shape[-1]]*(ultimate.values*0+1)
     cdf = ultimate.latest_diagonal.values
     return cdf
示例#28
0
    def incr_to_cum(self, inplace=False):
        """Method to convert an incremental triangle into a cumulative triangle.

        Parameters
        ----------
        inplace: bool
            Set to True will update the instance data attribute inplace

        Returns
        -------
            Updated instance of triangle accumulated along the origin
        """
        xp = cp.get_array_module(self.values)
        if inplace:
            if not self.is_cumulative:
                self.values = xp.cumsum(xp.nan_to_num(self.values), axis=3)
                self.values = self._expand_dims(
                    self.nan_triangle) * self.values
                self.num_to_nan()
                self.is_cumulative = True
                self._set_slicers()
            return self
        else:
            new_obj = copy.deepcopy(self)
            return new_obj.incr_to_cum(inplace=True)
示例#29
0
 def _assign_n_periods_weight_int(self, X, n_periods):
     ''' Zeros out weights depending on number of periods desired
         Only works for type(n_periods) == int
     '''
     xp = cp.get_array_module(X.values)
     if n_periods < 1 or n_periods >= X.shape[-2] - 1:
         return X.values * 0 + 1
     else:
         val_offset = {
             'Y': {
                 'Y': 1
             },
             'Q': {
                 'Y': 4,
                 'Q': 1
             },
             'M': {
                 'Y': 12,
                 'Q': 3,
                 'M': 1
             }
         }
         val_date_min = \
             X.valuation[X.valuation<=X.valuation_date].drop_duplicates().sort_values()
         val_date_min = \
             val_date_min[-n_periods * \
             val_offset[X.development_grain][X.origin_grain] - 1]
         w = X[X.valuation >= val_date_min]
         return xp.nan_to_num(
             (w / w).values) * X._expand_dims(X._nan_triangle())
示例#30
0
    def cum_to_incr(self, inplace=False):
        """Method to convert an cumlative triangle into a incremental triangle.

        Parameters
        ----------
            inplace: bool
                Set to True will update the instance data attribute inplace

        Returns
        -------
            Updated instance of triangle accumulated along the origin
        """
        xp = cp.get_array_module(self.values)
        if inplace:
            if self.is_cumulative or self.is_cumulative is None:
                temp = xp.nan_to_num(self.values)[..., 1:] - \
                    xp.nan_to_num(self.values)[..., :-1]
                temp = xp.concatenate((self.values[..., 0:1], temp), axis=3)
                temp = temp * self._expand_dims(self.nan_triangle)
                if xp != sp:
                    temp[temp == 0] = np.nan
                self.values = temp
                self.is_cumulative = False
                self._set_slicers()
            return self
        else:
            new_obj = copy.deepcopy(self)
            return new_obj.cum_to_incr(inplace=True)