Example #1
0
    def get_likelihood(self, uni_matrix):
        """Compute likelihood given a U matrix.

        Args:
            uni_matrix (numpy.array):
                Matrix to compute the likelihood.

        Return:
            tuple (np.ndarray, np.ndarray, np.array):
                likelihood and conditional values.
        """
        if self.parents is None:
            left_u = uni_matrix[:, self.L]
            right_u = uni_matrix[:, self.R]

        else:
            left_ing = list(self.D - self.parents[0].D)[0]
            right_ing = list(self.D - self.parents[1].D)[0]
            left_u = uni_matrix[self.L, left_ing]
            right_u = uni_matrix[self.R, right_ing]

        copula = Bivariate(copula_type=self.name)
        copula.theta = self.theta

        X_left_right = np.array([[left_u, right_u]])
        X_right_left = np.array([[right_u, left_u]])

        value = np.sum(copula.probability_density(X_left_right))
        left_given_right = copula.partial_derivative(X_left_right)
        right_given_left = copula.partial_derivative(X_right_left)

        return value, left_given_right, right_given_left
Example #2
0
    def test_sample(self, uniform_mock):
        """Sample use the inverse-transform method to generate new samples."""
        # Setup
        instance = Bivariate(CopulaTypes.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([[6.080069565509917e-06, 0.1],
                                    [6.080069565509917e-06, 0.2],
                                    [6.080069565509917e-06, 0.4],
                                    [6.080069565509917e-06, 0.6],
                                    [4.500185268624483e-06, 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
Example #3
0
    def prepare_next_tree(self):
        """Prepare conditional U matrix for next tree."""
        for edge in self.edges:
            copula_theta = edge.theta

            if self.level == 1:
                left_u = self.u_matrix[:, edge.L]
                right_u = self.u_matrix[:, edge.R]

            else:
                left_parent, right_parent = edge.parents
                left_u, right_u = Edge.get_conditional_uni(left_parent, right_parent)

            # compute conditional cdfs C(i|j) = dC(i,j)/duj and dC(i,j)/du
            left_u = [x for x in left_u if x is not None]
            right_u = [x for x in right_u if x is not None]
            X_left_right = np.array([[x, y] for x, y in zip(left_u, right_u)])
            X_right_left = np.array([[x, y] for x, y in zip(right_u, left_u)])

            copula = Bivariate(copula_type=edge.name)
            copula.theta = copula_theta
            left_given_right = copula.partial_derivative(X_left_right)
            right_given_left = copula.partial_derivative(X_right_left)

            # correction of 0 or 1
            left_given_right[left_given_right == 0] = EPSILON
            right_given_left[right_given_left == 0] = EPSILON
            left_given_right[left_given_right == 1] = 1 - EPSILON
            right_given_left[right_given_left == 1] = 1 - EPSILON
            edge.U = np.array([left_given_right, right_given_left])
Example #4
0
    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 = Bivariate(CopulaTypes.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)
Example #5
0
    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 = Bivariate(CopulaTypes.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)
Example #6
0
    def test_sample_random_state(self):
        """If random_state is set, the samples are the same."""
        # Setup
        instance = Bivariate(CopulaTypes.FRANK, random_seed=0)
        instance.tau = 0.5
        instance.theta = instance.compute_theta()

        expected_result = np.array([[3.66330927e-06, 5.48813504e-01],
                                    [6.08006957e-06, 7.15189366e-01],
                                    [5.27582646e-06, 6.02763376e-01],
                                    [5.58315848e-06, 5.44883183e-01],
                                    [6.08006957e-06, 4.23654799e-01]])

        # Run
        result = instance.sample(5)

        # Check
        compare_nested_iterables(result, expected_result)
Example #7
0
    def test_sample_random_state(self):
        """If random_state is set, the samples are the same."""
        # Setup
        instance = Bivariate(CopulaTypes.CLAYTON, random_seed=0)
        instance.tau = 0.5
        instance.theta = instance.compute_theta()

        expected_result = np.array([[0.68627770, 0.54881350],
                                    [0.64059280, 0.71518937],
                                    [0.90594782, 0.60276338],
                                    [0.96040856, 0.54488318],
                                    [0.40876969, 0.42365480]])

        # Run
        result = instance.sample(5)

        # Check
        compare_nested_iterables(result, expected_result)
Example #8
0
    def get_likelihood(self, uni_matrix):
        """Compute likelihood given a U matrix."""
        if self.parents is None:
            left_u = uni_matrix[:, self.L]
            right_u = uni_matrix[:, self.R]

        else:
            left_ing = list(self.D - self.parents[0].D)[0]
            right_ing = list(self.D - self.parents[1].D)[0]
            left_u = uni_matrix[self.L, left_ing]
            right_u = uni_matrix[self.R, right_ing]

        copula = Bivariate(self.name)
        copula.theta = self.theta

        X_left_right = np.array([[left_u, right_u]])
        X_right_left = np.array([[right_u, left_u]])

        value = np.sum(copula.probability_density(X_left_right))
        left_given_right = copula.partial_derivative(X_left_right)
        right_given_left = copula.partial_derivative(X_right_left)

        return value, left_given_right, right_given_left
Example #9
0
    def test_sample(self, uniform_mock):
        """Sample use the inverse-transform method to generate new samples."""
        # Setup
        instance = Bivariate(CopulaTypes.CLAYTON)
        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.05233100, 0.1], [0.14271095, 0.2],
                                    [0.39959746, 0.4], [0.68567125, 0.6],
                                    [0.89420523, 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
Example #10
0
    def _sample_row(self):
        """Generate a single sampled row from vine model.

        Returns:
            numpy.ndarray
        """
        unis = np.random.uniform(0, 1, self.n_var)
        # randomly select a node to start with
        first_ind = np.random.randint(0, self.n_var)
        adj = self.trees[0].get_adjacent_matrix()
        visited = []
        explore = [first_ind]

        sampled = np.zeros(self.n_var)
        itr = 0
        while explore:
            current = explore.pop(0)
            neighbors = np.where(adj[current, :] == 1)[0].tolist()
            if itr == 0:
                new_x = self.ppfs[current](unis[current])

            else:
                for i in range(itr - 1, -1, -1):
                    current_ind = -1

                    if i >= self.truncated:
                        continue

                    current_tree = self.trees[i].edges
                    # get index of edge to retrieve
                    for edge in current_tree:
                        if i == 0:
                            if (edge.L == current and edge.R == visited[0]) or\
                               (edge.R == current and edge.L == visited[0]):
                                current_ind = edge.index
                                break
                        else:
                            if edge.L == current or edge.R == current:
                                condition = set(edge.D)
                                condition.add(edge.L)
                                condition.add(edge.R)

                                visit_set = set(visited)
                                visit_set.add(current)

                                if condition.issubset(visit_set):
                                    current_ind = edge.index
                                break

                    if current_ind != -1:
                        # the node is not indepedent contional on visited node
                        copula_type = current_tree[current_ind].name
                        copula = Bivariate(
                            copula_type=CopulaTypes(copula_type))
                        copula.theta = current_tree[current_ind].theta

                        U = np.array([unis[visited[0]]])
                        if i == itr - 1:
                            tmp = copula.percent_point(
                                np.array([unis[current]]), U)[0]
                        else:
                            tmp = copula.percent_point(np.array([tmp]), U)[0]

                        tmp = min(max(tmp, EPSILON), 0.99)

                new_x = self.ppfs[current](np.array([tmp]))

            sampled[current] = new_x

            for s in neighbors:
                if s not in visited:
                    explore.insert(0, s)

            itr += 1
            visited.insert(0, current)

        return sampled
Example #11
0
    def sample(self, num_rows=1):
        """Generating samples from vine model."""
        unis = np.random.uniform(0, 1, self.n_var)
        # randomly select a node to start with
        first_ind = randint(0, self.n_var - 1)
        adj = self.trees[0].get_adjacent_matrix()
        visited = []
        explore = [first_ind]

        sampled = np.zeros(self.n_var)
        itr = 0
        while explore:
            current = explore.pop(0)
            neighbors = np.where(adj[current, :] == 1)[0].tolist()
            if itr == 0:
                new_x = self.ppfs[current](unis[current])

            else:
                for i in range(itr - 1, -1, -1):
                    current_ind = -1

                    if i >= self.truncated:
                        continue

                    current_tree = self.trees[i].edges
                    # get index of edge to retrieve
                    for edge in current_tree:
                        if i == 0:
                            if (edge.L == current and edge.R == visited[0]) or\
                               (edge.R == current and edge.L == visited[0]):
                                current_ind = edge.index
                                break
                        else:
                            if edge.L == current or edge.R == current:
                                condition = set(edge.D)
                                condition.add(edge.L)
                                condition.add(edge.R)

                                visit_set = set(visited)
                                visit_set.add(current)

                                if condition.issubset(visit_set):
                                    current_ind = edge.index
                                break

                    if current_ind != -1:
                        # the node is not indepedent contional on visited node
                        copula_type = current_tree[current_ind].name
                        copula = Bivariate(CopulaTypes(copula_type))
                        copula.theta = current_tree[current_ind].theta
                        derivative = copula.partial_derivative_scalar

                        if i == itr - 1:
                            tmp = optimize.fminbound(
                                derivative, EPSILON, 1.0,
                                args=(unis[visited[0]], unis[current])
                            )
                        else:
                            tmp = optimize.fminbound(
                                derivative, EPSILON, 1.0,
                                args=(unis[visited[0]], tmp)
                            )

                        tmp = min(max(tmp, EPSILON), 0.99)

                new_x = self.ppfs[current](tmp)

            sampled[current] = new_x

            for s in neighbors:
                if s not in visited:
                    explore.insert(0, s)

            itr += 1
            visited.insert(0, current)

        return sampled