2

I already have a CRF trained model that I have trained using SimpleTagger.

        SimpleTagger.main(new String[] {
                "--train", "true",
                "--model-file", "/Desktop/crfmodel",
                "--threads",  "8",
                "--training-proportion", "0.8",
                "--weights", "dense",
                "--test", "lab",
//                "--orders", "2",
                "/Desktop/annotations.txt"
        });

I am planning to load this model and use it for tagging. I am using this code.

    public static void main(String[] args) throws Exception {

        //DOCS http://mallet.cs.umass.edu/classifier-devel.php

        Instance instance = getMyInstance();

        Classifier classifier = loadClassifier(Paths.get("/Desktop/crfmodel").toFile());

        Labeling labeling = classifier.classify(instance).getLabeling();
        Label l = labeling.getBestLabel();
        System.out.print(instance);
        System.out.println(l);
    }


    private static Classifier loadClassifier(File serializedFile)
            throws FileNotFoundException, IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream (new FileInputStream(serializedFile));
        Classifier crf = (Classifier) ois.readObject();
        ois.close();

        return crf;
    }

When I try to do the above I get the following error

Exception in thread "main" java.lang.ClassCastException: cc.mallet.fst.CRF cannot be cast to cc.mallet.classify.Classifier
    at TagClassifier.loadClassifier(TagClassifier.java:77)
    at TagClassifier.main(TagClassifier.java:64)

The error is happening in line

Classifier crf = (Classifier) ois.readObject();

May I know why this is happening. Also, if there is a correct documented way to label an input using a trained model, can you please share any links/documentation? Thank you very much in advance!!!

Adithya Puram
  • 303
  • 2
  • 6
  • 23

2 Answers2

2

I think I figured it out by looking at SimpleTagger code.

        crfModel = loadClassifier(Paths.get("/Desktop/crfmodel").toFile());
        pipe = crfModel.getInputPipe();
        pipe.setTargetProcessing(false);
        String formatted = getFormattedQuery(q);

        Instance instance = pipe.pipe(new Instance(formatted, null, null, null));
        Sequence sequence = (Sequence) instance.getData();
        Sequence[] tags = tag(sequence, 3);
    private static Sequence[] tag(Sequence input, int bestK) {
        Sequence[] answers;
        if (bestK == 1) {
            answers = new Sequence[1];
            answers[0] = crfModel.transduce(input);
        } else {
            MaxLatticeDefault lattice = new MaxLatticeDefault(crfModel, input, null);
            answers = lattice.bestOutputSequences(bestK).toArray(new Sequence[0]);
        }
        return answers;
    }
Adithya Puram
  • 303
  • 2
  • 6
  • 23
0

They're different things, so you can't cast one to the other. A CRF infers classes for each element in a sequence, so its output is an array of labels. A classifier takes one input and returns one label.

David Mimno
  • 1,836
  • 7
  • 7
  • Thanks David Mimno, is there an example/class you can point me to, that can infer sequence of each element in an instance. Also is it possible to get the percentage or probability of how certain these predictions are? – Adithya Puram Apr 07 '20 at 22:27