Meka api i want to integrate Meka in Java Eclipse - java

public class Evaluate {
public static void main(String args[]) throws Exception{
//load datasets
DataSource source = new DataSource("F:/data/solar_flare.arff");
Instances dataset = source.getDataSet();
BufferedReader reader = new BufferedReader(new FileReader("F:/data/solar_flare.arff"));
Instances training = new Instances(reader);
reader = new BufferedReader(new FileReader("F:/data/solar_flare.arff"));
Instances testing = new Instances(reader);
J48 jjjj = new J48();
MultilabelClassifier PS = new PS();
PS.setClassifier(jjjj);
PS.setOptions(Utils.splitOptions("-threshold PCut1 -verbosity 3"));
PS.buildClassifier(training);
Evaluation ecal = new Evaluation(training);
ecal.evaluateModel(PS, testing);
dataset.setClassIndex(dataset.numAttributes()-1);
J48 tree = new J48();
tree.buildClassifier(dataset);
Evaluation eval = new Evaluation(dataset);
Random rand = new Random(1);
int folds = 10;
DataSource source1 = new DataSource("F:/data/solar_flare.arff");
Instances testDataset = source1.getDataSet();
testDataset.setClassIndex(testDataset.numAttributes()-1);
eval.crossValidateModel(tree, testDataset, folds, rand);
System.out.println(eval.toMatrixString("=== Confusion Matrix ===\n"));
}
}
This my Code its give error back
This is error
"Exception in thread "main" java.lang.NoSuchMethodError:
weka.core.Attribute.(Ljava/lang/String;Ljava/util/List;)V at
meka.core.PSUtils.PSTransformation(PSUtils.java:416) at
meka.classifiers.multilabel.PS.buildClassifier(PS.java:225)" at
Evaluate.main(Evaluate.java:57)

This is a typical error when you are using a library with a version that does not correspond to what you expect. You have to make sure the weka.core.Attribute exists in your version with the specified method.

Related

Exception while compiling scala code from Java program

I have the following code to compile scala code at runtime in a Java program
Settings s = new Settings();
Global g = new Global(s);
Global.Run run = g.new Run();
List<String> files = new LinkedList<>();
files.add("src/main/java/scala/rules/ScalaRuleBasedStrategy.scala");
run.compile(JavaConverters.asScalaBufferConverter(files)
.asScala().toList());
But I am getting this error:
Exception in thread "main" java.lang.NoSuchMethodError: scala.tools.nsc.Global$gen$.mkBlock(Lscala/collection/immutable/List;)Lscala/reflect/internal/Trees$Tree;
at scala.tools.nsc.ast.parser.TreeBuilder.makeBlock(TreeBuilder.scala:110)
at scala.tools.nsc.ast.parser.Parsers$Parser.block(Parsers.scala:1689)
Try
Settings s = new Settings();
MutableSettings.BooleanSetting usejavacp = s.usejavacp(); // added
usejavacp.value_$eq(true); // added
Global g = new Global(s);
Global.Run run = g.new Run();
List<String> files = new LinkedList<>();
files.add("src/main/java/scala/rules/ScalaRuleBasedStrategy.scala");
run.compile(
JavaConverters.asScalaBufferConverter(files)
.asScala().toList()
);

Unable to identify error in Lucene MoreLikeThis

