Package jazzparser :: Package misc :: Package raphsto :: Class RaphstoHmm
[hide private]
[frames] | no frames]

Class RaphstoHmm

source code

                       object --+    
                                |    
utils.nltk.ngram.model.NgramModel --+
                                    |
                                   RaphstoHmm
Known Subclasses:

Hidden Markov Model that implements the model described in the paper.

States are in the form of a tuple (tonic,mode,chord) where tonic is in \{0, ..., 11\}; mode is one of \{constants.MODE_MAJOR, constants.MODE_MINOR\}; chord is one of \{constants.CHORD_I, ..., constants.CHORD_VII\}.

Emissions are in the form of a list of pairs (pc,r), where pc is a pitch class (like tonic above) and r is an onset time abstraction and is one of \{0, ...,3\}.

Unlike with NgramModel, the emission domain is the domain of values from which each element of an emission is selected. In other words, the actually domain of emissions is the powerset of emission_dom.

In the description of the model, r is described as a condition of the emission distribution. Although the model is truly replicated here, the interface suggests otherwise, since we treat the rythmic markers as if they're part of the emissions. From a conceptual point of view, this makes more sense and I think it's rather odd that the model doesn't treat them this way.

As for prior distributions (start state distribution), we ignore the tonic of the first state - it doesn't make any sense to look at it since the model is pitch-invariant throughout. We then just use our marginalized chord distribution and assume that the mode distribution is uniform (there are only two and it probably won't make much difference).


Note: mutable distributions: if you use mutable distributions for transition or emission distributions, make sure you invalidate the cache by calling clear_cache after updating the distributions. Various caches are used to speed up retreival of probabilities. If you fail to do this, you'll end up getting some values unpredictably from the old distributions

Instance Methods [hide private]
 
__init__(self, key_transition_dist, chord_transition_dist, emission_dist, chord_dist, model_name='default', history='', description='', chord_set='scale+dom7')
x.__init__(...) initializes x; see help(type(x)) for signature
source code
 
label(self, handler)
Produces labels for the midi data using the model.
source code
 
clear_cache(self)
Initializes or empties probability distribution caches.
source code
 
add_history(self, string)
Adds a line to the end of this model's history string.
source code
 
sequence_to_ngram(self, seq) source code
 
ngram_to_sequence(self, ngram) source code
 
last_label_in_ngram(self, ngram) source code
 
backoff_ngram(self, ngram) source code
 
set_chord_transition_probabilities(self, spec)
Sets the parameters of the chord transition distribution.
source code
 
retrain_unsupervised(self, *args, **kwargs)
Unsupervised training.
source code
 
transition_log_probability(self, state, previous_state)
Gives the probability P(label_i | label_(i-1), ..., label_(i-n)), where the previous labels are given in the sequence label_context.
source code
 
emission_log_probability(self, emission, state)
Gives the probability P(emission | label).
source code
 
forward_log_probabilities(self, sequence, normalize=True)
We override this to provide a faster implementation.
source code
 
backward_log_probabilities(self, sequence, normalize=True)
We override this to provide a faster implementation.
source code
 
normal_forward_probabilities(self, sequence)
If you want the normalized matrix of forward probabilities, it's ok to use normal (non-log) probabilities and these can be computed more quickly, since you don't need to sum logs (which is time consuming).
source code
 
normal_backward_probabilities(self, sequence)
Return the backward probability matrices a Numpy array.
source code
 
compute_gamma(self, sequence, forward=None, backward=None)
Computes the gamma matrix used in Baum-Welch.
source code
 
compute_xi(self, sequence, forward=None, backward=None)
Computes the xi matrix used by Baum-Welch.
source code
 
to_picklable_dict(self)
Produces a picklable representation of model as a dict.
source code
 
_get_my_filename(self) source code
 
save(self)
Saves the model data to a file.
source code
 
delete(self)
Removes all the model's data.
source code

Inherited from utils.nltk.ngram.model.NgramModel: __repr__, backward_probabilities, decode_forward, decode_gamma, emission_probability, forward_backward_log_probabilities, forward_backward_probabilities, forward_probabilities, gamma_probabilities, generalized_viterbi, generate, get_all_ngrams, get_backoff_models, get_emission_matrix, get_transition_matrix, labeled_sequence_log_probability, normal_forward_backward_probabilities, precompute, transition_log_probability_debug, transition_probability, transition_probability_debug, viterbi_decode, viterbi_selector_probabilities

