class_docstr: Implements a simple HMM fitted with Viterbi algorithm.
  
  The HMM annotation estimator uses the
  the Viterbi algorithm to fit a sequence of 'hidden state' class
  annotations (represented by an array of integers the same size
  as the observation) to a sequence of observations.
  
  This is done by finding the most likely path given the emission
  probabilities - (ie the probability that a particular observation
  would be generated by a given hidden state), the transition prob
  (ie the probability of transitioning from one state to another or
  staying in the same state) and the initial probabilities - ie the
  belief of the probability distribution of hidden states at the
  start of the observation sequence).
  
  Current assumptions/limitations of this implementation:
     - the spacing of time series points is assumed to be equivalent.
     - it only works on univariate data.
     - the emission parameters and transition probabilities are
         assumed to be known.
     - if no initial probs are passed, uniform probabilities are
         assigned (ie rather than the stationary distribution.)
     - requires and returns np.ndarrays.
  
  _fit is currently empty as the parameters of the probability
  distribution are required to be passed to the algorithm.
  
  _predict - first the transition_probability and transition_id matrices are
  calculated - these are both nxm matrices, where n is the number of
  hidden states and m is the number of observations. The transition
  probability matrices record the probability of the most likely
  sequence which has observation `m` being assigned to hidden state n.
  The transition_id matrix records the step before hidden state n that
  proceeds it in the most likely path.  This logic is mostly carried
  out by helper function _calculate_trans_mats.
  Next, these matrices are used to calculate the most likely
  path (by backtracing from the final mostly likely state and the
  id's that proceeded it.)  This logic is done via a helper func
  hmm_viterbi_label.
  
  Parameters
  ----------
  emission_funcs : list, shape = [num hidden states]
      List should be of length n (the number of hidden states)
      Either a list of callables [fx_1, fx_2] with signature fx_1(X) -> float
      or a list of callables and matched keyword arguments for those
      callables [(fx_1, kwarg_1), (fx_2, kwarg_2)] with signature
      fx_1(X, **kwargs) -> float (or a list with some mixture of the two).
      The callables should take a value and return a probability when passed
      a single observation. All functions should be properly normalized PDFs
      over the same space as the observed data.
  transition_prob_mat: 2D np.ndarry, shape = [num_states, num_states]
      Each row should sum to 1 in order to be properly normalized
      (ie the j'th column in the i'th row represents the
      probability of transitioning from state i to state j.)
  initial_probs: 1D np.ndarray, shape = [num hidden states], optional
      A array of probabilities that the sequence of hidden states starts in each
      of the hidden states. If passed, should be of length `n` the number of
      hidden states and  should match the length of both the emission funcs
      list and the transition_prob_mat. The initial probs should be reflective
      of prior beliefs.  If none is passed will each hidden state will be
      assigned an equal initial prob.
  
  Attributes
  ----------
  emission_funcs : list, shape = [num_hidden_states]
      The functions to use in calculating the emission probabilities. Taken
      from the __init__ param of same name.
  transition_prob_mat: 2D np.ndarry, shape = [num_states, num_states]
      Matrix of transition probabilities from hidden state to hidden state.
      Taken from the __init__ param of same name.
  initial_probs : 1D np.ndarray, shape = [num_hidden_states]
      Probability over the hidden state identity of the first state. If the
      __init__ param of same name was passed it will take on that value.
      Otherwise it is set to be uniform over all hidden states.
  num_states : int
      The number of hidden states.  Set to be the length of the emission_funcs
      parameter which was passed.
  states : list
      A list of integers from 0 to num_states-1.  Integer labels for the hidden
      states.
  num_obs : int
      The length of the observations data.  Extracted from data.
  trans_prob : 2D np.ndarray, shape = [num_observations, num_hidden_states]
      Shape [num observations, num hidden states]. The max probability that that
      observation is assigned to that hidden state.
      Calculated in _calculate_trans_mat and assigned in _predict.
  trans_id : 2D np.ndarray, shape = [num_observations, num_hidden_states]
      Shape [num observations, num hidden states]. The state id of the state
      proceeding the observation is assigned to that hidden state in the most
      likely path where that occurs. Calculated in _calculate_trans_mat and
      assigned in _predict.
  
  Examples
  --------
  >>> from sktime.annotation.hmm import HMM
  >>> from scipy.stats import norm
  >>> from numpy import asarray
  >>> # define the emission probs for our HMM model:
  >>> centers = [3.5,-5]
  >>> sd = [.25 for i in centers]
  >>> emi_funcs = [(norm.pdf, {'loc': mean,
  ...  'scale': sd[ind]}) for ind, mean in enumerate(centers)]
  >>> hmm_est = HMM(emi_funcs, asarray([[0.25,0.75], [0.666, 0.333]]))
  >>> # generate synthetic data (or of course use your own!)
  >>> obs = asarray([3.7,3.2,3.4,3.6,-5.1,-5.2,-4.9])
  >>> hmm_est = hmm_est.fit(obs)
  >>> labels = hmm_est.predict(obs)
class_docstr_tok: ["Implements","a","simple","HMM","fitted","with","Viterbi","algorithm",".","The","HMM","annotation","estimator","uses","the","the","Viterbi","algorithm","to","fit","a","sequence","of","'hidden","state","'","class","annotations","(","represented","by","an","array","of","integers","the","same","size","as","the","observation",")","to","a","sequence","of","observations",".","This","is","done","by","finding","the","most","likely","path","given","the","emission","probabilities","-","(","ie","the","probability","that","a","particular","observation","would","be","generated","by","a","given","hidden","state",")",",","the","transition","prob","(","ie","the","probability","of","transitioning","from","one","state","to","another","or","staying","in","the","same","state",")","and","the","initial","probabilities","-","ie","the","belief","of","the","probability","distribution","of","hidden","states","at","the","start","of","the","observation","sequence",")",".","Current","assumptions\/limitations","of","this","implementation",":","-","the","spacing","of","time","series","points","is","assumed","to","be","equivalent",".","-","it","only","works","on","univariate","data",".","-","the","emission","parameters","and","transition","probabilities","are","assumed","to","be","known",".","-","if","no","initial","probs","are","passed",",","uniform","probabilities","are","assigned","(","ie","rather","than","the","stationary","distribution",".",")","-","requires","and","returns","np.ndarrays",".","_fit","is","currently","empty","as","the","parameters","of","the","probability","distribution","are","required","to","be","passed","to","the","algorithm",".","_predict","-","first","the","transition_probability","and","transition_id","matrices","are","calculated","-","these","are","both","nxm","matrices",",","where","n","is","the","number","of","hidden","states","and","m","is","the","number","of","observations",".","The","transition","probability","matrices","record","the","probability","of","the","most","likely","sequence","which","has","observation","`","m","`","being","assigned","to","hidden","state","n.","The","transition_id","matrix","records","the","step","before","hidden","state","n","that","proceeds","it","in","the","most","likely","path",".","This","logic","is","mostly","carried","out","by","helper","function","_calculate_trans_mats",".","Next",",","these","matrices","are","used","to","calculate","the","most","likely","path","(","by","backtracing","from","the","final","mostly","likely","state","and","the","id","'s","that","proceeded","it",".",")","This","logic","is","done","via","a","helper","func","hmm_viterbi_label",".","Parameters","--","--","--","--","--","emission_funcs",":","list",",","shape","=","[","num","hidden","states","]","List","should","be","of","length","n","(","the","number","of","hidden","states",")","Either","a","list","of","callables","[","fx_1",",","fx_2","]","with","signature","fx_1","(","X",")","-",">","float","or","a","list","of","callables","and","matched","keyword","arguments","for","those","callables","[","(","fx_1",",","kwarg_1",")",",","(","fx_2",",","kwarg_2",")","]","with","signature","fx_1","(","X",",","*","*","kwargs",")","-",">","float","(","or","a","list","with","some","mixture","of","the","two",")",".","The","callables","should","take","a","value","and","return","a","probability","when","passed","a","single","observation",".","All","functions","should","be","properly","normalized","PDFs","over","the","same","space","as","the","observed","data",".","transition_prob_mat",":","2D","np.ndarry",",","shape","=","[","num_states",",","num_states","]","Each","row","should","sum","to","1","in","order","to","be","properly","normalized","(","ie","the","j'th","column","in","the","i'th","row","represents","the","probability","of","transitioning","from","state","i","to","state","j",".",")","initial_probs",":","1D","np.ndarray",",","shape","=","[","num","hidden","states","]",",","optional","A","array","of","probabilities","that","the","sequence","of","hidden","states","starts","in","each","of","the","hidden","states",".","If","passed",",","should","be","of","length","`","n","`","the","number","of","hidden","states","and","should","match","the","length","of","both","the","emission","funcs","list","and","the","transition_prob_mat",".","The","initial","probs","should","be","reflective","of","prior","beliefs",".","If","none","is","passed","will","each","hidden","state","will","be","assigned","an","equal","initial","prob",".","Attributes","--","--","--","--","--","emission_funcs",":","list",",","shape","=","[","num_hidden_states","]","The","functions","to","use","in","calculating","the","emission","probabilities",".","Taken","from","the","__init__","param","of","same","name",".","transition_prob_mat",":","2D","np.ndarry",",","shape","=","[","num_states",",","num_states","]","Matrix","of","transition","probabilities","from","hidden","state","to","hidden","state",".","Taken","from","the","__init__","param","of","same","name",".","initial_probs",":","1D","np.ndarray",",","shape","=","[","num_hidden_states","]","Probability","over","the","hidden","state","identity","of","the","first","state",".","If","the","__init__","param","of","same","name","was","passed","it","will","take","on","that","value",".","Otherwise","it","is","set","to","be","uniform","over","all","hidden","states",".","num_states",":","int","The","number","of","hidden","states",".","Set","to","be","the","length","of","the","emission_funcs","parameter","which","was","passed",".","states",":","list","A","list","of","integers","from","0","to","num_states-1",".","Integer","labels","for","the","hidden","states",".","num_obs",":","int","The","length","of","the","observations","data",".","Extracted","from","data",".","trans_prob",":","2D","np.ndarray",",","shape","=","[","num_observations",",","num_hidden_states","]","Shape","[","num","observations",",","num","hidden","states","]",".","The","max","probability","that","that","observation","is","assigned","to","that","hidden","state",".","Calculated","in","_calculate_trans_mat","and","assigned","in","_predict",".","trans_id",":","2D","np.ndarray",",","shape","=","[","num_observations",",","num_hidden_states","]","Shape","[","num","observations",",","num","hidden","states","]",".","The","state","id","of","the","state","proceeding","the","observation","is","assigned","to","that","hidden","state","in","the","most","likely","path","where","that","occurs",".","Calculated","in","_calculate_trans_mat","and","assigned","in","_predict",".","Examples","--","--","--","--",">",">",">","from","sktime.annotation.hmm","import","HMM",">",">",">","from","scipy.stats","import","norm",">",">",">","from","numpy","import","asarray",">",">",">","#","define","the","emission","probs","for","our","HMM","model",":",">",">",">","centers","=","[","3.5",",","-5","]",">",">",">","sd","=","[",".25","for","i","in","centers","]",">",">",">","emi_funcs","=","[","(","norm.pdf",",","{","'loc","'",":","mean",",","...","'scale","'",":","sd","[","ind","]","}",")","for","ind",",","mean","in","enumerate","(","centers",")","]",">",">",">","hmm_est","=","HMM","(","emi_funcs",",","asarray","(","[","[","0.25,0.75","]",",","[","0.666",",","0.333","]","]",")",")",">",">",">","#","generate","synthetic","data","(","or","of","course","use","your","own","!",")",">",">",">","obs","=","asarray","(","[","3.7,3.2,3.4,3.6",",","-5.1",",","-5.2",",","-4.9","]",")",">",">",">","hmm_est","=","hmm_est.fit","(","obs",")",">",">",">","labels","=","hmm_est.predict","(","obs",")"]
docstr: Calculate the transition mats used in the Viterbi algorithm.
  
  Parameters
  ----------
  initial_probs : 1D np.ndarray, shape = [num_hidden_states]
      A nx1 dimensional array of floats where n
      represents the number of hidden states in the model. It
      contains the probability that hidden state for the state
      before the first observation was state n.  Should sum to 1.
  emi_probs : 2D np.ndarray, shape = [num_observations, num_hidden_states]
      A nxm dimensional arrayof floats, where n is the
      number of hidden states and m is the number of observations.
      For a given observation, it should contain the probability that it
      could havbe been generated (ie emitted) from each of the hidden states
      Each entry should be between 0 and 1
  transition_prob_mat : 2D np.ndarray, shape = [num_states, num_states]
      A nxn dimensional array of floats where n is
      the number of hidden states in the model. The jth col in the ith row
      represents the probability of transitioning to state j from state i.
      Thus each row should sum to 1.
  num_obs : int,
      the number of observations (m)
  num_states : int,
      the number of hidden states (n)
  
  Returns
  -------
  trans_prob : 2D np.ndarray, shape = [num_observations, num_hidden_states]
      an nxm dimensional array which represents the
      maximum probability of the hidden state of observation m is state n.
  trans_id : 2D np.ndarray, shape = [num_observations, num_hidden_states]
      a nxm dimensional array which for each observation
      "i" and state "j" the i,j entry records the state_id of the most
      likely state that could have led to the hidden state being "i" for
      observation "j".
docstr_tok: ["Calculate","the","transition","mats","used","in","the","Viterbi","algorithm",".","Parameters","--","--","--","--","--","initial_probs",":","1D","np.ndarray",",","shape","=","[","num_hidden_states","]","A","nx1","dimensional","array","of","floats","where","n","represents","the","number","of","hidden","states","in","the","model",".","It","contains","the","probability","that","hidden","state","for","the","state","before","the","first","observation","was","state","n.","Should","sum","to","1.","emi_probs",":","2D","np.ndarray",",","shape","=","[","num_observations",",","num_hidden_states","]","A","nxm","dimensional","arrayof","floats",",","where","n","is","the","number","of","hidden","states","and","m","is","the","number","of","observations",".","For","a","given","observation",",","it","should","contain","the","probability","that","it","could","havbe","been","generated","(","ie","emitted",")","from","each","of","the","hidden","states","Each","entry","should","be","between","0","and","1","transition_prob_mat",":","2D","np.ndarray",",","shape","=","[","num_states",",","num_states","]","A","nxn","dimensional","array","of","floats","where","n","is","the","number","of","hidden","states","in","the","model",".","The","jth","col","in","the","ith","row","represents","the","probability","of","transitioning","to","state","j","from","state","i",".","Thus","each","row","should","sum","to","1.","num_obs",":","int",",","the","number","of","observations","(","m",")","num_states",":","int",",","the","number","of","hidden","states","(","n",")","Returns","--","--","--","-","trans_prob",":","2D","np.ndarray",",","shape","=","[","num_observations",",","num_hidden_states","]","an","nxm","dimensional","array","which","represents","the","maximum","probability","of","the","hidden","state","of","observation","m","is","state","n.","trans_id",":","2D","np.ndarray",",","shape","=","[","num_observations",",","num_hidden_states","]","a","nxm","dimensional","array","which","for","each","observation","``","i","''","and","state","``","j","''","the","i",",","j","entry","records","the","state_id","of","the","most","likely","state","that","could","have","led","to","the","hidden","state","being","``","i","''","for","observation","``","j","''","."]
code: def _calculate_trans_mats(
      initial_probs: np.ndarray,
      emi_probs: np.ndarray,
      transition_prob_mat: np.ndarray,
      num_obs: int,
      num_states: int,
  ) -> Tuple[np.array, np.array]:
      """Calculate the transition mats used in the Viterbi algorithm.
  
      Parameters
      ----------
      initial_probs : 1D np.ndarray, shape = [num_hidden_states]
          A nx1 dimensional array of floats where n
          represents the number of hidden states in the model. It
          contains the probability that hidden state for the state
          before the first observation was state n.  Should sum to 1.
      emi_probs : 2D np.ndarray, shape = [num_observations, num_hidden_states]
          A nxm dimensional arrayof floats, where n is the
          number of hidden states and m is the number of observations.
          For a given observation, it should contain the probability that it
          could havbe been generated (ie emitted) from each of the hidden states
          Each entry should be between 0 and 1
      transition_prob_mat : 2D np.ndarray, shape = [num_states, num_states]
          A nxn dimensional array of floats where n is
          the number of hidden states in the model. The jth col in the ith row
          represents the probability of transitioning to state j from state i.
          Thus each row should sum to 1.
      num_obs : int,
          the number of observations (m)
      num_states : int,
          the number of hidden states (n)
  
      Returns
      -------
      trans_prob : 2D np.ndarray, shape = [num_observations, num_hidden_states]
          an nxm dimensional array which represents the
          maximum probability of the hidden state of observation m is state n.
      trans_id : 2D np.ndarray, shape = [num_observations, num_hidden_states]
          a nxm dimensional array which for each observation
          "i" and state "j" the i,j entry records the state_id of the most
          likely state that could have led to the hidden state being "i" for
          observation "j".
      """
      # trans_prob represents the maximum probability of being in that
      # state at that stage
      trans_prob = np.zeros((num_states, num_obs))
      trans_prob[:, 0] = np.log(initial_probs) + np.log(emi_probs[:, 0])
  
      # trans_id is the index of the state that would have been the most
      # likely preceding state.
      trans_id = np.zeros((num_states, num_obs), dtype=np.int32)
  
      # use Vertibi Algorithm to fill in trans_prob and trans_id:
      for i in range(1, num_obs):
          # adds log(transition_prob_mat) element-wise:
          paths = np.log(transition_prob_mat)
          # adds the probabilities for the state before columns wise:
          paths += np.stack(
              [trans_prob[:, i - 1] for _ in range(num_states)], axis=0
          ).T
          # adds the probabilities from emission row wise:
          paths += np.stack(
              [np.log(emi_probs[:, i]) for _ in range(num_states)],
              axis=0,
          )
          trans_id[:, i] = np.argmax(paths, axis=0)
          trans_prob[:, i] = np.max(paths, axis=0)
  
      if np.any(np.isinf(trans_prob[:, -1])):
          warnings.warn(
              "Change parameters, the distribution doesn't work",
              stacklevel=2,
          )
  
      return trans_prob, trans_id
  
file_path: sktime/sktime/annotation/hmm.py
imports: import warnings
  from typing import Tuple
  import numpy
  from scipy.stats import norm
  from sktime.annotation.base._base import BaseSeriesAnnotator
label_desc: Use image node_id 3 for calling the HMM obj's underlying member method code with example usage: obj._calculate_trans_mats(initial_probs, emi_probs, transition_prob_mat, num_obs, num_states) and returns: trans_prob,  trans_id