All Downloads are FREE. Search and download functionalities are using the official Maven repository.

marytts.machinelearning.SoP Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2010 DFKI GmbH.
 * All Rights Reserved.  Use is subject to license terms.
 *
 * This file is part of MARY TTS.
 *
 * MARY TTS is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, version 3 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see .
 *
 */

package marytts.machinelearning;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.PrintWriter;
import java.io.StringReader;
import java.util.Scanner;

import marytts.features.FeatureDefinition;
import marytts.unitselection.select.Target;

/**
 * Contains the coefficients and factors of an equation of the form: if interceptTterm = TRUE solution = coeffs[0] +
 * coeffs[1]*factors[0] + coeffs[2]*factors[1] + ... + coeffs[n]*factors[n-1] if interceptterm = FALSE solution =
 * coeffs[0]*factors[0] + coeffs[1]*factors[1] + ... + coeffs[n]*factors[n]
 * 
 * @author marcela
 * 
 */
public class SoP {

	private double coeffs[]; // coefficients of the multiple linear equation
	private String factors[]; // variables in the multiple linear
	private int factorsIndex[]; // indices in featureDefinition
	boolean interceptTerm;
	double correlation;
	double rmse;
	double solution;
	FeatureDefinition featureDefinition = null;

	public void setCorrelation(double val) {
		correlation = val;
	}

	public void setRMSE(double val) {
		rmse = val;
	}

	public double[] getCoeffs() {
		return coeffs;
	}

	public double getCorrelation() {
		return correlation;
	}

	public double getRMSE() {
		return rmse;
	}

	public int[] getFactorsIndex() {
		return factorsIndex;
	}

	public SoP() {
	}

	/**
	 * Build a new empty sop with the given feature definition.
	 * 
	 * @param featDef
	 *            featDef
	 */
	public SoP(FeatureDefinition featDef) {
		this.featureDefinition = featDef;
	}

	/***
	 * if b0=true then the number of selected factors 0 numCoeffs-1 (there is one coeff more) if b0=false then the number of
	 * selected factor is the same as the number of coeffs When setting the factors, it checks to which indexes correspond
	 * according to the featureDefinition.
	 * 
	 * @param coeffsVal
	 *            coeffsVal
	 * @param selectedFactorsIndex
	 *            selectedFactorsIndex
	 * @param allFactorsList
	 *            allFactorsList
	 * @param b0
	 *            b0
	 * @throws Exception
	 *             Exception
	 */
	public void setCoeffsAndFactors(double coeffsVal[], int selectedFactorsIndex[], String allFactorsList[], boolean b0)
			throws Exception {
		if (featureDefinition == null) {
			throw new Exception("FeatureDefinition not defined in SoP");
		} else {
			interceptTerm = b0;
			int numFactors = selectedFactorsIndex.length;
			if (interceptTerm) {
				// there is one coefficient more than factors
				coeffs = new double[numFactors + 1];
				factors = new String[numFactors + 1];
				factorsIndex = new int[numFactors + 1];
				coeffs[0] = coeffsVal[0];
				factors[0] = "_"; // if there is intercept term then the first factor is empty here indicated with _
				factorsIndex[0] = -1;
				for (int i = 1; i < (numFactors + 1); i++) {
					coeffs[i] = coeffsVal[i];
					factors[i] = allFactorsList[selectedFactorsIndex[i - 1]];
					factorsIndex[i] = featureDefinition.getFeatureIndex(factors[i]);
				}
			} else {
				coeffs = new double[numFactors];
				factors = new String[numFactors];
				factorsIndex = new int[numFactors];
				for (int i = 0; i < numFactors; i++) {
					coeffs[i] = coeffsVal[i];
					factors[i] = allFactorsList[selectedFactorsIndex[i]];
					factorsIndex[i] = featureDefinition.getFeatureIndex(factors[i]);
				}
			}
		}
	}

