Esempio n. 1
0
def test_fit_single_random_long():
    pi = np.array([0.3, 0.4, 0.3])

    a = np.array([
        [0.1, 0.1, 0.8],
        [0.5, 0.5, 0.0],
        [0.0, 0.5, 0.5]
    ])

    chain = mc.MarkovChain(pi, a)

    b = np.array([
        [0.2, 0.2, 0.2, 0.2, 0.2],
        [0.1, 0.1, 0.2, 0.3, 0.3],
        [0.0, 0.0, 0.0, 0.5, 0.5]
    ])

    model = dhmm.DiscreteHiddenMM(chain, b)

    sequence = np.random.choice(model.num_outputs, size=10000)

    model2 = model.fit_single(sequence)

    old_likelihood = model.likelihood(sequence)
    new_likelihood = model2.likelihood(sequence)

    assert new_likelihood >= old_likelihood
Esempio n. 2
0
def test_log_likelihood_constant():
    pi = np.array([1.0, 0.0, 0.0])

    a = np.array([
        [1.0, 0.0, 0.0],
        [0.5, 0.5, 0.0],
        [0.0, 0.5, 0.5]
    ])

    chain = mc.MarkovChain(pi, a)

    b = np.array([
        [1.0, 0.0, 0.0, 0.0, 0.0],
        [0.1, 0.1, 0.2, 0.3, 0.3],
        [0.0, 0.0, 0.0, 0.5, 0.5]
    ])

    model = dhmm.DiscreteHiddenMM(chain, b)

    sequence = np.random.choice(model.num_outputs, size=10)

    for i in range(100):
        likelihood = model.likelihood(sequence)
        log_likelihood = model.log_likelihood(sequence)

        assert np.allclose(np.log(likelihood), log_likelihood)
Esempio n. 3
0
def test_fit_single():
    pi = np.array([0.3, 0.4, 0.3])

    a = np.array([
        [0.1, 0.1, 0.8],
        [0.5, 0.5, 0.0],
        [0.0, 0.5, 0.5]
    ])

    chain = mc.MarkovChain(pi, a)

    b = np.array([
        [0.2, 0.2, 0.2, 0.2, 0.2],
        [0.1, 0.1, 0.2, 0.3, 0.3],
        [0.0, 0.0, 0.0, 0.5, 0.5]
    ])

    model = dhmm.DiscreteHiddenMM(chain, b)

    sequence = np.array([0, 1, 2, 3, 4])

    model2 = model.fit_single(sequence)

    old_likelihood = model.likelihood(sequence)
    new_likelihood = model2.likelihood(sequence)

    assert new_likelihood >= old_likelihood
Esempio n. 4
0
def test_likelihood_summation():
    pi = np.array([0.1, 0.9])

    a = np.array([
        [0.1, 0.9],
        [0.5, 0.5]
    ])

    chain = mc.MarkovChain(pi, a)

    b = np.array([
        [0.2, 0.2, 0.2, 0.2, 0.2],
        [0.1, 0.1, 0.2, 0.3, 0.3]
    ])

    model = dhmm.DiscreteHiddenMM(chain, b)

    summation = 0.0

    for i in range(5):
        for j in range(5):
            for k in range(5):
                for z in range(5):
                    observations = [i, j, k, z]

                    likelihood = model.likelihood(np.array(observations, dtype=int))

                    assert likelihood >= 0.0

                    summation += likelihood

    assert np.abs(summation - 1.0) < cnst.EPSILON
def test_creation_dim_fails():
    """ Dimension mismatch throws exception """
    pi = np.array([0.1, 0.9, 0.5])

    a = np.array([
        [0.1, 0.9],
        [0.5, 0.5]
    ])

    mc.MarkovChain(pi, a)
def test_creation_negative_distribution():
    """ Dimension mismatch throws exception """
    pi = np.array([1.1, -0.1])

    a = np.array([
        [0.1, 0.9],
        [0.5, 0.4]
    ])

    mc.MarkovChain(pi, a)
def test_creation_passes():
    """ Simplistic test case to make sure setup works """
    pi = np.array([0.1, 0.9])

    a = np.array([
        [0.1, 0.9],
        [0.5, 0.5]
    ])

    mc.MarkovChain(pi, a)
