Link to home
Start Free TrialLog in
Avatar of willie108
willie108

asked on

rewriting a method

Hello. I have code that includes the following:

private static AbstractClassifier getModel(String model) {
        // build test model
        AbstractClassifier naiveBayes = new NaiveBayes(); // new
instance of naiveBayes
        if ("naiveBayes".equalsIgnoreCase(model)) {
            naiveBayes = new NaiveBayes(); // new instance of naiveBayes
        } else if ("naiveBayesMultinomial".equalsIgnoreCase(model)) {
            naiveBayes = new NaiveBayesMultinomial(); // new instance
of naiveBayes
        } else if ("naiveBayesUpdateable".equalsIgnoreCase(model)) {
            naiveBayes = new NaiveBayesUpdateable(); // new instance
of naiveBayes
        } else if ("naiveBayesMultinomialUpdateable".equalsIgnoreCase(model)) {
            naiveBayes = new NaiveBayesMultinomialUpdateable(); // new
instance of naiveBayes
        }
        return naiveBayes;
    }

Open in new window


However there are many other "models" I want to include and whose names are specified in a table. They are listed here:
http://weka.sourceforge.net/doc/overview-summary.html

I want to use a method called getModel(model) to access them.
But I would have to write a getModel for each of them.

With regard to the code:

private static AbstractClassifier getModel(String model) {
        // build test model
        AbstractClassifier naiveBayes = new NaiveBayes(); // new
instance of naiveBayes
        if ("naiveBayes".equalsIgnoreCase(model)) {
            naiveBayes = new NaiveBayes(); // new instance of naiveBayes
        } else if ("naiveBayesMultinomial".equalsIgnoreCase(model)) {
            naiveBayes = new NaiveBayesMultinomial(); // new instance
of naiveBayes
        } else if ("naiveBayesUpdateable".equalsIgnoreCase(model)) {
            naiveBayes = new NaiveBayesUpdateable(); // new instance
of naiveBayes
        } else if ("naiveBayesMultinomialUpdateable".equalsIgnoreCase(model)) {
            naiveBayes = new NaiveBayesMultinomialUpdateable(); // new
instance of naiveBayes
        }
        return naiveBayes;
    }



 I was looking for some way to not have to write one of these for each type of
model (i.e. all of the subpackages of    weka.classifiers.functions. ,
  weka.classifiers.lazy. ,    weka.classifiers.meta. ,
weka.classifiers.misc. ,    weka.classifiers.rules. ,
weka.classifiers.trees. )

But to be able to use them like this
  Classifier classifier = getModel(model);

        inputMappedClassifier = new InputMappedClassifier();
        inputMappedClassifier.setClassifier(classifier);
        inputMappedClassifier.setSuppressMappingReport(true);
        inputMappedClassifier.buildClassifier(dataTrain); // build classifier

I think there are many many models in Weka and I would like to avoid
having to specify each of them if possible.

I found out that
If the String "model" is a fully qualified name (e.g.
"weka.classifiers.bayes.NaiveBayes") then you can just go:

Classifier classifier = Class.forName(model).newInstance();
 
Can someone tell me how I could implement this? I would use the fully qualified name but I don't know how to modify the definition of getModel and I am not sure what other changes to make.

Thank you.
Avatar of mccarl
mccarl
Flag of Australia image

Firstly, in your original method, I'm not even sure what AbstractClassifier is. I don't see it in the weka javadoc's. However, changing that to just Classifier, the code to implement your Class.forName() solution is quite easy...
    private static Classifier getModel(String model) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return (Classifier) Class.forName(model).newInstance();
    }

Open in new window

(Note: you may want to handle error conditions differently, but that is up to you. Handle them in this method and you may not need to throw any exceptions, or in the calling method by catching the appropriate exceptions)
Avatar of willie108
willie108

ASKER

Hi. Thank you. I have this statement in my code:
import weka.classifiers.AbstractClassifier;

I am not really much of a programmer so I am not sure about it.

Can I replace
    private static AbstractClassifier getModel(String model) {
        // build test model
        AbstractClassifier naiveBayes = new NaiveBayes(); // new instance of naiveBayes
        if ("naiveBayes".equalsIgnoreCase(model)) {
            naiveBayes = new NaiveBayes(); // new instance of naiveBayes
        } else if ("naiveBayesMultinomial".equalsIgnoreCase(model)) {
            naiveBayes = new NaiveBayesMultinomial(); // new instance of naiveBayes
        } else if ("naiveBayesUpdateable".equalsIgnoreCase(model)) {
            naiveBayes = new NaiveBayesUpdateable(); // new instance of naiveBayes
        } else if ("naiveBayesMultinomialUpdateable".equalsIgnoreCase(model)) {
            naiveBayes = new NaiveBayesMultinomialUpdateable(); // new instance of naiveBayes
        }
        return naiveBayes;
    }

Open in new window


by

    private static Classifier getModel(String model) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return (Classifier) Class.forName(model).newInstance();
    }

Open in new window


and then use this

Classifier classifier = Class.forName(model).newInstance();

Open in new window


to call the method?

Thanks.
ASKER CERTIFIED SOLUTION
Avatar of mccarl
mccarl
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi Thanks very much.

So I should replace:

    private static AbstractClassifier getModel(String model) {
        // build test model
        AbstractClassifier naiveBayes = new NaiveBayes(); // new instance of naiveBayes
        if ("naiveBayes".equalsIgnoreCase(model)) {
            naiveBayes = new NaiveBayes(); // new instance of naiveBayes
        } else if ("naiveBayesMultinomial".equalsIgnoreCase(model)) {
            naiveBayes = new NaiveBayesMultinomial(); // new instance of naiveBayes
        } else if ("naiveBayesUpdateable".equalsIgnoreCase(model)) {
            naiveBayes = new NaiveBayesUpdateable(); // new instance of naiveBayes
        } else if ("naiveBayesMultinomialUpdateable".equalsIgnoreCase(model)) {
            naiveBayes = new NaiveBayesMultinomialUpdateable(); // new instance of naiveBayes
        }
        return naiveBayes;
    }

Open in new window


with
    private static Classifier getModel(String model) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return (Classifier) Class.forName(model).newInstance();
    }

Open in new window


and then do something like this:
Classifier classifier = getModel("weka.classifiers.bayes.NaiveBayes");

Open in new window

(with appropriate model)?
Yes!
OK. Thanks!!!
Excellent. Thanks.