I need to use Lucene MoreLikeThis to find similar documents given a paragraph of text. I am new to Lucene and followed the code here
I have already indexed the documents at the directory - "C:\Users\lucene_index_files\v2"
I am using "They are computer engineers and they like to develop their own tools. The program in languages like Java, CPP." as the document to which I want to find similar documents.
public class LuceneSearcher2 {
public static void main(String[] args) throws IOException {
LuceneSearcher2 m = new LuceneSearcher2();
System.out.println("1");
m.start();
System.out.println("2");
//m.writerEntries();
m.findSilimar("They are computer engineers and they like to develop their own tools. The program in languages like Java, CPP.");
System.out.println("3");
}
private Directory indexDir;
private StandardAnalyzer analyzer;
private IndexWriterConfig config;
public void start() throws IOException{
//analyzer = new StandardAnalyzer(Version.LUCENE_42);
//config = new IndexWriterConfig(Version.LUCENE_42, analyzer);
analyzer = new StandardAnalyzer();
config = new IndexWriterConfig(analyzer);
config.setOpenMode(OpenMode.CREATE_OR_APPEND);
indexDir = new RAMDirectory(); //don't write on disk
//https://stackoverflow.com/questions/36542551/lucene-in-java-method-not-found?rq=1
indexDir = FSDirectory.open(FileSystems.getDefault().getPath("C:\\Users\\lucene_index_files\\v2")); //write on disk
//System.out.println(indexDir);
}
private void findSilimar(String searchForSimilar) throws IOException {
IndexReader reader = DirectoryReader.open(indexDir);
IndexSearcher indexSearcher = new IndexSearcher(reader);
System.out.println("2a");
MoreLikeThis mlt = new MoreLikeThis(reader);
mlt.setMinTermFreq(0);
mlt.setMinDocFreq(0);
mlt.setFieldNames(new String[]{"title", "content"});
mlt.setAnalyzer(analyzer);
System.out.println("2b");
StringReader sReader = new StringReader(searchForSimilar);
//Query query = mlt.like(sReader, null);
//Throws error - The method like(String, Reader...) in the type MoreLikeThis is not applicable for the arguments (StringReader, null)
Query query = mlt.like("computer");
System.out.println("2c");
System.out.println(query.toString());
TopDocs topDocs = indexSearcher.search(query,10);
for ( ScoreDoc scoreDoc : topDocs.scoreDocs ) {
Document aSimilar = indexSearcher.doc( scoreDoc.doc );
String similarTitle = aSimilar.get("title");
String similarContent = aSimilar.get("content");
System.out.println("====similar finded====");
System.out.println("title: "+ similarTitle);
System.out.println("content: "+ similarContent);
}
System.out.println("2d");
}}
I am unsure as to what is causing the system to not generate an output/
What is your output ? I am assuming your not finding similar documents. The reason could be that the query you are creating is empty.
First of all to run your code in a meaningful way this line
Query query = mlt.like(sReader, null);
needs a String[] of field names as the argument, so it should work like this
Query query = mlt.like(sReader, new String[]{"title", "content"});
Now, in order to use MoreLikeThis in Lucene, your stored Fields have to have the set the option to store term vectors "setStoreTermVectors(true);" true when creating fields, for instance like this:
FieldType fieldType = new FieldType();
fieldType.setStored(true);
fieldType.setStoreTermVectors(true);
fieldType.setTokenized(true);
Field contentField = new Field("contents", this.getBlurb(), fieldType);
doc.add(contentField);
Leaving this out could result in an empty query string and consequently no results for the query

converting Instance type ArrayList to Instances object

I have implemented an ArrayList which it's type is Instance, and by writing some code, I have read the positive instances and negative instances from a file and according to their class lable, add them to the related ArrayList. Now I want to know how can I convert the type of this ArrayList to Instances type and then be able to use some methods and classes of Weka API in order to resample it and create a classifier?
below is a bit of my code.
public class MyDecision {
double m=0.1;
double d=0.1;
private ArrayList<Instance> positiveInstances;
private ArrayList<Instance> negativeInstances;
Filter filter;
private double[] classlabels;
public MyDecision() throws Exception{
positiveInstances = new ArrayList<Instance>();
negativeInstances = new ArrayList<Instance>();
br = new BufferedReader(new FileReader("D:\\workspace\\MyDecision\\littleMyChurn\\Churn.arff"));
ArffSaver saverTets = new ArffSaver();
ArffSaver saverTraining = new ArffSaver();
Instances trainData = new Instances(br);
// Make the last attribute be the class
trainData.setClassIndex(trainData.numAttributes() - 1);
br.close();
classlabels=trainData.attributeToDoubleArray(trainData.numAttributes()-1);
for(int i=0;i<=trainData.numInstances()-1;i++){
if(classlabels[i]==0){
positiveInstances.add(trainData.instance(i));
}
else if(classlabels[i]==1){
negativeInstances.add(trainData.instance(i));
}
}
Resample resample = new Resample();
}
}
Try to create your Arraylist so:
ArrayList<Instance> positiveInstances = new ArrayList<>();

Evaluate the class of a sample using WEKA

