in orbit/template/ktr.py [0:0]
def _set_knots_scale_matrix(self, df, training_meta):
num_of_observations = training_meta[TrainingMetaKeys.NUM_OF_OBS.value]
if self._num_of_positive_regressors > 0:
# calculate average local absolute volume for each segment
local_val = np.ones(
(self._num_of_positive_regressors, self._num_knots_coefficients)
)
if self.flat_multiplier:
multiplier = np.ones(local_val.shape)
else:
multiplier = np.ones(local_val.shape)
# store local value for the range on the left side since last knot
for idx in range(len(self._regression_knots_idx)):
if idx < len(self._regression_knots_idx) - 1:
str_idx = self._regression_knots_idx[idx]
end_idx = self._regression_knots_idx[idx + 1]
else:
str_idx = self._regression_knots_idx[idx]
end_idx = num_of_observations
local_val[:, idx] = np.mean(
np.fabs(self._positive_regressor_matrix[str_idx:end_idx]),
axis=0,
)
global_mean = np.expand_dims(
np.mean(np.fabs(self._positive_regressor_matrix), axis=0), -1
)
test_flag = local_val < 0.01 * global_mean
# adjust knot scale with the multiplier derive by the average value and shift by 0.001 to avoid zeros in
# scale parameters
multiplier[test_flag] = DEFAULT_LOWER_BOUND_SCALE_MULTIPLIER
# replace entire row of nan (when 0.1 * global_mean is equal to global_min) with upper bound
multiplier[np.isnan(multiplier).all(axis=-1)] = 1.0
# geometric drift i.e. 0.1 = 10% up-down in 1 s.d. prob.
# self._positive_regressor_knot_scale has shape num_of_pr x num_of_knot
self._positive_regressor_knot_scale = multiplier * np.expand_dims(
self._positive_regressor_knot_scale_1d, -1
)
# keep a lower bound of scale parameters
self._positive_regressor_knot_scale[
self._positive_regressor_knot_scale < 1e-4
] = 1e-4
# TODO: we change the type here, maybe we should change it earlier?
self._positive_regressor_init_knot_scale = np.array(
self._positive_regressor_init_knot_scale
)
self._positive_regressor_init_knot_scale[
self._positive_regressor_init_knot_scale < 1e-4
] = 1e-4
if self._num_of_negative_regressors > 0:
# calculate average local absolute volume for each segment
local_val = np.ones(
(self._num_of_negative_regressors, self._num_knots_coefficients)
)
if self.flat_multiplier:
multiplier = np.ones(local_val.shape)
else:
multiplier = np.ones(local_val.shape)
# store local value for the range on the left side since last knot
for idx in range(len(self._regression_knots_idx)):
if idx < len(self._regression_knots_idx) - 1:
str_idx = self._regression_knots_idx[idx]
end_idx = self._regression_knots_idx[idx + 1]
else:
str_idx = self._regression_knots_idx[idx]
end_idx = num_of_observations
local_val[:, idx] = np.mean(
np.fabs(self._negative_regressor_matrix[str_idx:end_idx]),
axis=0,
)
global_mean = np.expand_dims(
np.mean(np.fabs(self._negative_regressor_matrix), axis=0), -1
)
test_flag = local_val < 0.01 * global_mean
# adjust knot scale with the multiplier derive by the average value and shift by 0.001 to avoid zeros in
# scale parameters
multiplier[test_flag] = DEFAULT_LOWER_BOUND_SCALE_MULTIPLIER
# replace entire row of nan (when 0.1 * global_mean is equal to global_min) with upper bound
multiplier[np.isnan(multiplier).all(axis=-1)] = 1.0
# geometric drift i.e. 0.1 = 10% up-down in 1 s.d. prob.
self._negative_regressor_knot_scale = multiplier * np.expand_dims(
self._negative_regressor_knot_scale_1d, -1
)
# keep a lower bound of scale parameters
self._negative_regressor_knot_scale[
self._negative_regressor_knot_scale < 1e-4
] = 1e-4
# TODO: we change the type here, maybe we should change it earlier?
self._negative_regressor_init_knot_scale = np.array(
self._negative_regressor_init_knot_scale
)
self._negative_regressor_init_knot_scale[
self._negative_regressor_init_knot_scale < 1e-4
] = 1e-4
if self._num_of_regular_regressors > 0:
# do the same for regular regressor
# calculate average local absolute volume for each segment
local_val = np.ones(
(self._num_of_regular_regressors, self._num_knots_coefficients)
)
if self.flat_multiplier:
multiplier = np.ones(local_val.shape)
else:
multiplier = np.ones(local_val.shape)
# store local value for the range on the left side since last knot
for idx in range(len(self._regression_knots_idx)):
if idx < len(self._regression_knots_idx) - 1:
str_idx = self._regression_knots_idx[idx]
end_idx = self._regression_knots_idx[idx + 1]
else:
str_idx = self._regression_knots_idx[idx]
end_idx = num_of_observations
local_val[:, idx] = np.mean(
np.fabs(self._regular_regressor_matrix[str_idx:end_idx]), axis=0
)
# adjust knot scale with the multiplier derive by the average value and shift by 0.001 to avoid zeros in
# scale parameters
global_mean = np.expand_dims(
np.mean(np.fabs(self._regular_regressor_matrix), axis=0), -1
)
test_flag = local_val < 0.01 * global_mean
multiplier[test_flag] = DEFAULT_LOWER_BOUND_SCALE_MULTIPLIER
# replace entire row of nan (when 0.1 * global_mean is equal to global_min) with upper bound
multiplier[np.isnan(multiplier).all(axis=-1)] = 1.0
# geometric drift i.e. 0.1 = 10% up-down in 1 s.d. prob.
# self._regular_regressor_knot_scale has shape num_of_pr x num_of_knot
self._regular_regressor_knot_scale = multiplier * np.expand_dims(
self._regular_regressor_knot_scale_1d, -1
)
# keep a lower bound of scale parameters
self._regular_regressor_knot_scale[
self._regular_regressor_knot_scale < 1e-4
] = 1e-4
# TODO: we change the type here, maybe we should change it earlier?
self._regular_regressor_init_knot_scale = np.array(
self._regular_regressor_init_knot_scale
)
self._regular_regressor_init_knot_scale[
self._regular_regressor_init_knot_scale < 1e-4
] = 1e-4