	// Need to add a SoP.load() method to load the coeffs and features from a file
	// this means that we need a sop file for each type... left, mid and righ f0
	// for duration ???
	// this function also set the featureDefinition for this model
	public void load(String sopFile) {
		// System.out.println("sopFileName: " + sopFile);
		String nextLine;
		String strContext = "";
		Scanner s = null;
		try {
			s = new Scanner(new BufferedReader(new FileReader(sopFile)));

			// The first part contains the feature definition
			while (s.hasNext()) {
				nextLine = s.nextLine();
				if (nextLine.trim().equals(""))
					break;
				else
					strContext += nextLine + "\n";
			}
			// the featureDefinition is the same for vowel, consonant and Pause
			featureDefinition = new FeatureDefinition(new BufferedReader(new StringReader(strContext)), false);

			// next line should contain the coeffs and linguistic features
			// vowel line
			if (s.hasNext()) {
				nextLine = s.nextLine();
				// System.out.println("line vowel = " + nextLine);
				setCoeffsAndFactors(nextLine);
				// printCoefficients();
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (s != null)
				s.close();
		}

	}

	public void setCoeffsAndFactors(String line) {

		// features definition should be already set

		String word[] = line.split(" ");
		int j = 0;
		coeffs = new double[word.length / 2];
		factors = new String[word.length / 2];
		factorsIndex = new int[word.length / 2];
		interceptTerm = false;
		for (int i = 0; i < word.length; i++) {
			// System.out.println("w=" + word[i]);
			coeffs[j] = Double.parseDouble(word[i]);
			factors[j] = word[i + 1];
			if (word[i + 1].contentEquals("_")) {
				interceptTerm = true;
				factorsIndex[j] = -1;
			} else
				factorsIndex[j] = featureDefinition.getFeatureIndex(factors[j]);
			i++;
			j++;
		}
	}

	// this we will not need after using acoustic modeller
	public SoP(String line, FeatureDefinition feaDef) {

		this.featureDefinition = feaDef;

		String word[] = line.split(" ");
		int j = 0;
		coeffs = new double[word.length / 2];
		factors = new String[word.length / 2];
		factorsIndex = new int[word.length / 2];
		interceptTerm = false;
		for (int i = 0; i < word.length; i++) {
			// System.out.println("w=" + word[i]);
			coeffs[j] = Double.parseDouble(word[i]);
			factors[j] = word[i + 1];
			if (word[i + 1].contentEquals("_")) {
				interceptTerm = true;
				factorsIndex[j] = -1;
			} else
				factorsIndex[j] = featureDefinition.getFeatureIndex(factors[j]);
			i++;
			j++;
		}
	}

	public FeatureDefinition getFeatureDefinition() {
		return featureDefinition;
	}

	/**
	 * Solve the linear equation given the features (factors) in t and coeffs and factors in the SoP object * if interceptTterm =
	 * TRUE solution = coeffs[0] + coeffs[1]*factors[0] + coeffs[2]*factors[1] + ... + coeffs[n]*factors[n-1] if interceptterm =
	 * FALSE solution = coeffs[0]*factors[0] + coeffs[1]*factors[1] + ... + coeffs[n]*factors[n]
	 * 
	 * @param t
	 *            t
	 * @param feaDef
	 *            feaDef
	 * @param log
	 *            log
	 * @return solution
	 */
	public double solve(Target t, FeatureDefinition feaDef, boolean log) {
		solution = 0.0f;
		double lastPosSolution = 0.0;
		if (interceptTerm) {
			// the first factor is empty filled with "_" so it should not be used
			solution = coeffs[0];
			for (int i = 1; i < coeffs.length; i++) {
				solution = solution + (coeffs[i] * t.getFeatureVector().getByteFeature(factorsIndex[i]));
				if (solution > 0.0)
					lastPosSolution = solution;
				else
					System.out.println("WARNING: sop solution negative");
			}
		} else {
			for (int i = 0; i < coeffs.length; i++) {
				solution = solution + (coeffs[i] * t.getFeatureVector().getByteFeature(factorsIndex[i]));
				if (solution > 0.0)
					lastPosSolution = solution;
				else
					System.out.println("WARNING: sop solution negative");
			}
		}
		if (solution < 0.0)
			solution = lastPosSolution;

		if (log)
			return Math.exp(solution);
		else
			return solution;
	}

	public double solve(Target t, FeatureDefinition feaDef, boolean log, boolean debug) {
		solution = 0.0f;
		double lastPosSolution = 0.0;
		if (interceptTerm) {
			// the first factor is empty filled with "_" so it should not be used
			solution = coeffs[0];
			if (debug)
				System.out.format("   solution = %.3f (coeff[0])\n", coeffs[0]);
			for (int i = 1; i < coeffs.length; i++) {
				// check if the retrieved bytevalue is allowed for the kind of feature factor
				byte feaVal = t.getFeatureVector().getByteFeature(factorsIndex[i]);
				String feaValStr = t.getFeatureVector().getFeatureAsString(factorsIndex[i], feaDef);
				if (feaDef.hasFeatureValue(factorsIndex[i], feaValStr)) {
					if (debug)
						System.out.format("   %.3f + (%.3f * %d (%s) = ", solution, coeffs[i], feaVal, factors[i]);
					solution = solution + (coeffs[i] * feaVal);
					if (debug)
						System.out.format("%.3f  featureIndex=%d  feaValStr=%s \n", solution, factorsIndex[i], feaValStr);
				} else {
					System.out.format("WARNING: Feature value for %s = %s is not valid", coeffs[i], feaValStr);
				}
				if (solution > 0.0)
					lastPosSolution = solution;
			}
		} else {
			for (int i = 0; i < coeffs.length; i++)
				solution = solution + (coeffs[i] * t.getFeatureVector().getByteFeature(factorsIndex[i]));
			if (solution > 0.0)
				lastPosSolution = solution;

		}
		if (debug) {
			if (log)
				return Math.exp(lastPosSolution);
			else
				return lastPosSolution;
		} else {
			if (log)
				return Math.exp(solution);
			else
				return solution;
		}
	}

	public double interpret(Target t) {

		return solve(t, this.featureDefinition, false);

	}

	/***
	 * First line vowel coefficients plus factors, second line consonant coefficients plus factors
	 * 
	 * @param toSopFile
	 *            toSopFile
	 */
	public void saveSelectedFeatures(PrintWriter toSopFile) {
		for (int j = 0; j < coeffs.length; j++)
			toSopFile.print(coeffs[j] + " " + factors[j] + " ");
		toSopFile.println();
	}

	public void printCoefficients() {
		if (coeffs != null) {
			System.out.println("SoP coefficients (factor : factorIndex in FeatureDefinition)");
			for (int j = 0; j < coeffs.length; j++)
				System.out.format(" %.5f (%s : %d)\n", coeffs[j], factors[j], factorsIndex[j]);
		} else
			System.out.println("There is no coefficients to print (coeffs=null).");
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy