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
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()
);
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
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<>();
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!
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);