Ejemplo n.º 1
0
    def test_result_does_not_depend_on_position_in_feature_dimension(self):
        norms1 = self.variance.transform(X=self.x)

        variance2 = OnlineVariance(self.n_features, rate=self.rate)
        norms2 = variance2.transform(X=np.fliplr(self.x))

        np.testing.assert_allclose(norms1, np.fliplr(norms2))
Ejemplo n.º 2
0
    def setUp(self):
        self.n_features = 3
        self.rate = 0.02
        self.variance = OnlineVariance(self.n_features, rate=self.rate)

        self.rng = np.random.default_rng(33)
        self.n_samples = 500
        self.x = self.rng.normal(size=(self.n_samples, self.n_features))
Ejemplo n.º 3
0
    def test_result_in_one_seq_independent_of_other_seqs(self):
        X1 = self.x
        norms1 = self.variance.transform(X=X1)

        X2 = np.copy(self.x)
        X2[:, 1] = self.x[:, 2]
        variance2 = OnlineVariance(self.n_features, rate=self.rate)
        norms2 = variance2.transform(X=X2)

        np.testing.assert_allclose(norms1[:, 0], norms2[:, 0])
Ejemplo n.º 4
0
    def setUp(self):
        self.n_features = 4
        self.order = 4
        self.rate = 0.01
        self.variance = OnlineVariance(self.n_features, rate=self.rate)

        self.rng = np.random.default_rng(33)
        self.n_samples = 500
        self.x = self.rng.normal(size=(self.n_samples, self.n_features))

        self.norms = self.variance.transform(X=self.x)
Ejemplo n.º 5
0
    def test_repeated_transform_same_as_single_transform_on_combined_input(self):
        norms = self.variance.transform(X=self.x)

        n1 = self.n_samples // 2
        x1 = self.x[:n1]
        x2 = self.x[n1:]

        variance_alt = OnlineVariance(self.n_features, rate=self.rate)
        norms1 = variance_alt.transform(X=x1)
        norms2 = variance_alt.transform(X=x2)

        norms_exp = np.row_stack((norms1, norms2))
        np.testing.assert_allclose(norms, norms_exp)
    def __init__(
        self,
        weights: Optional[Sequence] = None,
        n_models: Optional[int] = None,
        n_features: Optional[int] = None,
        rng: Union[int, np.random.Generator] = 0,
        variance_kws: Optional[dict] = None,
    ):
        """ Initialize the variance-based regressor.

        This chains together a `PredictionError` instance with an `OnlineVariance`.

        Parameters
        ----------
        weights
           Regression coefficients for each model, shape `(n_models, n_features)`. If
           this is provided, `n_models` and `n_features` need not be provided. If
           `weights` is not provided, it will be initialized randomly, using a standard
           normal distribution. See `rng`.
        n_models
           Number of models. If `weights` is provided, `n_models` need not be. However,
           if both are provided, then `n_models` should be equal to the number of rows
           in `weights`.
        n_features
           Number of predictor variables (features). If `weights` is provided,
           `n_features` need not be. However, if both are provided, then `n_features`
           should be equal to the number of columns in `weights`.
        rng
           Random number generator or seed to use for generating initial weight
           values. If seed, a random number generator is created using
           `np.random.default_rng`. If not provided, a seed of 0 is used. The random
           number generator is not used at all if `weights` is provided.
        variance_kws
           Additional keywords to pass to `OnlineVariance`. By default `negative` is set
           to true.
        """
        if weights is None:
            if not hasattr(rng, "normal"):
                rng = np.random.default_rng(rng)
            weights = rng.normal(size=(n_models, n_features))
        else:
            if n_models is not None and n_models != np.shape(weights)[0]:
                raise ValueError("n_models does not match shape(weights)[0]")
            if n_features is not None and n_features != np.shape(weights)[1]:
                raise ValueError("n_features does not match shape(weights)[1]")

        self.n_models = len(weights)

        self.prediction_error = PredictionError(weights)

        if variance_kws is None:
            variance_kws = {}
        variance_kws.setdefault("negative", True)
        self.variance_norm = OnlineVariance(self.n_models, **variance_kws)

        super().__init__(["prediction_error", "variance_norm"])