Inherited from object: __delattr__, __format__, __getattribute__, __hash__, __new__, __reduce__, __reduce_ex__, __setattr__, __sizeof__, __str__, __subclasshook__

Class Methods [hide private]
 
get_label_dom(cls, chord_set='scale+dom7') source code
 
initialize_chord_types(cls, probs, model_name='default', chord_set='scale+dom7')
Creates a new model with the distributions initialized naively to favour simple chord-types, as R&S do in the paper.
source code
 
initialize_existing_model(cls, old_model_name, model_name='default')
Initializes a model using parameters from an already trained model.
source code
 
from_picklable_dict(cls, data, model_name='default')
Reproduces an n-gram model that was converted to a picklable form using to_picklable_dict.
source code
 
_get_model_dir(cls) source code
 
_get_filename(cls, model_name) source code
 
list_models(cls)
Returns a list of the names of available models.
source code
 
load_model(cls, model_name) source code
Static Methods [hide private]
 
get_trainer() source code
 
train(*args, **kwargs)
We don't train a RaphstoHmm using the train method, since our training procedure is not the same as the superclass, so this would be confusing, as this method would require completely different input.
source code
Class Variables [hide private]
  V = {0: 1, 1: 1, 2: 1, 3: 4, 4: 5}
This is the function (mapping) described in the model as V.
  LABEL_DOM = None
hash(x)
Properties [hide private]
  _filename

Inherited from utils.nltk.ngram.model.NgramModel: model_type

Inherited from object: __class__

Method Details [hide private]

__init__(self, key_transition_dist, chord_transition_dist, emission_dist, chord_dist, model_name='default', history='', description='', chord_set='scale+dom7')
(Constructor)

source code 

x.__init__(...) initializes x; see help(type(x)) for signature

Overrides: object.__init__
(inherited documentation)

label(self, handler)

source code 

Produces labels for the midi data using the model.

Input is given in the form of a jazzparser.misc.raphsto.midi.MidiHandler instance.

Uses Viterbi on the model to get a state sequence and returns a list containing a (state,time) pair for each state change.

clear_cache(self)

source code 

Initializes or empties probability distribution caches.

Make sure to call this if you change or update the distributions.

Overrides: utils.nltk.ngram.model.NgramModel.clear_cache

train(*args, **kwargs)
Static Method

source code 

We don't train a RaphstoHmm using the train method, since our training procedure is not the same as the superclass, so this would be confusing, as this method would require completely different input.

We train our models by initializing in some way (usually hand-setting of parameters), then using Baum-Welch on unlabelled data.

This method will just raise a RaphstoHmmError.

Overrides: utils.nltk.ngram.model.NgramModel.train

initialize_chord_types(cls, probs, model_name='default', chord_set='scale+dom7')
Class Method

source code 

Creates a new model with the distributions initialized naively to favour simple chord-types, as R&S do in the paper. They don't say what values they use for probs, except that they're high, medium and low respectively.

The transition distribution is initialized so that everything is equiprobable.

