Ejemplo n.º 1
0
 def fromJSON(self, jsonObj):
     """Initializes the prototype with a JSON dictionary."""
     super(PrototypeHMM, self).fromJSON(jsonObj)
     self.N = jsonObj["N"]
     self.model = WeightedGaussianHMM(self.N, "diag", algorithm="map", params="mc")
     self.model.n_features = jsonObj["n_features"]
     self.model.transmat_ = normalize(jsonObj["transmat"], axis=1)
     self.model.startprob_ = normalize(jsonObj["startprob"], axis=0)
     self.model._means_ = np.asarray(jsonObj["means"])
     self.model._covars_ = np.asarray(jsonObj["covars"])
Ejemplo n.º 2
0
    def train(self, obs, obs_weights=None, max_N=15):
        """Estimates the prototype from a set of observations.
        
        Parameters
        ----------
        max_N : int
           The maximum lenght of the HMM.
      
        """
        if obs_weights is None:
            obs_weights = np.ones(len(obs))
        else:
            obs_weights = np.asarray(obs_weights)

        # set the number of states
        if self.num_states >= 1.0:
            self.N = int(self.num_states)
        else:
            mean_length = np.mean([each_obs.shape[0] for each_obs in obs])
            self.N = min(int(self.num_states * mean_length), max_N)

        # transition prob: left-to-right
        self.transmat = np.zeros((self.N, self.N))
        for i in range(self.N):
            self.transmat[i, i] = self.self_transprob
            if i + 1 < self.N:
                self.transmat[i, i + 1] = self.next_transprob
            for j in range(i + 2, self.N):
                self.transmat[i, j] = self.skip_transprob

        self.transmat = normalize(self.transmat, axis=1)

        # state prior prob: left-most only
        self.startprob = np.zeros(self.N)
        self.startprob[0] = 1.0

        self.model = WeightedGaussianHMM(self.N, "diag", self.startprob, self.transmat, algorithm="map", params="mc")
        self.num_obs = len(obs)

        return self.model.fit(obs, obs_weights=obs_weights)
Ejemplo n.º 3
0
class PrototypeHMM(_Prototype):
    """HMM-based prototype.

    This class uses HMM as the underlying model. The similarity is defined
    in term of the log likelihood.

    Parameters
    ----------
    num_states : float
       Number of hidden states. If num_states < 1, the number of states is 
       set proportionally to the average length of the observations. 
       For example, if num_states = 0.5, the number of states will 
       be set to 0.5 * average length of the observations.

    self_transprob : float
       Probability of staying in the same state.

    next_transprob : float
       Probability of moving to the adjacent state.

    skip_transprob : float
       Probability of moving to any other non-adjacent states.

    Attributes
    ----------
    N : int
       Number of hidden states in the model.

    """

    def __init__(self, label, num_states=0.5, self_transprob=0.8, next_transprob=0.2, skip_transprob=1e-6):
        _Prototype.__init__(self, label)
        self.num_states = num_states
        self.self_transprob = self_transprob
        self.next_transprob = next_transprob
        self.skip_transprob = skip_transprob

    def train(self, obs, obs_weights=None, max_N=15):
        """Estimates the prototype from a set of observations.
        
        Parameters
        ----------
        max_N : int
           The maximum lenght of the HMM.
      
        """
        if obs_weights is None:
            obs_weights = np.ones(len(obs))
        else:
            obs_weights = np.asarray(obs_weights)

        # set the number of states
        if self.num_states >= 1.0:
            self.N = int(self.num_states)
        else:
            mean_length = np.mean([each_obs.shape[0] for each_obs in obs])
            self.N = min(int(self.num_states * mean_length), max_N)

        # transition prob: left-to-right
        self.transmat = np.zeros((self.N, self.N))
        for i in range(self.N):
            self.transmat[i, i] = self.self_transprob
            if i + 1 < self.N:
                self.transmat[i, i + 1] = self.next_transprob
            for j in range(i + 2, self.N):
                self.transmat[i, j] = self.skip_transprob

        self.transmat = normalize(self.transmat, axis=1)

        # state prior prob: left-most only
        self.startprob = np.zeros(self.N)
        self.startprob[0] = 1.0

        self.model = WeightedGaussianHMM(self.N, "diag", self.startprob, self.transmat, algorithm="map", params="mc")
        self.num_obs = len(obs)

        return self.model.fit(obs, obs_weights=obs_weights)

    def score(self, obs, last_state_only=True):
        """Calculates the score of an observation.
       
        Returns
        -------
        score : float
          If last_state_only=False, the score is defined as the log
          likelihood of the observation under the model. Otherwise,
          the score is defined as the log likelihood at the last state
          only.

        """
        obs = np.asarray(obs)
        framelogprob = self.model._compute_log_likelihood(obs)
        if last_state_only:
            _, fwdlattice = self.model._do_forward_pass(framelogprob)
            return fwdlattice[-1, -1]
        else:
            logprob, _ = self.model._do_forward_pass(framelogprob)
            return logprob

    def toJSON(self):
        """Returns a JSON dictionary representing the prototype."""
        info = super(PrototypeHMM, self).toJSON()
        info["n_components"] = int(self.model.n_components)
        info["n_features"] = int(self.model.n_features)
        info["transmat"] = self.model.transmat_.astype(np.float16).tolist()
        info["startprob"] = self.model.startprob_.astype(np.float16).tolist()
        info["means"] = self.model._means_.astype(np.float16).tolist()
        info["covars"] = self.model._covars_.astype(np.float16).tolist()
        info["N"] = self.N
        return info

    def fromJSON(self, jsonObj):
        """Initializes the prototype with a JSON dictionary."""
        super(PrototypeHMM, self).fromJSON(jsonObj)
        self.N = jsonObj["N"]
        self.model = WeightedGaussianHMM(self.N, "diag", algorithm="map", params="mc")
        self.model.n_features = jsonObj["n_features"]
        self.model.transmat_ = normalize(jsonObj["transmat"], axis=1)
        self.model.startprob_ = normalize(jsonObj["startprob"], axis=0)
        self.model._means_ = np.asarray(jsonObj["means"])
        self.model._covars_ = np.asarray(jsonObj["covars"])