I have created a model in Weka using the SMO algorithm. I am trying to evaluate a test sample using the mentioned model to classify it in my two-class problem. I am a bit confused on how to evaluate the sample using Weka Smo code. I have built an empty arff file which contains only the meta-data of the file. I calculate the sample features and I add the vector in arff file. I have created the following function Evaluate in order to evaluate a sample. File template.arff is the template which contains the meta-data of a arff file and models/smo my model.
public static void Evaluate(ArrayList<Float> temp) throws Exception {
temp.add(Float.parseFloat("1"));
System.out.println(temp.size());
double dt[] = new double[temp.size()];
for (int index = 0; index < temp.size(); index++) {
dt[index] = temp.get(index);
}
double data[][] = new double[1][];
data[0] = dt;
weka.classifiers.Classifier c = loadModel(new File("models/"), "/smo"); // loads smo model
File tmp = new File("template.arff"); //loads data template
Instances dataset = new weka.core.converters.ConverterUtils.DataSource(tmp.getAbsolutePath()).getDataSet();
int numInstances = data.length;
for (int inst = 0; inst < numInstances; inst++) {
dataset.add(new Instance(1.0, data[inst]));
}
dataset.setClassIndex(dataset.numAttributes() - 1);
Evaluation eval = new Evaluation(dataset);
//returned evaluated index
double a = eval.evaluateModelOnceAndRecordPrediction(c, dataset.instance(0));
double arr[] = c.distributionForInstance(dataset.instance(0));
System.out.println(" Confidence Scores");
for (int idx = 0; idx < arr.length; idx++) {
System.out.print(arr[idx] + " ");
}
System.out.println();
}
I am not sure if I am right here. I create the sample file. Afterwards I am loading my model. I am wandering if my code is what I need in order to evaluate the class of sample temp. If this code is ok, how can I extract the confidence score and not the binary decision about the class? The structure of template.arff file is:
#relation Dataset
#attribute Attribute0 numeric
#attribute Attribute1 numeric
#attribute Attribute2 numeric
...
#ATTRIBUTE class {1, 2}
#data
Moreover loadModel function is the following:
public static SMO loadModel(File path, String name) throws Exception {
SMO classifier;
FileInputStream fis = new FileInputStream(path + name + ".model");
ObjectInputStream ois = new ObjectInputStream(fis);
classifier = (SMO) ois.readObject();
ois.close();
return classifier;
}
I found this post here which suggest to locate the SMO.java file and change the following line smo.buildClassifier(train, cl1, cl2, true, -1, -1); // from false to true.
However it seems when I did so, I got the same binary output.
My training function:
public void weka_train(File input, String[] options) throws Exception {
long start = System.nanoTime();
File tmp = new File("data.arff");
TwitterTrendSetters obj = new TwitterTrendSetters();
Instances data = new weka.core.converters.ConverterUtils.DataSource(
tmp.getAbsolutePath()).getDataSet();
data.setClassIndex(data.numAttributes() - 1);
Classifier c = null;
String ctype = null;
boolean newmodel = false;
ctype = "SMO";
c = new SMO();
for (int i = 0; i < options.length; i++) {
System.out.print(options[i]);
}
c.setOptions(options);
c.buildClassifier(data);
newmodel = true;
if (newmodel) {
obj.saveModel(c, ctype, new File("models"));
}
}
I have some suggestions but I have no idea whether they will work. Let me know if this works for you.
First use SMO not just the parent object Classifier class. I created a new method loadModelSMO as an example of this.
SMO Class
public static SMO loadModelSMO(File path, String name) throws Exception {
SMO classifier;
FileInputStream fis = new FileInputStream(path + name + ".model");
ObjectInputStream ois = new ObjectInputStream(fis);
classifier = (SMO) ois.readObject();
ois.close();
return classifier;
}
and then
SMO c = loadModelSMO(new File("models/"), "/smo");
...
I found a article that might help you out from the mailing list subject titled
I used SMO with logistic regression but I always get a confidence of 1.0
It suggest to set use the -M to fit your logistics model which can be used through the method
setOptions(java.lang.String[] options)
Also maybe you need to set your build logistics model to true
Confidence score in SMO
c.setBuildLogisticModels(true);
Let me know if this helped at all.
Basically you should try to use the option "-M" for SMO to fit logistic models, in training process. Check the solution proposed here. It should work!

unable to find class label in arff file

I have followed example code on weka websites for example but i still keep on getting an error of unable to find the class label
weka.core.WekaException: weka.classifiers.bayes.NaiveBayesMultinomialUpdateable: Not enough training instances with class labels (required: 1, provided: 0)!
I have tried this file with the weka explorer and it works fine.
ArffLoader loader = new ArffLoader();
loader.setFile(new File(""));//file is valid
Instances structure = loader.getStructure();
structure.setClassIndex(structure.numAttributes() - 1);
// train NaiveBayes
NaiveBayesMultinomialUpdateable n = new NaiveBayesMultinomialUpdateable();
FilteredClassifier f = new FilteredClassifier();
StringToWordVector s = new StringToWordVector();
f.setFilter(s);
f.setClassifier(n);
f.buildClassifier(structure);
Instance current;
while ((current = loader.getNextInstance(structure)) != null)
n.updateClassifier(current);
// output generated model
System.out.println(n);
The problem lies in where the class index is at position 0
ArffLoader loader = new ArffLoader();
loader.setFile(new File(""));//file is valid
Instances structure = loader.getStructure();
structure.setClassIndex(0);
// train NaiveBayes
NaiveBayesMultinomialUpdateable n = new NaiveBayesMultinomialUpdateable();
FilteredClassifier f = new FilteredClassifier();
StringToWordVector s = new StringToWordVector();
f.setFilter(s);
f.setClassifier(n);
f.buildClassifier(structure);
Instance current;
while ((current = loader.getNextInstance(structure)) != null)
n.updateClassifier(current);
// output generated model
System.out.println(n);

Categories