def setUp(self): self.X = np.array([[2641.16233666, 180.2425623], [921.14476418, 192.35609972], [-651.32239137, 150.24830291], [1223.63536668, 156.62123653], [3233.37342355, 173.80311908], [1373.22400821, 191.0922843], [1959.28188858, 163.22252158], [1076.99295365, 190.73280428], [2029.25100261, 158.52982435], [1835.52188141, 163.0101334], [1170.03850556, 205.24904026], [739.42628394, 175.42916046], [1866.65810627, 208.31821984], [3703.49786503, 178.98351969], [1719.45232017, 160.50981075], [258.90206528, 163.19294974], [219.42363944, 173.30395132], [609.90212377, 215.18996298], [1618.44207239, 164.71141696], [2323.2775272, 178.84973821], [3251.78732274, 182.99902513], [1430.63989981, 217.5796917], [-180.57028875, 201.56983421], [-592.84497457, 174.92272693]]) self.copula = Frank()
def setUp(self): self.X = np.array([ [0.2, 0.1], [0.2, 0.3], [0.4, 0.5], [0.6, 0.4], [0.8, 0.6], [0.8, 0.9], ]) self.copula = Frank()
def test_cdf_zero_if_single_arg_is_zero(self): """Test of the analytical properties of copulas on a range of values of theta.""" # Setup instance = Frank() tau_values = np.linspace(-1.0, 1.0, 20)[1: -1] # Run/Check for tau in tau_values: instance.tau = tau instance.theta = instance.compute_theta() copula_zero_if_arg_zero(instance)
def test_cdf_value_if_all_other_arg_are_one(self): """Test of the analytical properties of copulas on a range of values of theta.""" # Setup instance = Frank() tau_values = np.linspace(-1.0, 1.0, 20)[1: -1] # Run/Check for tau in tau_values: instance.tau = tau instance.theta = instance.compute_theta() copula_single_arg_not_one(instance, tolerance=1E-03)
def test_sample(self, uniform_mock): """Sample use the inverse-transform method to generate new samples.""" # Setup instance = Frank() instance.tau = 0.5 instance.theta = instance.compute_theta() uniform_mock.return_value = np.array([0.1, 0.2, 0.4, 0.6, 0.8]) expected_result = np.array([ [0.0312640840463779, 0.1], [0.1007998170183327, 0.2], [0.3501836319841291, 0.4], [0.6498163680158703, 0.6], [0.8992001829816683, 0.8] ]) expected_uniform_call_args_list = [ ((0, 1, 5), {}), ((0, 1, 5), {}) ] # Run result = instance.sample(5) # Check assert isinstance(result, np.ndarray) assert result.shape == (5, 2) compare_nested_iterables(result, expected_result) assert uniform_mock.call_args_list == expected_uniform_call_args_list
class TestFrank(TestCase): def setUp(self): self.X = np.array([ [0.2, 0.1], [0.2, 0.3], [0.4, 0.5], [0.6, 0.4], [0.8, 0.6], [0.8, 0.9], ]) self.copula = Frank() def test_fit(self): """On fit, theta and tau attributes are set.""" self.copula.fit(self.X) self.assertAlmostEqual(self.copula.tau, 0.7877, places=3) self.assertAlmostEqual(self.copula.theta, 17.0227, places=3) def test_probability_density(self): """Probability_density returns the probability density for the given values.""" # Setup self.copula.fit(self.X) expected_result = np.array([4.4006, 4.2302]) # Run result = self.copula.probability_density(np.array([ [0.2, 0.2], [0.6, 0.61] ])) # Check assert isinstance(result, np.ndarray) assert np.isclose(result, expected_result, rtol=0.05).all() def test_cumulative_distribution(self): """Cumulative_density returns the probability distribution value for a point.""" # Setup self.copula.fit(self.X) expected_result = np.array([0.1602, 0.5641]) # Run result = self.copula.cumulative_distribution(np.array([ [0.2, 0.2], [0.6, 0.61] ])) # Check assert isinstance(result, np.ndarray) assert np.isclose(result, expected_result, rtol=0.05).all() @patch('copulas.bivariate.base.np.random.uniform') def test_sample(self, uniform_mock): """Sample use the inverse-transform method to generate new samples.""" # Setup instance = Frank() instance.tau = 0.5 instance.theta = instance.compute_theta() uniform_mock.return_value = np.array([0.1, 0.2, 0.4, 0.6, 0.8]) expected_result = np.array([ [0.0312640840463779, 0.1], [0.1007998170183327, 0.2], [0.3501836319841291, 0.4], [0.6498163680158703, 0.6], [0.8992001829816683, 0.8] ]) expected_uniform_call_args_list = [ ((0, 1, 5), {}), ((0, 1, 5), {}) ] # Run result = instance.sample(5) # Check assert isinstance(result, np.ndarray) assert result.shape == (5, 2) compare_nested_iterables(result, expected_result) assert uniform_mock.call_args_list == expected_uniform_call_args_list def test_cdf_zero_if_single_arg_is_zero(self): """Test of the analytical properties of copulas on a range of values of theta.""" # Setup instance = Frank() tau_values = np.linspace(-1.0, 1.0, 20)[1: -1] # Run/Check for tau in tau_values: instance.tau = tau instance.theta = instance.compute_theta() copula_zero_if_arg_zero(instance) def test_cdf_value_if_all_other_arg_are_one(self): """Test of the analytical properties of copulas on a range of values of theta.""" # Setup instance = Frank() tau_values = np.linspace(-1.0, 1.0, 20)[1: -1] # Run/Check for tau in tau_values: instance.tau = tau instance.theta = instance.compute_theta() copula_single_arg_not_one(instance, tolerance=1E-03)
class TestFrank(TestCase): def setUp(self): self.X = np.array([[2641.16233666, 180.2425623], [921.14476418, 192.35609972], [-651.32239137, 150.24830291], [1223.63536668, 156.62123653], [3233.37342355, 173.80311908], [1373.22400821, 191.0922843], [1959.28188858, 163.22252158], [1076.99295365, 190.73280428], [2029.25100261, 158.52982435], [1835.52188141, 163.0101334], [1170.03850556, 205.24904026], [739.42628394, 175.42916046], [1866.65810627, 208.31821984], [3703.49786503, 178.98351969], [1719.45232017, 160.50981075], [258.90206528, 163.19294974], [219.42363944, 173.30395132], [609.90212377, 215.18996298], [1618.44207239, 164.71141696], [2323.2775272, 178.84973821], [3251.78732274, 182.99902513], [1430.63989981, 217.5796917], [-180.57028875, 201.56983421], [-592.84497457, 174.92272693]]) self.copula = Frank() def test_fit(self): """On fit, theta and tau attributes are set.""" # Setup expected_theta = 0.1307082 expected_tau = 0.01449275 # Run self.copula.fit(self.X) actual_theta = self.copula.theta actual_tau = self.copula.tau # Check self.assertAlmostEqual(actual_theta, expected_theta, places=3) self.assertAlmostEqual(actual_tau, expected_tau) def test_probability_density(self): """Probability_density returns the probability density for the given values.""" # Setup self.copula.fit(self.X) expected_result = 0.999672586804842 # Run result = self.copula.probability_density(np.array([[0.1, 0.5]])) # Check assert np.isclose(result, expected_result).all() assert isinstance(result, np.ndarray) def test_cumulative_distribution(self): """Cumulative_density returns the probability distribution value for a point.""" # Setup self.copula.fit(self.X) expected_result = 0.05147003 # Run result = self.copula.cumulative_distribution(np.array([[0.1, 0.5]])) # Check assert np.isclose(result, expected_result).all() assert isinstance(result, np.ndarray) @patch('copulas.bivariate.base.np.random.uniform') def test_sample(self, uniform_mock): """Sample use the inverse-transform method to generate new samples.""" # Setup instance = Frank() instance.tau = 0.5 instance.theta = instance.compute_theta() uniform_mock.return_value = np.array([0.1, 0.2, 0.4, 0.6, 0.8]) expected_result = np.array([[0.0312640840463779, 0.1], [0.1007998170183327, 0.2], [0.3501836319841291, 0.4], [0.6498163680158703, 0.6], [0.8992001829816683, 0.8]]) expected_uniform_call_args_list = [((0, 1, 5), {}), ((0, 1, 5), {})] # Run result = instance.sample(5) # Check assert isinstance(result, np.ndarray) assert result.shape == (5, 2) compare_nested_iterables(result, expected_result) assert uniform_mock.call_args_list == expected_uniform_call_args_list def test_cdf_zero_if_single_arg_is_zero(self): """Test of the analytical properties of copulas on a range of values of theta.""" # Setup instance = Frank() tau_values = np.linspace(-1.0, 1.0, 20)[1:-1] # Run/Check for tau in tau_values: instance.tau = tau instance.theta = instance.compute_theta() copula_zero_if_arg_zero(instance) def test_cdf_value_if_all_other_arg_are_one(self): """Test of the analytical properties of copulas on a range of values of theta.""" # Setup instance = Frank() tau_values = np.linspace(-1.0, 1.0, 20)[1:-1] # Run/Check for tau in tau_values: instance.tau = tau instance.theta = instance.compute_theta() copula_single_arg_not_one(instance, tolerance=1E-03)
def select_copula(X): r"""Select best copula function based on likelihood. Given out candidate copulas the procedure proposed for selecting the one that best fit to a dataset of pairs :math:`\{(u_j, v_j )\}, j=1,2,...n` , is as follows: 1. Estimate the most likely parameter :math:`\theta` of each copula candidate for the given dataset. 2. Construct :math:`R(z|\theta)`. Calculate the area under the tail for each of the copula candidates. 3. Compare the areas: :math:`a_u` achieved using empirical copula against the ones achieved for the copula candidates. Score the outcome of the comparison from 3 (best) down to 1 (worst). 4. Proceed as in steps 2- 3 with the lower tail and function :math:`L`. 5. Finally the sum of empirical upper and lower tail functions is compared against :math:`R + L`. Scores of the three comparisons are summed and the candidate with the highest value is selected. Args: X(np.ndarray): Matrix of shape (n,2). Returns: copula: Best copula that fits for it. """ frank = Frank() frank.fit(X) if frank.tau <= 0: return frank copula_candidates = [frank] # append copulas into the candidate list for copula_class in [Clayton, Gumbel]: try: copula = copula_class() copula.tau = frank.tau copula._compute_theta() copula_candidates.append(copula) except ValueError: pass left_tail, empirical_left_aut, right_tail, empirical_right_aut = _compute_empirical( X) candidate_left_auts, candidate_right_auts = _compute_candidates( copula_candidates, left_tail, right_tail) empirical_aut = np.concatenate((empirical_left_aut, empirical_right_aut)) candidate_auts = [ np.concatenate((l, r)) for l, r in zip(candidate_left_auts, candidate_right_auts) ] # compute L2 distance from empirical distribution diff_left = [ np.sum((empirical_left_aut - l)**2) for l in candidate_left_auts ] diff_right = [ np.sum((empirical_right_aut - r)**2) for r in candidate_right_auts ] diff_both = [ np.sum((empirical_aut - candidate)**2) for candidate in candidate_auts ] # calcule ranks score_left = pd.Series(diff_left).rank(ascending=False) score_right = pd.Series(diff_right).rank(ascending=False) score_both = pd.Series(diff_both).rank(ascending=False) score = score_left + score_right + score_both selected_copula = np.argmax(score.values) return copula_candidates[selected_copula]