Implementation of a homogeneous Markov model of order 0 based on AbstractModel: Difference between revisions

From Jstacs
Jump to navigationJump to search
(New page: <source lang="java"> import java.util.Arrays; import de.jstacs.NonParsableException; import de.jstacs.NotTrainedException; import de.jstacs.data.AlphabetContainer; import de.jstacs.data.S...)
 
No edit summary
Line 91: Line 91:


public void train( Sample data, double[] weights ) throws Exception {
public void train( Sample data, double[] weights ) throws Exception {
//if we do not have any weights, we create some,
//giving all sequences the same weight
if(weights == null){
weights = new double[data.getNumberOfElements()];
Arrays.fill( weights, 1.0 );
}
//reset the parameter array
//reset the parameter array
Arrays.fill( probs, 0.0 );
Arrays.fill( probs, 0.0 );
//default sequence weight
double w = 1;
//for each sequence in the data set
//for each sequence in the data set
for(int i=0;i<data.getNumberOfElements();i++){
for(int i=0;i<data.getNumberOfElements();i++){
//retrieve sequence
//retrieve sequence
Sequence seq = data.getElementAt( i );
Sequence seq = data.getElementAt( i );
//if we do have any weights, use them
if(weights != null){
w = weights[i]
}
//for each position in the sequence
//for each position in the sequence
for(int j=0;j<seq.getLength();j++){
for(int j=0;j<seq.getLength();j++){
//count symbols, weighted by weights
//count symbols, weighted by weights
probs[ seq.discreteVal( j ) ] += weights[i];
probs[ seq.discreteVal( j ) ] += w;
}
}
}
}

Revision as of 08:33, 5 September 2008

import java.util.Arrays;

import de.jstacs.NonParsableException;
import de.jstacs.NotTrainedException;
import de.jstacs.data.AlphabetContainer;
import de.jstacs.data.Sample;
import de.jstacs.data.Sequence;
import de.jstacs.io.XMLParser;
import de.jstacs.models.AbstractModel;
import de.jstacs.results.NumericalResult;
import de.jstacs.results.NumericalResultSet;



public class HomogeneousMarkovModel extends AbstractModel {

	//array for the parameters, i.e. the probabilities for each symbol
	private double[] probs;
	//stores if the model has been trained
	private boolean isTrained;
	
	public HomogeneousMarkovModel( AlphabetContainer alphabets ) throws Exception {
		//we have a homogeneous Model, hence the length is set to 0
		super( alphabets, 0 );
		//a homogeneous Model can only handle simple alphabets
		if(! (alphabets.isSimple() && alphabets.isDiscrete()) ){
			throw new Exception("Only simple and discrete alphabets allowed");
		}
		//initialize parameter array
		this.probs = new double[(int) alphabets.getAlphabetLengthAt( 0 )];
		//we have not trained the model, yet
		isTrained = false;
	}

	public HomogeneousMarkovModel( StringBuffer stringBuff ) throws NonParsableException {
		super( stringBuff );
	}

	@Override
	protected void fromXML( StringBuffer xml ) throws NonParsableException {
		//extract our XML-code
		xml = XMLParser.extractForTag( xml, "homogeneousMarkovModel" );
		//extract all the variables using XMLParser
		alphabets = (AlphabetContainer) XMLParser.extractStorableForTag( xml, "alphabets" );
		length = XMLParser.extractIntForTag( xml, "length" );
		probs = XMLParser.extractDoubleArrayForTag( xml, "probs" );
		isTrained = XMLParser.extractBooleanForTag( xml, "isTrained" );
	}

	public StringBuffer toXML() {
		StringBuffer buf = new StringBuffer();
		//pack all the variables using XMLParser
		XMLParser.appendStorableWithTags( buf, alphabets, "alphabets" );
		XMLParser.appendIntWithTags( buf, length, "length" );
		XMLParser.appendDoubleArrayWithTags( buf, probs, "probs" );
		XMLParser.appendBooleanWithTags( buf, isTrained, "isTrained" );
		//add our own tag
		XMLParser.addTags( buf, "homogeneousMarkovModel" );
		return buf;
	}

	public String getInstanceName() {
		return "Homogeneous Markov model of order 0";
	}

	public double getLogPriorTerm() throws Exception {
		//we use ML-estimation, hence no prior term
		return 0;
	}

	public NumericalResultSet getNumericalCharacteristics() throws Exception {
		//we do not have much to tell here
		return new NumericalResultSet(new NumericalResult("Number of parameters","The number of parameters this model uses",probs.length));
	}

	public double getProbFor( Sequence sequence, int startpos, int endpos ) throws NotTrainedException, Exception {
		double seqProb = 1.0;
		//compute the probability of the sequence between startpos and endpos (inclusive)
		//as product of the single symbol probabilities
		for(int i=startpos;i<=endpos;i++){
			//directly access the array by the numerical representation of the symbols
			seqProb *= probs[sequence.discreteVal( i )];
		}
		return seqProb;
	}

	public boolean isTrained() {
		return isTrained;
	}

	public void train( Sample data, double[] weights ) throws Exception {
		//reset the parameter array
		Arrays.fill( probs, 0.0 );
		//default sequence weight
		double w = 1;
		//for each sequence in the data set
		for(int i=0;i<data.getNumberOfElements();i++){
			//retrieve sequence
			Sequence seq = data.getElementAt( i );
			//if we do have any weights, use them
			if(weights != null){
				w = weights[i]
			}
			//for each position in the sequence
			for(int j=0;j<seq.getLength();j++){
				//count symbols, weighted by weights
				probs[ seq.discreteVal( j ) ] += w;
			}
		}
		//compute normalization
		double norm = 0.0;
		for(int i=0;i<probs.length;i++){
			norm += probs[i];
		}
		//normalize probs to obtain proper probabilities
		for(int i=0;i<probs.length;i++){
			probs[i] /= norm;
		}
		//now the model is trained
		isTrained = true;
	}

}