def test_edge_cases_shuffle_batches(self): """`stats.shuffle_batches`: Edge Case Validator. Tests the behavior of `shuffle_batches` with edge cases. Raises: Exception: If at least one `Exception` raised is not of the expected kind. """ 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.""" with self.assertRaises(_InvalidFeatureSetError): # Batches all empty. shuffle_batches([_np.matrix([[]]), _np.matrix([[]])]) with self.assertRaises(_InvalidFeatureSetError): # Second batch empty. shuffle_batches([X, _np.matrix([[]])]) with self.assertRaises(_InvalidFeatureSetError): # Third batch empty. shuffle_batches([X, X, _np.matrix([[]])])
def test_edge_cases_visualization_plot_feature(self): """`visualization.Visualization.plot_feature`: Edge Case Validator. Tests the behavior of `Visualization.plot_feature` with edge cases. Raises: Exception: If at least one `Exception` raised is not of the expected kind. """ 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", (1, 1)) """Visualization: Plotter instance.""" for ModelWrapper in self.wrappers.values(): with self.assertRaises(_InvalidFeatureSetError): # Empty feature set. v._plot_feature(_np.matrix([[]]), Y, 0, ModelWrapper) with self.assertRaises(_InvalidObservationSetError): # Empty observation set. v._plot_feature(X, _np.matrix([[]]), 0, ModelWrapper) with self.assertRaises(IndexError): # Feature index out of range. v._plot_feature(X, Y, self.data_shape[1], ModelWrapper) v.close()
def test_edge_cases_batches(self): """`stats.batches`: Edge Case Validator. Tests the behavior of `batches` with edge cases. Raises: Exception: If at least one `Exception` raised is not of the expected kind. """ 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.""" with self.assertRaises(_InvalidFeatureSetError): # Empty matrix `X`. batches(_np.matrix([[]]), Y, 20) with self.assertRaises(_InvalidObservationSetError): # Empty matrix `Y`. batches(X, _np.matrix([[]]), 20) with self.assertRaises(ValueError): # `k` greater than 'n'. print len(batches(X, Y, 110))
def test_invalid_args_mse(self): """`loss.mse`: Argument Validator. Tests the behavior of `mse` with invalid argument counts and values. Raises: Exception: If at least one `Exception` raised is not of the expected kind. """ with self.assertRaises(TypeError): # No arguments. mse() with self.assertRaises(TypeError): # Only one arguments. mse(123) with self.assertRaises(TypeError): # More than two arguments. mse(123, 123, 123, 1123) with self.assertRaises(_InvalidObservationSetError): # List of an empty list instead of observation matrix. mse([[]], _random_matrix((self.n, 1))) with self.assertRaises(_InvalidObservationSetError): # `None` instead of prediction matrix. mse(_random_matrix((self.n, 1)), [[]]) with self.assertRaises(_IncompatibleDataSetsError): # Incompatible observation and prediction matrices. mse(_random_matrix((self.n, 1)), _random_matrix((self.n + 1, 1)))
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_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()
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)
def test_random_model_constant_augmentor(self): """`augmentors.constant_augmentor`: Randomized Validator. Tests the behavior of `constant_augmentor` by feeding it randomly generated arguments. Raises: AssertionError: If `constant_augmentor` needs debugging. """ for i in range(self.n_tests): X = _random_matrix(self.data_shape) """np.matrix: Random-valued matrix.""" n = X.shape[0] """int: Number of data points.""" new_X = constant_augmentor(X) """np.matrix: Test input.""" # Augmentation should also be a matrix. self.assertIsInstance(X, _np.matrix) # Unit-valued vector should have been appended to the left of `X`. self.assertEqual(new_X.shape[1], X.shape[1] + 1) # Yet the number of rows should remain the same. self.assertEqual(new_X.shape[0], X.shape[0]) # Yet the number of rows should remain the same. self.assertEqual(new_X.shape[0], X.shape[0]) # The norm of the leftmost column vector of `new_X` should be # computable accordin to the following formula. self.assertAlmostEqual(_np.linalg.norm(new_X[:, 0]), _math.sqrt(n))
def test_invalid_args_constant_augmentor(self): """`augmentors.constant_augmentor`: Argument Validator. Tests the behavior of `constant_augmentor` with invalid argument counts and values. Raises: Exception: If at least one `Exception` raised is not of the expected kind. """ with self.assertRaises(TypeError): # No arguments. constant_augmentor() with self.assertRaises(TypeError): # Too many arguments. constant_augmentor(123, 123) with self.assertRaises(TypeError): # With **kwargs. constant_augmentor(_random_matrix((self.data_shape)), key1="key1") with self.assertRaises(_InvalidFeatureSetError): # String instead of matrix `X`. constant_augmentor("string") with self.assertRaises(_InvalidFeatureSetError): # `None` instead of matrix `X`. constant_augmentor(None) with self.assertRaises(_InvalidFeatureSetError): # ndarray instead of matrix `X`. constant_augmentor(_np.zeros(self.data_shape))
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_edge_cases_mse(self): """`loss.mse`: Edge Case Validator. Tests the behavior of `mse` with edge cases. Raises: Exception: If at least one `Exception` raised is not of the expected kind. """ with self.assertRaises(_InvalidObservationSetError): # Empty observation matrix. mse(_np.matrix([[]]), _random_matrix((self.n, 1))) with self.assertRaises(_InvalidObservationSetError): # Empty prediction matrix. mse(_random_matrix((self.n, 1)), _np.matrix([[]]))
def test_invalid_args_shuffle_batches(self): """`stats.shuffle_batches`: Argument Validator. Tests the behavior of `shuffle_batches` with invalid argument counts and values. Raises: Exception: If at least one `Exception` raised is not of the expected kind. """ 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, 25) """list of np.matrix: Random-valued batches.""" with self.assertRaises(TypeError): # No arguments. shuffle_batches() with self.assertRaises(TypeError): # Too many arguments. shuffle_batches(b, "extra") with self.assertRaises(TypeError): # Keyword argument. shuffle_batches(b, key="value") with self.assertRaises(TypeError): # Matrix instead of list `batches`. shuffle_batches(b[0]) with self.assertRaises(TypeError): # Non-iterable `batches`. shuffle_batches(None) with self.assertRaises(TypeError): # Wrong kind of iterable `batches`. shuffle_batches("string")
def test_edge_cases_partition_data(self): """`stats.partition_data`: Edge Case Validator. Tests the behavior of `partition_data` with edge cases. Raises: Exception: If at least one `Exception` raised is not of the expected kind. """ n, d = self.data_shape """(int, int): Number of data points and number of features.""" with self.assertRaises(_InvalidFeatureSetError): # Empty matrix `X`. partition_data(_np.matrix([[]]), _random_matrix((n, 1)), 0.5) with self.assertRaises(_InvalidObservationSetError): # Empty matrix `Y`. partition_data(_random_matrix((n, d)), _np.matrix([[]]), 0.5)
def test_random_mse(self): """`loss.mse`: Randomized Validator. Tests the behavior of `mse` by feeding it randomly generated arguments. Raises: AssertionError: If `mse` needs debugging. """ for i in range(self.n_tests): Y = _random_matrix((self.n, 1), max_val=self.max_mean) """float: Random-valued observations.""" Y_hat = _random_matrix((self.n, 1), max_val=self.max_mean) """float: Random-valued predictions.""" delta_Y = abs(Y - Y_hat) """float: Distance between predictions and observations.""" squared_sum_delta_Y = _np.linalg.norm(delta_Y[1:, 0])**2 """float: Sum of the squares of all `delta_Y` values.""" # To ensure that the coercion does not result in the square of a # negative number, we can use the mean of the upper-bound # `squared_sum_delta_Y` as insurance that the computation will only # work with positive numbers. err = _uniform((squared_sum_delta_Y + 1.0) / self.n, (squared_sum_delta_Y + self.max_mean) / self.n) """float: MSE to coerce.""" # Coerce MSE by changing the first prediction to a strategic choice # and mathematically guaranteeing Y_hat[0, 0] = (_np.sqrt(self.n * err - squared_sum_delta_Y) - Y[0, 0]) * -1.0 result = mse(Y, Y_hat) """float: Test input.""" self.assertAlmostEqual(result, err)
def test_invalid_args_reduce_dimensions(self): """`stats.reduce_dimensions`: Argument Validator. Tests the behavior of `reduce_dimensions` with invalid argument counts and values. Raises: Exception: If at least one `Exception` raised is not of the expected kind. """ 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.""" with self.assertRaises(TypeError): # No arguments. reduce_dimensions() with self.assertRaises(TypeError): # Only one argument. reduce_dimensions(X) with self.assertRaises(TypeError): # More than three arguments. reduce_dimensions(X, Y, 0.5, None, "extra_arg") with self.assertRaises(TypeError): # Invalid kwarg. reduce_dimensions(X, Y, 0.5, key="value") with self.assertRaises(_InvalidFeatureSetError): # ndarray instead of matrix `X`. reduce_dimensions(_np.zeros(self.data_shape), Y) with self.assertRaises(_InvalidFeatureSetError): # `None` instead of matrix `X`. reduce_dimensions(None, Y) with self.assertRaises(_InvalidObservationSetError): # ndarray instead of matrix `Y`. reduce_dimensions(X, _np.zeros((self.data_shape[0], 1))) with self.assertRaises(_InvalidObservationSetError): # `None` instead of matrix `Y`. reduce_dimensions(X, None) with self.assertRaises(_InvalidObservationSetError): # Incompatible data sets. reduce_dimensions(X, X) with self.assertRaises(TypeError): # None instead of float `f`. reduce_dimensions(X, Y, None) with self.assertRaises(ValueError): # Minimum correlation greater than 1. reduce_dimensions(X, Y, 1.2) with self.assertRaises(ValueError): # Negative minimum correlation. reduce_dimensions(X, Y, -0.1)
def test_invalid_args_partition_data(self): """`stats.partition_data`: Argument Validator. Tests the behavior of `partition_data` with invalid argument counts and values. Raises: Exception: If at least one `Exception` raised is not of the expected kind. """ n, d = self.data_shape """(int, int): Number of data points and number of features.""" with self.assertRaises(TypeError): # Only two arguments. partition_data(_random_matrix((n, d)), _random_matrix((n, d))) with self.assertRaises(TypeError): # Only one arguments. partition_data(0) with self.assertRaises(TypeError): # No arguments. partition_data() with self.assertRaises(TypeError): # More than three arguments. partition_data(_random_matrix((n, d)), _random_matrix((n, d)), 0.5, 123) with self.assertRaises(_InvalidFeatureSetError): # List of a matrix instead of matrix `X`. partition_data([_random_matrix((n, d))], _random_matrix((n, 1)), 0.2) with self.assertRaises(_InvalidObservationSetError): # `None` instead of matrix `Y`. partition_data(_random_matrix((n, 1)), None, 0.5) with self.assertRaises(_InvalidObservationSetError): # Incompatible observation matrix `Y`. partition_data(_random_matrix((n, d)), _random_matrix((n, d)), 0.5) with self.assertRaises(_InvalidFeatureSetError): # Lists instead of matrices `X` and `Y`. partition_data([], [], 0.5) with self.assertRaises(TypeError): # None instead of float `f`. partition_data(_random_matrix((n, d)), _random_matrix((n, 1)), None) with self.assertRaises(ValueError): # Ratio `f` greater than 1. partition_data(_random_matrix((n, d)), _random_matrix((n, 1)), 1.2) with self.assertRaises(ValueError): # Zero-valued ratio `f`. partition_data(_random_matrix((n, d)), _random_matrix((n, 1)), 0) with self.assertRaises(ValueError): # Unit-valued ratio `f`. partition_data(_random_matrix((n, d)), _random_matrix((n, 1)), 1)
def test_invalid_args_batches(self): """`stats.batches`: Argument Validator. Tests the behavior of `batches` with invalid argument counts and values. Raises: Exception: If at least one `Exception` raised is not of the expected kind. """ n, d = self.data_shape """(int, int): Number of data points and number of features.""" with self.assertRaises(TypeError): # No arguments. batches() with self.assertRaises(TypeError): # Only two arguments. batches(123, 123) with self.assertRaises(TypeError): # More than three arguments. batches(123, 123, 123, 1123) with self.assertRaises(_InvalidFeatureSetError): # List instead of matrix `X`. batches([[]], _random_matrix((n, 1)), 20) with self.assertRaises(_InvalidObservationSetError): # `None` instead of matrix `Y`. batches(_random_matrix((n, d)), None, 20) with self.assertRaises(TypeError): # String instead of positive integer `k`. batches(_random_matrix((n, d)), _random_matrix((n, 1)), "hello") with self.assertRaises(TypeError): # List of integers instead of positive integer `k`. batches(_random_matrix((n, d)), _random_matrix((n, 1)), [0]) with self.assertRaises(TypeError): # Matrix instead of positive integer `k`. batches(_random_matrix((n, d)), _random_matrix((n, 1)), _random_matrix((n, 1))) with self.assertRaises(TypeError): # Float instead of positive integer `k`. batches(_random_matrix((n, d)), _random_matrix((n, 1)), 10.5) with self.assertRaises(ValueError): # Zero-valued `k`. batches(_np.matrix(_np.random.rand(n, d)), _np.matrix(_np.random.rand(n, 1)), 0) with self.assertRaises(ValueError): # Negative `k`. batches(_np.matrix(_np.random.rand(n, d)), _np.matrix(_np.random.rand(n, 1)), -1)
def test_invalid_args_visualization_plot_feature(self): """`visualization.Visualization.plot_feature`: Argument Validator. Tests the behavior of `Visualization.plot_feature` with invalid argument counts and values. Raises: Exception: If at least one `Exception` raised is not of the expected kind. """ 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", (1, 1)) """Visualization: Plotter instance.""" with self.assertRaises(TypeError): # No arguments. v._plot_feature() with self.assertRaises(TypeError): # Only one argument. v._plot_feature(X) with self.assertRaises(TypeError): # Only two arguments. v._plot_feature(X, Y) with self.assertRaises(TypeError): # Only three arguments. v._plot_feature(X, Y, 0) with self.assertRaises(TypeError): # `None` instead of model wrapper. v._plot_feature(X, Y, 0, None) with self.assertRaises(TypeError): # `Visualization` instead of `ModelWrapper`. v._plot_feature(X, Y, 0, v) for ModelWrapper in self.wrappers.values(): with self.assertRaises(TypeError): # Too many arguments. v._plot_feature(X, Y, 0, ModelWrapper, "extra") with self.assertRaises(TypeError): # With keyword. v._plot_feature(X, Y, 0, ModelWrapper, key="value") with self.assertRaises(_InvalidFeatureSetError): # Non-matrix feature set `X`. v._plot_feature(None, Y, 0, ModelWrapper) with self.assertRaises(_InvalidFeatureSetError): # ndarray instead of feature set `X`. v._plot_feature(_np.zeros(self.data_shape), Y, 0, ModelWrapper) with self.assertRaises(_InvalidObservationSetError): # Non-matrix feature set `X`. v._plot_feature(X, None, 0, ModelWrapper) with self.assertRaises(_InvalidObservationSetError): # ndarray instead of feature set `X`. v._plot_feature(X, _np.zeros((self.data_shape[0], 1)), 0, ModelWrapper) with self.assertRaises(_IncompatibleDataSetsError): # Incompatible datasets. v._plot_feature(X, _random_matrix((self.data_shape[0] + 1, 1)), 0, ModelWrapper) with self.assertRaises(TypeError): # Non-integer index `feature`. v._plot_feature(X, Y, None, ModelWrapper) with self.assertRaises(ValueError): # Negative integer instead of `feature`. v._plot_feature(X, Y, -2, ModelWrapper) v.close()