def setUp(self):
        """General Utilities Testing Configuration.

        Sets up the necessary information to begin testing.

        """
        self.data_shape = 100, 20
        self.label = '`visualization`'
        self.max_suplots = 20
        self.n_tests = 20
        self.name = __name__
        self.shapes = {}
        self.wrappers = {
            n: _ModelWrapperClass(m)
            for n, m in _active_models.iteritems()
        }

        p_to_shape = lambda p: p.shape
        """callable: Maps parameters to their matrix dimensions."""

        for name, ModelWrapper in self.wrappers.iteritems():
            ModelWrapper.model = dict(X=_random_matrix(self.data_shape))

            self.shapes[name] = _compose(tuple,
                                         map)(p_to_shape,
                                              ModelWrapper._model.params)

            # Model string should indicate that all parameters are set at this
            # point.
            self.assertIsNotNone(ModelWrapper._model.params)

            del ModelWrapper._model.params

            # Model string should indicate unset parameters at this point.
            self.assertIsNone(ModelWrapper._model.params)
    def test_random_visualization_plot_feature(self):
        """`visualization.Visualization.plot_feature`: Randomized Validator.

        Tests the behavior of `Visualization.plot_feature` by feeding it
        randomly generated arguments.

        Raises:
            AssertionError: If `Visualization.plot_feature` needs debugging.

        """
        for i in range(self.n_tests):
            for ModelWrapper in self.wrappers.values():
                X = _random_matrix(self.data_shape)
                """np.matrix: Random-valued feature set."""
                Y = _random_matrix((self.data_shape[0], 1))
                """np.matrix: Random-valued observation set."""

                v = Visualization("Title", (3, 3))
                """Visualization: Plotter instance."""

                # Intialize model parameters to random values.
                ModelWrapper.model = dict(X=X)

                for i in range(9):
                    x, y, error = v._plot_feature(X, Y, i, ModelWrapper)
                    """(list of float, :obj:`list of float`): X- and y-values to
                    plot."""

                    # `x` should be a list of floats.
                    self.assertIsInstance(x, list)
                    map(_appendargs(self.assertIsInstance, float), x)

                    # Number of `x` values should match number of data points in
                    # `X`.
                    self.assertEqual(len(x), X.shape[0])

                    # `x` values should match all values in `X`.
                    self.assertEqual(*map(_np.linalg.norm, [x, X[:, i]]))

                    # `y` should be a dict.
                    self.assertIsInstance(y, dict)

                    for j, values in _compose(enumerate, y.values)():
                        # `values` should be a list of floats.
                        self.assertIsInstance(values, list)
                        map(_appendargs(self.assertIsInstance, float), values)

                        # Number of values in `values` should match number of
                        # data points in `Y`.
                        self.assertEqual(len(values), Y.shape[0])

                        if j == 0:
                            # Observation values should match all values in `Y`.
                            self.assertEqual(
                                *map(_np.linalg.norm, [values, Y[:, 0]]))

                v.close()
Ejemplo n.º 3
0
    def test_random_batches(self):
        """`stats.batches`: Randomized Validator.

        Tests the behavior of `batches` by feeding it randomly generated
        arguments.

        Raises:
            AssertionError: If `batches` needs debugging.

        """
        n, d = self.data_shape
        """(int, int): Number of data points and number of features."""
        step_size = _compose(int, _np.floor)((n - 1) / float(self.n_tests))
        """int: Amount by which to increase batch-size `k` after each
        iteration."""

        for k in range(1, n, step_size):
            X = _random_matrix(self.data_shape)
            """np.matrix: Random-valued feature set."""
            Y = _random_matrix((self.data_shape[0], 1))
            """np.matrix: Random-valued observation set."""

            target_len = max(2, int(_np.floor(n / float(min(n, k)))))
            """int: Expected number of batches."""

            buckets = batches(X, Y, k)
            """list of np.matrix: Test input."""

            # `buckets` should be a list.
            self.assertIsInstance(buckets, list)

            # Each bucket `b` in `buckets` should be a matrix.
            for b in buckets:
                self.assertIsInstance(b, _np.matrix)

            # Number of buckets should match the total number of data points
            # (floor) divided by the number of data points per bucket.
            self.assertEqual(len(buckets), target_len)

            # Total number of data points across all buckets should match
            # original number of data points.
            self.assertEqual(sum([b.shape[0] for b in buckets]), n)

            norm_buckets = sum([
                sum([_np.linalg.norm(b[j, :])**2 for j in range(b.shape[0])])
                for b in buckets
            ])
            """float: Sum of the sum of the norms of all rows in all buckets."""
            norm = sum(
                [_np.linalg.norm(X[i, :])**2 + Y[i, 0]**2 for i in range(n)])
            """float: Sum of the norms of all rows in feature set plus the
            square of all data points in observation set."""

            # The norms of all bucket rows and the norms of the original dataset
            # should match when summed.
            self.assertAlmostEqual(norm_buckets, norm)