Parameters:
  • probs (3-tuple of floats) - probability mass to assign to (0.) chord notes, (1.) scale notes and (2.) other notes. The three values should sum to 1.0 (but will be normalized to if they don't)

set_chord_transition_probabilities(self, spec)

source code 

Sets the parameters of the chord transition distribution. This is used in initialization. The parameters are extracted from a string: this is so that it can be specified in a script option.

The required format of the string is a comma-separated list of parameters given as C0->C1-P, where C0 and C1 are chords (I, II, etc) that are in the model's distribution and P is a float probability. Parameters not specified will be evenly distributed the remaining probability mass.

retrain_unsupervised(self, *args, **kwargs)

source code 

Unsupervised training. Passes straight over to the train.RaphstoBaumWelchTrainer.

See Also: jazzparser.misc.raphsto.train.RaphstoBaumWelchTrainer

transition_log_probability(self, state, previous_state)

source code 

Gives the probability P(label_i | label_(i-1), ..., label_(i-n)), where the previous labels are given in the sequence label_context. The context should be in reverse order, i.e. with the most recent label at the start.

Note that this is the probability of a label given the previous n-1 labels, which is the same as the probability of the n-gram [label_i, ..., label_(i-n+1)] given the ngram [label_(i-1), ..., label_(i-n)], since all but the last element of the ngram overlaps with the condition, so has probability 1.

Caches all computed transition probabilities. This is particularly important for backoff models. Many n-grams will back off to the same (n-1)-gram and we don't want to recompute the transition probability for that each time.

Overrides: utils.nltk.ngram.model.NgramModel.transition_log_probability
(inherited documentation)

emission_log_probability(self, emission, state)

source code 

Gives the probability P(emission | label). Returned as a base 2 log.

Overrides: utils.nltk.ngram.model.NgramModel.emission_log_probability
(inherited documentation)

forward_log_probabilities(self, sequence, normalize=True)

source code 

We override this to provide a faster implementation.

It might also be possible to speed up the superclass' implementation using numpy, but it's easier here because we know we're using an HMM, not a higher-order ngram.

This is based on the fwd prob calculation in NLTK's HMM implementation.

Returns a numpy 2d array instead of a list of lists.

Overrides: utils.nltk.ngram.model.NgramModel.forward_log_probabilities

backward_log_probabilities(self, sequence, normalize=True)

source code 

We override this to provide a faster implementation.

Overrides: utils.nltk.ngram.model.NgramModel.backward_log_probabilities

See Also: forward_log_probability

Returns a numpy 2d array instead of a list of lists.

normal_forward_probabilities(self, sequence)

source code 

If you want the normalized matrix of forward probabilities, it's ok to use normal (non-log) probabilities and these can be computed more quickly, since you don't need to sum logs (which is time consuming).

Returns the matrix, and also the vector of values that each timestep was divided by to normalize (i.e. total probability of each timestep over all states). Also returns the total log probability of the sequence.

Parameters:
  • seq_prob - return the log probability of the whole sequence as well as the array (tuple of (array,logprob)).
Returns:
(matrix,normalizing vector,log prob)
Overrides: utils.nltk.ngram.model.NgramModel.normal_forward_probabilities

normal_backward_probabilities(self, sequence)

source code 

Return the backward probability matrices a Numpy array. This is faster than backward_log_probabilities because it uses Numpy arrays with non-log probabilities and normalizes each timestep.

Returns:
matrix over timesteps and all labels, with a dimension for each state in each (n-1)-gram: for time steps i and labels k, P(word^(i+1), ..., word^T | label_k^i)
Overrides: utils.nltk.ngram.model.NgramModel.normal_backward_probabilities

See Also: normal_forward_probabilities

(except that this doesn't return the logprob)

compute_gamma(self, sequence, forward=None, backward=None)

source code 

Computes the gamma matrix used in Baum-Welch. This is the matrix of state occupation probabilities for each timestep. It is computed from the forward and backward matrices.

These can be passed in as arguments to avoid recomputing if you need to reuse them, but will be computed from the model if not given. They are assumed to be the matrices computed by normal_forward_probabilities and normal_backward_probabilities (i.e. normalized, non-log probabilities).

compute_xi(self, sequence, forward=None, backward=None)

source code 

Computes the xi matrix used by Baum-Welch. It is the matrix of joint probabilities of occupation of pairs of conecutive states: P(i_t, j_{t+1} | O).

As with compute_gamma forward and backward matrices can optionally be passed in to avoid recomputing.

to_picklable_dict(self)

source code 

Produces a picklable representation of model as a dict. You can't just pickle the object directly because some of the NLTK classes can't be pickled. You can pickle this dict and reconstruct the model using NgramModel.from_picklable_dict(dict).

Overrides: utils.nltk.ngram.model.NgramModel.to_picklable_dict

from_picklable_dict(cls, data, model_name='default')
Class Method

source code 

Reproduces an n-gram model that was converted to a picklable form using to_picklable_dict.

Overrides: utils.nltk.ngram.model.NgramModel.from_picklable_dict

Property Details [hide private]

_filename

Get Method:
_get_my_filename(self)