blob: 2bad4e0ed5bfed6190e3c73a868cd269f677cf06 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.opennlp.ml.maxent;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import org.apache.opennlp.ml.model.Context;
import org.apache.opennlp.ml.model.AbstractModel;
import org.apache.opennlp.ml.model.EvalParameters;
import org.apache.opennlp.ml.model.Prior;
import org.apache.opennlp.ml.model.UniformPrior;
/**
* A maximum entropy model which has been trained using the Generalized
* Iterative Scaling procedure (implemented in GIS.java).
*/
public final class GISModel extends AbstractModel {
/**
* Creates a new model with the specified parameters, outcome names, and
* predicate/feature labels.
*
* @param params
* The parameters of the model.
* @param predLabels
* The names of the predicates used in this model.
* @param outcomeNames
* The names of the outcomes this model predicts.
* @param correctionConstant
* The maximum number of active features which occur in an event.
* @param correctionParam
* The parameter associated with the correction feature.
*/
public GISModel(Context[] params, String[] predLabels, String[] outcomeNames,
int correctionConstant, double correctionParam) {
this(params, predLabels, outcomeNames, correctionConstant, correctionParam,
new UniformPrior());
}
/**
* Creates a new model with the specified parameters, outcome names, and
* predicate/feature labels.
*
* @param params
* The parameters of the model.
* @param predLabels
* The names of the predicates used in this model.
* @param outcomeNames
* The names of the outcomes this model predicts.
* @param correctionConstant
* The maximum number of active features which occur in an event.
* @param correctionParam
* The parameter associated with the correction feature.
* @param prior
* The prior to be used with this model.
*/
public GISModel(Context[] params, String[] predLabels, String[] outcomeNames,
int correctionConstant, double correctionParam, Prior prior) {
super(params, predLabels, outcomeNames, correctionConstant, correctionParam);
this.prior = prior;
prior.setLabels(outcomeNames, predLabels);
modelType = ModelType.Maxent;
}
/**
* Use this model to evaluate a context and return an array of the likelihood
* of each outcome given that context.
*
* @param context
* The names of the predicates which have been observed at the
* present decision point.
* @return The normalized probabilities for the outcomes given the context.
* The indexes of the double[] are the outcome ids, and the actual
* string representation of the outcomes can be obtained from the
* method getOutcome(int i).
*/
public final double[] eval(String[] context) {
return (eval(context, new double[evalParams.getNumOutcomes()]));
}
public final double[] eval(String[] context, float[] values) {
return (eval(context, values, new double[evalParams.getNumOutcomes()]));
}
public final double[] eval(String[] context, double[] outsums) {
return eval(context, null, outsums);
}
/**
* Use this model to evaluate a context and return an array of the likelihood
* of each outcome given that context.
*
* @param context
* The names of the predicates which have been observed at the
* present decision point.
* @param outsums
* This is where the distribution is stored.
* @return The normalized probabilities for the outcomes given the context.
* The indexes of the double[] are the outcome ids, and the actual
* string representation of the outcomes can be obtained from the
* method getOutcome(int i).
*/
public final double[] eval(String[] context, float[] values, double[] outsums) {
int[] scontexts = new int[context.length];
for (int i = 0; i < context.length; i++) {
Integer ci = pmap.get(context[i]);
scontexts[i] = ci == null ? -1 : ci;
}
prior.logPrior(outsums, scontexts, values);
return GISModel.eval(scontexts, values, outsums, evalParams);
}
/**
* Use this model to evaluate a context and return an array of the likelihood
* of each outcome given the specified context and the specified parameters.
*
* @param context
* The integer values of the predicates which have been observed at
* the present decision point.
* @param prior
* The prior distribution for the specified context.
* @param model
* The set of parametes used in this computation.
* @return The normalized probabilities for the outcomes given the context.
* The indexes of the double[] are the outcome ids, and the actual
* string representation of the outcomes can be obtained from the
* method getOutcome(int i).
*/
public static double[] eval(int[] context, double[] prior,
EvalParameters model) {
return eval(context, null, prior, model);
}
/**
* Use this model to evaluate a context and return an array of the likelihood
* of each outcome given the specified context and the specified parameters.
*
* @param context
* The integer values of the predicates which have been observed at
* the present decision point.
* @param values
* The values for each of the parameters.
* @param prior
* The prior distribution for the specified context.
* @param model
* The set of parametes used in this computation.
* @return The normalized probabilities for the outcomes given the context.
* The indexes of the double[] are the outcome ids, and the actual
* string representation of the outcomes can be obtained from the
* method getOutcome(int i).
*/
public static double[] eval(int[] context, float[] values, double[] prior,
EvalParameters model) {
Context[] params = model.getParams();
int numfeats[] = new int[model.getNumOutcomes()];
int[] activeOutcomes;
double[] activeParameters;
double value = 1;
for (int ci = 0; ci < context.length; ci++) {
if (context[ci] >= 0) {
Context predParams = params[context[ci]];
activeOutcomes = predParams.getOutcomes();
activeParameters = predParams.getParameters();
if (values != null) {
value = values[ci];
}
for (int ai = 0; ai < activeOutcomes.length; ai++) {
int oid = activeOutcomes[ai];
numfeats[oid]++;
prior[oid] += activeParameters[ai] * value;
}
}
}
double normal = 0.0;
for (int oid = 0; oid < model.getNumOutcomes(); oid++) {
if (model.getCorrectionParam() != 0) {
prior[oid] = Math
.exp(prior[oid]
* model.getConstantInverse()
+ ((1.0 - ((double) numfeats[oid] / model
.getCorrectionConstant())) * model.getCorrectionParam()));
} else {
prior[oid] = Math.exp(prior[oid] * model.getConstantInverse());
}
normal += prior[oid];
}
for (int oid = 0; oid < model.getNumOutcomes(); oid++) {
prior[oid] /= normal;
}
return prior;
}
public static void main(String[] args) throws java.io.IOException {
if (args.length == 0) {
System.err.println("Usage: GISModel modelname < contexts");
System.exit(1);
}
AbstractModel m = new org.apache.opennlp.ml.maxent.io.SuffixSensitiveGISModelReader(
new File(args[0])).getModel();
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
DecimalFormat df = new java.text.DecimalFormat(".###");
for (String line = in.readLine(); line != null; line = in.readLine()) {
String[] context = line.split(" ");
double[] dist = m.eval(context);
for (int oi = 0; oi < dist.length; oi++) {
System.out.print("[" + m.getOutcome(oi) + " " + df.format(dist[oi])
+ "] ");
}
System.out.println();
}
}
}