def test_matrix_construction(self): """Test matrix construction""" self.assertEqual(self._M.nb_rows, 3) self.assertEqual(self._M.nb_cols, 3) for row in range(self._M.nb_rows): for col in range(self._M.nb_cols): self.assertEqual(self._M[row, col], 0.) self.assertEqual(self._M, linalg.Matrix(3)) self.assertEqual(self._M, linalg.Matrix(self._M))
class TestCompleteVectorPredictor(unittest.TestCase, TestPredictor): _alpha = linalg.Vector([1., 2.]) _delta = linalg.Matrix([[0.5, 2.], [1., 4.]]) _len = 6 _eta = linalg.Vector([4.7, 9.4]) @classmethod def setUpClass(cls): """Test complete vector predictor construction""" cls.sample_space_init() cls._pred = glm.CompleteVectorPredictor(cls._vector_sample_spaces, 2) def test_predictor(self): """Test vector predictor operator""" self._pred.alpha = self._alpha self._pred.delta = self._delta self.assertEqual(len(self._pred), self._len) eta = self._pred(1, 1.6) self.assertEqual(eta[0], self._eta[0]) self.assertEqual(eta[1], self._eta[1]) @classmethod def tearDownClass(cls): """Test complete vector predictor deletion""" del cls._pred
def setUpClass(cls): """Test undirected Gaussian distribution construction""" theta = [] for i in range(cls._K): theta.append([0. if not j in [i, i - 1, i + 1] else 0.5 if j in [i - 1, i + 1] else 1. for j in range(cls._K)]) cls._dist = pgm.UndirectedGaussianDistribution(linalg.Vector([0.] * cls._K), linalg.Matrix(theta)) cls._data = cls._dist.simulation(3 * cls._K + 1)
def test_chordality(self): """Test undirected graph chordality""" self.assertTrue(self._graph.is_chordal) graph = pgm.UndirectedGraph( linalg.Matrix([[0.0, 1.0, 0.0, 1.0], [1.0, 0.0, 1.0, 0.0], [0.0, 1.0, 0.0, 1.0], [1.0, 0.0, 1.0, 0.0]])) self.assertFalse(graph.is_chordal) self.assertTrue(graph.maximum_cardinality_embedding().is_chordal)
def setUpClass(cls): """Test directed graph construction""" cls._graph = pgm.DirectedGraph( linalg.Matrix([[0.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0], [1.0, 0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 1.0], [0.0, 0.0, 0.0, 0.0, 0.0]]))
def setUpClass(cls): """Test undirected forest construction""" cls._graph = pgm.UndirectedForest( linalg.Matrix([[0.0, 2.0, 1.0, 0.0, 0.0], [2.0, 0.0, 3.0, 0.0, 0.0], [1.0, 3.0, 0.0, 4.0, 0.0], [0.0, 0.0, 4.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0, 0.0]]))
class TestAdjacentFLink(unittest.TestCase, AbstractTestVectorLink): _dist = core.LaplaceDistribution() _eta = linalg.Vector([1.,1.]) f0 = _dist.pdf(_eta[0]) f1 = _dist.pdf(_eta[1]) F0 = _dist.cdf(_eta[0]) F1 = _dist.cdf(_eta[1]) norm = 1/( 1 + F0/(1-F0) * F1/(1-F1) + F1/(1-F1) ) _mu = linalg.Vector([norm*F0/(1-F0)*F1/(1-F1), norm*F1/(1-F1)]) _mu_prime = linalg.Matrix([[f0/(F0*(1-F0)), 0], [0, f1/(F1*(1-F1))]]) * linalg.Matrix([[1,0], [1,1]]) *( linalg.Matrix(_mu) - _mu * linalg.RowVector(_mu) ) @classmethod def setUpClass(cls): """Test adjacent FLink construction""" cls._link = glm.OrdinalLink(ratio='adjacent', distribution=cls._dist) @classmethod def tearDownClass(cls): """Test adjacent FLink deletion""" del cls._link
class TestReferenceFLink(unittest.TestCase, AbstractTestVectorLink): #_places = 4 _dist = core.NormalDistribution() _eta = linalg.Vector([1.,1.]) f0 = _dist.pdf(_eta[0]) f1 = _dist.pdf(_eta[1]) F0 = _dist.cdf(_eta[0]) F1 = _dist.cdf(_eta[1]) norm = 1/( 1 + F0/(1-F0) + F1/(1-F1) ) _mu = linalg.Vector([norm*F0/(1-F0), norm*F1/(1-F1)]) _mu_prime = linalg.Matrix([[f0/(F0*(1-F0)), 0], [0, f1/(F1*(1-F1))]]) * ( linalg.Matrix(_mu) - _mu * linalg.RowVector(_mu) ) @classmethod def setUpClass(cls): """Test reference FLink construction""" cls._link = glm.NominalLink(ratio='reference', distribution=cls._dist) @classmethod def tearDownClass(cls): """Test reference FLink deletion""" del cls._link
class TestConstrainedRegressionEstimation( TestCanonicalNominalRegressionEstimation): _alpha = linalg.Vector([7.3348, 3.5917, 4.3719]) _delta = linalg.Vector([-0.0235, -0.1002, 0.0238, -1.1738]) # (Louviere et al., 2000) page 157 _slope_constraint = linalg.Matrix([[1, 0, 0, 0], [0, 0, 0, 0], [-1, 0, 0, 0], [0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0], [0, -1, 0, 0], [0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1], [0, 0, 0, 0], [1, 0, 0, 0], [-1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 1, 0, 0], [0, -1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [-1, 0, 0, 0], [1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, -1, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]) @classmethod def setUpClass(cls): """Test multivariate data construction""" cls._data = data.load('travel') cls._data.TravelMode.sample_space.reference = "car" def test_Fisher(self): """Test Fisher scoring estimation for nominal regression with constrained design""" mle = glm.nominal_estimation( Z='constrained', data=self._data, response=0, explanatories={1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, slope_constraint=self._slope_constraint) alpha = mle.estimated.predictor.alpha delta = mle.estimated.predictor.delta for i in range(len(self._alpha)): self.assertAlmostEqual(alpha[i], self._alpha[i], places=4) for i in range(len(self._delta)): self.assertAlmostEqual(delta[i], self._delta[i], places=4) #mle_normal = glm.nominal_estimation(distribution=core.NormalDistribution(), Z='constrained', algo='Fisher', data=self._data, response=0, explanatories={1,2,3,4,5,6,7,8,9,10}, slope_constraint=slope_constraint) @classmethod def tearDownClass(cls): """Test multivariate data deletion""" del cls._data
class TestCumulativeLink(unittest.TestCase, AbstractTestVectorLink): _eta = linalg.Vector([0.,1.]) # linear predictors must be strictly ordered for cumulative models ! _mu = linalg.Vector([0.5, -0.5+ math.exp(1)/(1.+math.exp(1))]) _mu_prime = linalg.Matrix([[0.25,-0.25], [0, math.exp(1)/pow(1+math.exp(1), 2)]]) @classmethod def setUpClass(cls): """Test cumulative logistic link construction""" cls._link = glm.OrdinalLink(ratio='cumulative') @classmethod def tearDownClass(cls): """Test cumulative logistic link deletion""" del cls._link
class TestSequentialLink(unittest.TestCase, AbstractTestVectorLink): _eta = linalg.Vector([1.,1.]) norm = 1 + math.exp(1) _mu = linalg.Vector([math.exp(1)/norm, math.exp(1)/pow(norm, 2)]) _mu_prime = linalg.Matrix([[math.exp(1)/pow(norm, 2), -math.exp(2)/pow(norm, 3)], [0, math.exp(1)/pow(norm, 3)]]) @classmethod def setUpClass(cls): """Test Sequential logistic link construction""" cls._link = glm.OrdinalLink(ratio='sequential') @classmethod def tearDownClass(cls): """Test Sequential logistic link deletion""" del cls._link
class TestAdjacentLink(unittest.TestCase, AbstractTestVectorLink): #_places = 5 _eta = linalg.Vector([1.,1.]) norm = 1 + math.exp(1) + math.exp(2) _mu = linalg.Vector([math.exp(2)/norm, math.exp(1)/norm]) _mu_prime = linalg.Matrix([[math.exp(2)*(1+math.exp(1))/norm**2, -math.exp(3)/norm**2], [math.exp(2)/norm**2, math.exp(1)/norm**2]]) @classmethod def setUpClass(cls): """Test adjacent logistic link construction""" cls._link = glm.OrdinalLink(ratio='adjacent') @classmethod def tearDownClass(cls): """Test adjacent logistic link deletion""" del cls._link
class TestOrdinalCanonicalLink(unittest.TestCase, AbstractTestVectorLink): #_places = 5 _eta = linalg.Vector([1.,1.]) norm = 1 + math.exp(1) + math.exp(2) _mu = linalg.Vector([math.exp(2)/norm, math.exp(1)/norm]) _mu_prime = linalg.Matrix([[math.exp(2)*(1+math.exp(1))/norm**2, -math.exp(3)/norm**2], [math.exp(2)/norm**2, math.exp(1)/norm**2]]) #_mu_prime = linalg.Matrix([[1,0], [1,1]]) * ( linalg.Matrix(_mu) - _mu * linalg.RowVector(_mu) ) @classmethod def setUpClass(cls): """Test ordinal canonical link construction""" cls._link = glm.OrdinalLink() @classmethod def tearDownClass(cls): """Test ordinal canonical link deletion""" del cls._link
def to_matrix(self, sort=None): if sort is None: vertices = range(self.nb_vertices) elif isinstance(sort, list): vertices = range(self.nb_vertices) def sorter(vertex): return sort[vertex] vertices = sorted(vertices, key = sorter) elif isinstance(sort, basestring): if sort == 'mcs': vertices = range(self.nb_vertices) vertices = [vertices[vertex] for vertex in self.maximum_cardinality_search()] else: raise ValueError('\'sort\' parameter') else: raise TypeError('\'sort\' parameter') return linalg.Matrix([[float(self.has_edge(u, v)) for v in vertices] for u in vertices])
class AbstractTestVectorLink(object): _places = 5 _eta = linalg.Vector([1.,1.]) _mu = linalg.Vector([math.exp(1)/(1+2*math.exp(1)), math.exp(1)/(1+2*math.exp(1))]) _mu_prime = linalg.Matrix(_mu) - _mu * linalg.RowVector(_mu) def test_evaluate(self): """ Test vector link evaluate """ self.assertEqual(self._link.evaluate(self._mu).round(self._places), self._eta.round(self._places)) def test_inverse(self): """Test vector link inverse""" self.assertEqual(self._link.inverse(self._eta).round(self._places), self._mu.round(self._places)) self.assertEqual(self._link.inverse(self._link.evaluate(self._mu)).round(self._places), self._mu.round(self._places)) def test_inverse_derivative(self): """Test vector link inverse derivative""" self.assertEqual(self._link.inverse_derivative(self._eta).round(self._places), self._mu_prime.round(self._places))
class TestSequentialFLink(unittest.TestCase, AbstractTestVectorLink): _dist = core.GumbelDistribution() _eta = linalg.Vector([0.,1.]) f0 = _dist.pdf(_eta[0]) f1 = _dist.pdf(_eta[1]) F0 = _dist.cdf(_eta[0]) F1 = _dist.cdf(_eta[1]) _mu = linalg.Vector([F0, F1*(1-F0)]) _mu_prime = linalg.Matrix([[f0, -f0*F1], [0, f1*(1-F0)]]) @classmethod def setUpClass(cls): """Test Sequential FLink construction""" cls._link = glm.OrdinalLink(ratio='sequential', distribution=cls._dist) @classmethod def tearDownClass(cls): """Test Sequential FLink deletion""" del cls._link
class TestCumulativeFLink(unittest.TestCase, AbstractTestVectorLink): _dist = core.CauchyDistribution() _eta = linalg.Vector([0.,1.]) # linear predictors must be strictly ordered for cumulative models ! f0 = _dist.pdf(_eta[0]) f1 = _dist.pdf(_eta[1]) F0 = _dist.cdf(_eta[0]) F1 = _dist.cdf(_eta[1]) _mu = linalg.Vector([F0, F1-F0]) _mu_prime = linalg.Matrix([[f0, -f0], [0, f1]]) @classmethod def setUpClass(cls): """Test cumulative FLink construction""" cls._link = glm.OrdinalLink(ratio='cumulative', distribution=cls._dist) @classmethod def tearDownClass(cls): """Test cumulative FLink deletion""" del cls._link
class TestReferenceRegression(unittest.TestCase, AbstractTestCategoricalRegression): _alpha = linalg.Vector([1., 2.]) _delta = linalg.Matrix([[-1.5, 2.], [-2., 2.5]]) _x = [1, 1.6] _nb_param = 6 _eta = linalg.Vector([2.7, 4.]) _canonical_link = glm.NominalLink(ratio='reference') _norm = 1 + math.exp(_eta[0]) + math.exp(_eta[1]) _mu = linalg.Vector( [math.exp(_eta[0]) / _norm, math.exp(_eta[1]) / _norm, 1 / _norm]) _categories = {'Bb', 'Bc', 'Ba'} _places = 10 @classmethod def setUpClass(cls): """Test reference regression construction""" cls.predictor_init() nss = core.NominalSampleSpace(*cls._categories) cls._model = glm.NominalRegression(nss, cls._pred, cls._canonical_link) def test_get_nb_parameters(self): """Test reference regression get number of parameters""" self.assertEqual(self._model.nb_parameters, self._nb_param) def test_conditional(self): """Test reference regression conditional operator""" response_distribution = self._model(*self._x) self.assertAlmostEqual(response_distribution.pdf('Ba'), self._mu[0], places=self._places) self.assertAlmostEqual(response_distribution.pdf('Bb'), self._mu[1], places=self._places) self.assertAlmostEqual(response_distribution.pdf('Bc'), self._mu[2], places=self._places) @classmethod def tearDownClass(cls): """Test reference regression deletion""" del cls._model
class TestCanonicalNominalRegressionEstimation(unittest.TestCase): _alpha = linalg.Vector([-0.591, -1.039]) _delta = linalg.Matrix([[-0.388, 1.128, 1.588], [-0.813, 1.478, 2.917]]) # (Dosbson, 2008) page 155 _loglikelihood = -290.35 @classmethod def setUpClass(cls): """Test multivariate data construction""" cls._data = data.load('cars') cls._data.AirConditioning.sample_space.reference = 'little_important' cls._data.Sex.sample_space.reference = 'women' cls._data.Age.sample_space.reference = '18_23' def test_Fisher(self): """Test Fisher scoring estimation for nominal regression with complete design""" mle = glm.nominal_estimation(data=self._data, response=0, explanatories={1, 2}) self.assertAlmostEqual(mle.loglikelihood, self._loglikelihood, places=2) alpha = mle.estimated.predictor.alpha delta = mle.estimated.predictor.delta for i in range(len(self._alpha)): self.assertAlmostEqual(alpha[i], self._alpha[i], places=3) for j in range(self._delta.nb_cols): self.assertAlmostEqual(delta[i, j], self._delta[i, j], places=3) #mle = glm.nominal_estimation(design='proportional', data=self._data, response = 0, explanatories = {1,2}) @classmethod def tearDownClass(cls): """Test multivariate data deletion""" del cls._data
def setUpClass(cls): """Test multinormal distribution construction""" cls._dist = core.MultinormalDistribution( linalg.Vector([0., 0., 0.]), linalg.Matrix([[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]))
def setUpClass(cls): """Test matrix construction""" cls._M = linalg.Matrix(3, 3)
class TestHierarchicalRegression(unittest.TestCase, AbstractTestCategoricalRegression): _alpha = linalg.Vector([1., 2.]) _delta = linalg.Matrix([[-1.5, 2.], [-2., 2.5]]) _x = [1, 1.6] _nb_param = 12 _eta = linalg.Vector([2.7, 4.]) _norm_root = [1 + math.exp(_eta[0]), 1 + math.exp(_eta[1])] _mu_root = linalg.Vector([ math.exp(_eta[0]) / _norm_root[0], math.exp(_eta[1]) / _norm_root[1] - math.exp(_eta[0]) / _norm_root[0], 1 - math.exp(_eta[1]) / _norm_root[1] ]) _categories_root = ['C', 'B', 'A'] _norm_B = 1 + math.exp(_eta[0]) + math.exp(_eta[1]) _mu_B = linalg.Vector([ math.exp(_eta[0]) / _norm_B, math.exp(_eta[1]) / _norm_B, 1 / _norm_B ]) _categories_B = {'Ba', 'Bb', 'Bc'} _places = 10 @classmethod def hierarchical_sample_space_init(cls): ordinal_space = core.OrdinalSampleSpace(*cls._categories_root) nominal_space = core.NominalSampleSpace(*cls._categories_B) cls._hss = core.HierarchicalSampleSpace(ordinal_space) cls._hss.partition('B', nominal_space) @classmethod def setUpClass(cls): """Test hierarchical regression construction""" cls.hierarchical_sample_space_init() cls.predictor_init() cls._model = glm.HierarchicalRegression(cls._hss, cls._vector_sample_spaces) @classmethod def test_get_set_regression(self): """Test hierarchical regression get and set regression model""" model_root = self._model.get_regression("") model_root.predictor = self._pred model_root.link = glm.OrdinalLink(ratio='cumulative') self._model.set_regression("", model_root) model_B = self._model.get_regression("B") model_B.predictor = self._pred model_B.link = glm.NominalLink(ratio='reference') self._model.set_regression("B", model_B) def test_get_nb_parameters(self): """Test hierarchical regression get number of parameters""" self.assertEqual( self._model.nb_parameters, self._nb_param ) # Warning after issue #32 it must be equal to 0 and not 12 def test_conditional(self): """Test hierarchical regression conditional operator""" response_distribution = self._model(*self._x) self.assertAlmostEqual(response_distribution.pdf('C'), float(1 / 3), places=self._places) self.assertAlmostEqual(response_distribution.internal_pdf('B'), float(1 / 3), places=self._places) self.assertAlmostEqual(response_distribution.pdf('Ba'), float(1 / 9), places=self._places) self.test_get_set_regression() response_distribution = self._model(*self._x) self.assertAlmostEqual(response_distribution.pdf('C'), self._mu_root[0], places=self._places) self.assertAlmostEqual(response_distribution.internal_pdf('B'), self._mu_root[1], places=self._places) self.assertAlmostEqual(response_distribution.pdf('A'), self._mu_root[2], places=self._places) self.assertAlmostEqual(response_distribution.pdf('Ba'), self._mu_root[1] * self._mu_B[0], places=self._places) self.assertAlmostEqual(response_distribution.pdf('Bb'), self._mu_root[1] * self._mu_B[1], places=self._places) self.assertAlmostEqual(response_distribution.pdf('Bc'), self._mu_root[1] * self._mu_B[2], places=self._places) @classmethod def tearDownClass(cls): """Test hierarchcical regression deletion""" del cls._model