Ejemplo n.º 4
0
    def test_random_shuffle_batches(self):
        """`stats.shuffle_batches`: Randomized Validator.

        Tests the behavior of `shuffle_batches` by feeding it randomly generated
        arguments.

        Raises:
            AssertionError: If `shuffle_batches` needs debugging.

        """
        extract_shape = lambda b: b.shape
        """callable: Returns the dimensions of the given matrix."""
        row_norms = lambda b: _np.linalg.norm(b, axis=1)
        """callable: Returns the sum of all row norms in `b`."""
        aslist = lambda A: A.T[0, :].tolist()[0]
        """callable: Maps vectors to lists."""
        is_row_equal = lambda r: _compose(all, aslist)(r[0, :])
        """callable: Determines whether all entries are set to `True` in given
        element-wise equality row vector."""
        are_rows_equal = lambda v: v if isinstance(v, bool) \
                                     else _prependargs(_compose(all, map),
                                                       is_row_equal)(v)
        """callable: Determines whether all entries are set to `True` in given
        element-wise equality matrix vector."""

        for i in range(self.n_tests):
            X = _random_matrix(self.data_shape)
            """np.matrix: Random-valued feature set."""
            Y = _random_matrix((self.data_shape[0], 1))
            """np.matrix: Random-valued observation set."""

            b = batches(X, Y, 29)
            """list of np.matrix: Random-valued batches."""
            b_hat = shuffle_batches(b)
            """list of np.matrix: Test input."""

            shapes = map(extract_shape, b)
            """list of (int, int): Input batch shapes."""
            shapes_hat = map(extract_shape, b_hat)
            """list of (int, int): Output batch shapes."""

            # Re-ordered batches should be a list of np.matrix instances.
            self.assertIsInstance(b_hat, list)
            map(_appendargs(self.assertIsInstance, _np.matrix), b_hat)

            # Shapes and norms should match.
            self.assertTrue(
                _compose(all, map)(lambda shape: shape in shapes, shapes_hat))
            self.assertAlmostEqual(*map(
                _prependargs(_compose(sum, map), _compose(sum, row_norms)),
                [b, b_hat]))

            # Batches should be in different order.
            batches_not_equal = map(lambda (b1, b2): b1 != b2, zip(b, b_hat))
            """np.matrix: Element-wise equality matrix of all batches."""
            _compose(self.assertTrue, any, map)(are_rows_equal,
                                                batches_not_equal)
    def test_edge_cases_visualization_subplot(self):
        """`visualization.Visualization.subplot`: Edge Case Validator.

        Tests the behavior of `Visualization.subplot` with edge cases.

        Raises:
            Exception: If at least one `Exception` raised is not of the expected
                kind.

        """
        x = _compose(list, _np.random.uniform)(0.0,
                                               100.0,
                                               size=self.data_shape[0])
        """list of float: Random x-values."""
        values = {
            name: _compose(list, _np.random.uniform)(0.0, 100.0,
                                                     size=self.data_shape[0]) \
                  for name in ["observations", "predictions"]
        }
        """:obj:`list of float`: Contains all y-values."""

        v = Visualization("Title", (1, 1))
        """Visualization: Plotter instance."""

        for ModelWrapper in self.wrappers.values():
            with self.assertRaises(IndexError):
                # Suplot index out of range.
                v._subplot(1, x, values)

            with self.assertRaises(TypeError):
                # Empty `x`-values.
                v._subplot([], values, 0)

            with self.assertRaises(TypeError):
                # Empty `y`-values.
                v._subplot(x, {}, 0)

        v.close()
    def test_random_visualization_best_fit_lines(self):
        """`visualization.Visualization.best_fit_lines`: Randomized Validator.

        Tests the behavior of `Visualization.best_fit_lines` by feeding it
        randomly generated arguments.

        Raises:
            AssertionError: If `Visualization.best_fit_lines` needs debugging.

        """
        for i in range(self.n_tests):
            v = Visualization("Title", (3, 3))
            """Visualization: Plotter instance."""

            for i in range(9):
                x = _compose(list, _np.random.uniform)(0.0,
                                                       100.0,
                                                       size=self.data_shape[0])
                """list of float: Random x-values."""
                values = {
                    name: _compose(list,
                                   _np.random.uniform)(0.0, 100.0,
                                                       size=self.data_shape[0]) \
                          for name in ["observations", "predictions"]
                }
                """:obj:`list of float`: Contains all y-values."""

                lines = v._best_fit_lines(x, values, i)
                """list of matplotlib.lines.Line2D: Test input."""

                # Best-fit lines should be a list of Line2D instances.
                self.assertIsInstance(lines, list)
                map(_appendargs(self.assertIsInstance, _Line2D), lines)

                unique_x = _compose(list, _np.unique)(x)
                """list of float: X-values with duplicates removed."""

                for line in lines:
                    x_data = line.get_xdata()
                    """list of float: X-values in actual best-fit line."""
                    y_data = line.get_ydata()
                    """list of float: Y-values in actual best-fit line."""

                    # Number of x- and y-values in all lines should match number
                    # of unique values in `x`.
                    self.assertEqual(*map(_np.linalg.norm, [x_data, unique_x]))
                    self.assertEqual(*map(len, [y_data, unique_x]))

                    m = (y_data[1] - y_data[0]) / (x_data[1] - x_data[0])
                    """float: Best-fit line gradient."""
                    b = y_data[0] - m * x_data[0]
                    """float: Y-intercept."""

                    computed_y_vals = map(lambda val: m * val + b, x_data)
                    """list of float: Y-values computed analytically."""

                    # All lines should be rewritable in linear terms.
                    self.assertAlmostEqual(
                        *map(_np.linalg.norm, [computed_y_vals, y_data]))

            v.close()
    def test_invalid_args_visualization_subplot(self):
        """`visualization.Visualization.subplot`: Argument Validator.

        Tests the behavior of `Visualization.subplot` with invalid
        argument counts and values.

        Raises:
            Exception: If at least one `Exception` raised is not of the expected
                kind.

        """
        x = _compose(list, _np.random.uniform)(0.0,
                                               100.0,
                                               size=self.data_shape[0])
        """list of float: Random x-values."""
        values = {
            name: _compose(list, _np.random.uniform)(0.0, 100.0,
                                                     size=self.data_shape[0]) \
                  for name in ["observations", "predictions"]
        }
        """:obj:`list of float`: Contains all y-values."""

        v = Visualization("Title", (1, 1))
        """Visualization: Plotter instance."""

        with self.assertRaises(TypeError):
            # No arguments.
            v._subplot()

        with self.assertRaises(TypeError):
            # Only one argument.
            v._subplot(x)

        with self.assertRaises(TypeError):
            # Only two arguments.
            v._subplot(x, values)

        with self.assertRaises(TypeError):
            # Too many arguments.
            v._subplot(x, values, 0, "Title", "X-label", "Y-label", True,
                       "extra")

        with self.assertRaises(TypeError):
            # Invalid keyword.
            v._subplot(x, values, 0, key="value")

        with self.assertRaises(TypeError):
            # `None` instead of list `x`.
            v._subplot(None, values, 0)

        with self.assertRaises(TypeError):
            # np.matrix instead of list `x`.
            v._subplot(_np.matrix(x), values, 0)

        with self.assertRaises(TypeError):
            # `None` instead of dict of lists `values`.
            v._subplot(x, None, 0)

        with self.assertRaises(TypeError):
            value_list = {k: _np.matrix(val) for k, val in values.iteritems()}
            """:obj:`np.matrix`: Lists in `values` mapped to matrices."""

            # Dict of np.matrix instead of dict of lists `values`.
            v._subplot(x, value_list, 0)

        with self.assertRaises(TypeError):
            # List instead of dict of lists `values`.
            v._subplot(x, x, 0)

        with self.assertRaises(TypeError):
            # Incompatible x- and y-values.
            values_hat = {
                name: _compose(list, _np.random.uniform)(0.0, 100.0,
                                                         size=self.data_shape[1]) \
                      for name in ["observations", "predictions"]
            }
            """:obj:`list of float`: Contains all y-values."""
            v._subplot(x, values, 0)

        with self.assertRaises(TypeError):
            # `None` instead of int `subplot`.
            v._subplot(x, values, None)

        with self.assertRaises(TypeError):
            # Float instead of int `subplot`.
            v._subplot(x, values, 5.6)

        with self.assertRaises(TypeError):
            # Non-string `title`.
            v._subplot(x, values, 0, title=["hello", "bye"])

        with self.assertRaises(TypeError):
            # Non-string `xlabel`.
            v._subplot(x, values, 0, xlabel=["hello", "bye"])

        with self.assertRaises(TypeError):
            # Non-string `ylabel`.
            v._subplot(x, values, 0, ylabel=["hello", "bye"])