def test_creation_distribution_sum_2():
    """ Dimension mismatch throws exception """
    pi = np.array([0.1, 0.9])

    a = np.array([
        [0.1, 0.9],
        [0.5, 0.4]
    ])

    mc.MarkovChain(pi, a)
def test_simple_generation():
    """ Simple generation """
    pi = np.array([0.1, 0.9])

    a = np.array([
        [0.1, 0.9],
        [0.5, 0.5]
    ])

    model = mc.MarkovChain(pi, a)

    result = model.generate(n=100)

    assert result.shape[0] == 100
    assert result.dtype == int
def test_constant_generation():
    """ Simple generation """
    pi = np.array([1.0, 0.0, 0.0])

    a = np.array([
        [1.0, 0.0, 0.0],
        [0.3, 0.4, 0.3],
        [0.1, 0.8, 0.1]
    ])

    model = mc.MarkovChain(pi, a)

    result = model.generate(n=100)

    assert np.all(result < constants.EPSILON)
Esempio n. 11
0
def test_distribution_negative():
    pi = np.array([0.1, 0.9])

    a = np.array([
        [0.1, 0.9],
        [0.5, 0.5]
    ])

    chain = mc.MarkovChain(pi, a)

    b = np.array([
        [0.2, 0.2, 0.2, 0.6, -0.2],
        [0.1, 0.1, 0.2, 0.3, 0.3],
    ])

    dhmm.DiscreteHiddenMM(chain, b)
Esempio n. 12
0
def test_successful_creation():
    pi = np.array([0.1, 0.9])

    a = np.array([
        [0.1, 0.9],
        [0.5, 0.5]
    ])

    chain = mc.MarkovChain(pi, a)

    b = np.array([
        [0.2, 0.2, 0.2, 0.2, 0.2],
        [0.1, 0.1, 0.2, 0.3, 0.3]
    ])

    dhmm.DiscreteHiddenMM(chain, b)
Esempio n. 13
0
def test_distribution_does_not_sum_up():
    pi = np.array([0.1, 0.9])

    a = np.array([
        [0.1, 0.9],
        [0.5, 0.5]
    ])

    chain = mc.MarkovChain(pi, a)

    b = np.array([
        [0.2, 0.2, 0.2, 0.2, 0.2],
        [0.1, 0.1, 0.2, 0.3, 0.5]
    ])

    dhmm.DiscreteHiddenMM(chain, b)
Esempio n. 14
0
def test_dimension_mismatch():
    pi = np.array([0.1, 0.9])

    a = np.array([
        [0.1, 0.9],
        [0.5, 0.5]
    ])

    chain = mc.MarkovChain(pi, a)

    b = np.array([
        [0.2, 0.2, 0.2, 0.2, 0.2],
        [0.1, 0.1, 0.2, 0.3, 0.3],
        [0.1, 0.1, 0.2, 0.3, 0.3]
    ])

    dhmm.DiscreteHiddenMM(chain, b)
Esempio n. 15
0
def test_solve_for_state_constant_chain():
    pi = np.array([0.0, 0.0, 1.0])

    a = np.array([
        [1.0, 0.0, 0.0],
        [0.5, 0.5, 0.0],
        [0.0, 0.5, 0.5]
    ])

    chain = mc.MarkovChain(pi, a)

    b = np.array([
        [0.2, 0.2, 0.2, 0.2, 0.2],
        [0.1, 0.1, 0.2, 0.3, 0.3],
        [0.0, 0.0, 0.0, 0.5, 0.5]
    ])

    model = dhmm.DiscreteHiddenMM(chain, b)

    model.solve_for_states(np.array([0, 1, 2, 3, 4]))
Esempio n. 16
0
def test_solve_for_state_list():
    pi = np.array([1.0, 0.0, 0.0])

    a = np.array([
        [1.0, 0.0, 0.0],
        [0.5, 0.5, 0.0],
        [0.0, 0.5, 0.5]
    ])

    chain = mc.MarkovChain(pi, a)

    b = np.array([
        [0.2, 0.2, 0.2, 0.2, 0.2],
        [0.1, 0.1, 0.2, 0.3, 0.3],
        [0.0, 0.0, 0.0, 0.5, 0.5]
    ])

    model = dhmm.DiscreteHiddenMM(chain, b)

    assert np.allclose(model.solve_for_states(np.array([0, 1, 2, 3, 4])), 0)