Ejemplo n.º 7
0
class TestOnlineVarianceNegative(unittest.TestCase):
    def setUp(self):
        self.n_features = 4
        self.order = 4
        self.rate = 0.01
        self.variance = OnlineVariance(self.n_features, rate=self.rate)

        self.rng = np.random.default_rng(33)
        self.n_samples = 500
        self.x = self.rng.normal(size=(self.n_samples, self.n_features))

        self.norms = self.variance.transform(X=self.x)

    def test_negative_returned_when_asked_for(self):
        variance_neg = OnlineVariance(self.n_features, rate=self.rate, negative=True)
        norms_neg = variance_neg.transform(X=self.x)

        np.testing.assert_allclose(norms_neg, -self.norms)
Ejemplo n.º 8
0
 def setUp(self):
     self.n_features = 3
     self.rate = 0.02
     self.variance = OnlineVariance(self.n_features, rate=self.rate)
Ejemplo n.º 9
0
class TestOnlineVarianceTransform(unittest.TestCase):
    def setUp(self):
        self.n_features = 3
        self.rate = 0.02
        self.variance = OnlineVariance(self.n_features, rate=self.rate)

        self.rng = np.random.default_rng(33)
        self.n_samples = 500
        self.x = self.rng.normal(size=(self.n_samples, self.n_features))

    def test_all_outputs_are_non_negative(self):
        norms = self.variance.transform(X=self.x)
        self.assertGreaterEqual(np.min(norms), 0)

    def test_result_does_not_depend_on_position_in_feature_dimension(self):
        norms1 = self.variance.transform(X=self.x)

        variance2 = OnlineVariance(self.n_features, rate=self.rate)
        norms2 = variance2.transform(X=np.fliplr(self.x))

        np.testing.assert_allclose(norms1, np.fliplr(norms2))

    def test_result_in_one_seq_independent_of_other_seqs(self):
        X1 = self.x
        norms1 = self.variance.transform(X=X1)

        X2 = np.copy(self.x)
        X2[:, 1] = self.x[:, 2]
        variance2 = OnlineVariance(self.n_features, rate=self.rate)
        norms2 = variance2.transform(X=X2)

        np.testing.assert_allclose(norms1[:, 0], norms2[:, 0])

    def test_initial_estimate_is_zero(self):
        norms = self.variance.transform(X=self.x)

        np.testing.assert_allclose(norms[0], self.rate * self.x[0] ** 2)

    def test_one_step_update_end(self):
        norms = self.variance.transform(X=self.x)
        diffs = np.diff(norms, axis=0)

        expected_last_diff = self.rate * (self.x[-1] ** 2 - norms[-2])
        np.testing.assert_allclose(diffs[-1], expected_last_diff)

    def test_shape_of_output_correct(self):
        norms = self.variance.transform(X=self.x)
        self.assertEqual(norms.shape, self.x.shape)

    def test_repeated_transform_same_as_single_transform_on_combined_input(self):
        norms = self.variance.transform(X=self.x)

        n1 = self.n_samples // 2
        x1 = self.x[:n1]
        x2 = self.x[n1:]

        variance_alt = OnlineVariance(self.n_features, rate=self.rate)
        norms1 = variance_alt.transform(X=x1)
        norms2 = variance_alt.transform(X=x2)

        norms_exp = np.row_stack((norms1, norms2))
        np.testing.assert_allclose(norms, norms_exp)

    def test_output_is_set_properly(self):
        norms = self.variance.transform(X=self.x)
        np.testing.assert_allclose(self.variance.output_, norms[-1])

    def test_monitor_output(self):
        monitor = AttributeMonitor(["output_"])
        norms = self.variance.transform(X=self.x, monitor=monitor)

        np.testing.assert_allclose(monitor.history_.output_, norms)
Ejemplo n.º 10
0
    def test_negative_returned_when_asked_for(self):
        variance_neg = OnlineVariance(self.n_features, rate=self.rate, negative=True)
        norms_neg = variance_neg.transform(X=self.x)

        np.testing.assert_allclose(norms_neg, -self.norms)