Esempio n. 17
0
def test_generation_1():
    pi = np.array([0.1, 0.9])

    a = np.array([
        [0.1, 0.9],
        [0.5, 0.5]
    ])

    chain = mc.MarkovChain(pi, a)

    b = np.array([
        [0.2, 0.2, 0.2, 0.2, 0.2],
        [0.1, 0.1, 0.2, 0.3, 0.3]
    ])

    model = dhmm.DiscreteHiddenMM(chain, b)

    result = model.generate(100)

    assert result.shape[0] == 100
    assert result.shape[1] == 2
Esempio n. 18
0
def test_likelihood_basic():
    pi = np.array([0.1, 0.9])

    a = np.array([
        [0.1, 0.9],
        [0.5, 0.5]
    ])

    chain = mc.MarkovChain(pi, a)

    b = np.array([
        [0.2, 0.2, 0.2, 0.2, 0.2],
        [0.1, 0.1, 0.2, 0.3, 0.3]
    ])

    model = dhmm.DiscreteHiddenMM(chain, b)

    assert np.abs(model.likelihood(np.array([0], dtype=int)) - 0.11) < cnst.EPSILON
    assert np.abs(model.likelihood(np.array([1], dtype=int)) - 0.11) < cnst.EPSILON
    assert np.abs(model.likelihood(np.array([2], dtype=int)) - 0.20) < cnst.EPSILON
    assert np.abs(model.likelihood(np.array([3], dtype=int)) - 0.29) < cnst.EPSILON
    assert np.abs(model.likelihood(np.array([4], dtype=int)) - 0.29) < cnst.EPSILON
    def fit_single(self,
                   observations: np.ndarray,
                   stable=True) -> 'DiscreteHiddenMM':
        """ Perform an expectation-maximization procedure on the hidden markov chain model """
        dimension = observations.shape[0]

        if dimension > 0:
            # Helper variables
            alpha, alpha_multipliers = self._helper_alpha(observations,
                                                          stable=stable)
            beta, beta_multipliers = self._helper_beta(observations,
                                                       stable=stable)

            # Output will be stored in these variables
            new_initial_distribution = np.zeros(self.num_states, dtype=float)
            new_transition_numerator = np.zeros(
                (self.num_states, self.num_states), dtype=float)
            new_transition_denominator = np.zeros(
                (self.num_states, self.num_states), dtype=float)
            new_projection_numerator = np.zeros(
                (self.num_states, self.num_outputs), dtype=float)
            new_projection_denominator = np.zeros(
                (self.num_states, self.num_outputs), dtype=float)

            # The actual content of the algorithm is iterating the xi matrix through time
            for i in range(dimension):
                gamma = (alpha[i] * beta[i]) / (alpha[i] * beta[i]).sum()

                # This piece is only executed in the first step
                if i == 0:
                    new_initial_distribution = gamma

                # We have to skip the last step as there are one less transitions than observations
                if i < dimension - 1:
                    xi_numerator = (self.transition_matrix * np.outer(
                        alpha[i],
                        self.projection[:, observations[i + 1]] * beta[i + 1]))
                    xi = xi_numerator / xi_numerator.sum()

                    new_transition_numerator += xi
                    new_transition_denominator += gamma.reshape(
                        (self.num_states, 1))

                new_projection_numerator[:, observations[i]] += gamma
                new_projection_denominator += gamma.reshape(
                    (self.num_states, 1))

            new_transition = new_transition_numerator / new_transition_denominator
            new_projection = new_projection_numerator / new_projection_denominator

            # A way to handle divisions 0/0
            new_transition = np.where(np.isnan(new_transition),
                                      np.eye(self.num_states), new_transition)
            new_projection = np.where(np.isnan(new_projection),
                                      1.0 / self.num_outputs, new_projection)

            return DiscreteHiddenMM(
                mc.MarkovChain(new_initial_distribution, new_transition),
                new_projection)
        else:
            return self