8

Ich trainierte und erstellte ein J48-Modell mit WEKA-GUI. Ich habe die Modelldatei auf meinem Computer gespeichert und möchte sie jetzt dazu verwenden, eine einzelne Instanz in meinem Java-Code zu klassifizieren. Ich möchte eine Vorhersage für das Attribut "Cluster" erhalten. Was ich tue, ist die folgende:Klassifizierung einzelner Instanzen in Weka

public void classify(double lat, double lon, double co) 
{    

// Create attributes to be used with classifiers 
        Attribute latitude = new Attribute("latitude"); 
        Attribute longitude = new Attribute("longitude"); 
        Attribute carbonmonoxide = new Attribute("co"); 

        // Create instances for each pollutant with attribute values latitude, longitude and pollutant itself 
        inst_co = new DenseInstance(4); 

        // Set instance's values for the attributes "latitude", "longitude", and "pollutant concentration" 
        inst_co.setValue(latitude, lat); 
        inst_co.setValue(longitude, lon); 
        inst_co.setValue(carbonmonoxide, co); 
        inst_co.setMissing(cluster); 


    Classifier cls_co = (Classifier) weka.core.SerializationHelper.read("/CO_J48Model.model");//load classifier from file 

        // Test the model 
     double result = cls_co.classifyInstance(inst_co); 
} 

aber ich erhalte eine IndexArrayOutofBoundsException auf der Linie inst_co.setValue(latitude, lat);. Ich konnte den Grund für diese Ausnahme nicht finden. Ich werde es begrüßen, wenn mir jemand in die richtige Richtung zeigen könnte.

Antwort

8

Sie müssen Ihr inst_co zu Ihrem Datensatz hinzufügen, ein Instances-Objekt. Der folgende Code sollte funktionieren.

import java.util.ArrayList; 

import weka.classifiers.Classifier; 
import weka.core.Attribute; 
import weka.core.DenseInstance; 
import weka.core.Instance; 
import weka.core.Instances; 

public class QuestionInstanceClassifiy { 

    public static void main(String[] args) { 
     QuestionInstanceClassifiy q = new QuestionInstanceClassifiy(); 
     double result = q.classify(1.0d, 1, 1); 
     System.out.println(result); 
    } 

    private Instance inst_co; 

    public double classify(double lat, double lon, double co) { 

     // Create attributes to be used with classifiers 
     // Test the model 
     double result = -1; 
     try { 

      ArrayList<Attribute> attributeList = new ArrayList<Attribute>(2); 

      Attribute latitude = new Attribute("latitude"); 
      Attribute longitude = new Attribute("longitude"); 
      Attribute carbonmonoxide = new Attribute("co"); 

      ArrayList<String> classVal = new ArrayList<String>(); 
      classVal.add("ClassA"); 
      classVal.add("ClassB"); 


      attributeList.add(latitude); 
      attributeList.add(longitude); 
      attributeList.add(carbonmonoxide); 
      attributeList.add(new Attribute("@@[email protected]@",classVal)); 

      Instances data = new Instances("TestInstances",attributeList,0); 


      // Create instances for each pollutant with attribute values latitude, 
      // longitude and pollutant itself 
      inst_co = new DenseInstance(data.numAttributes()); 
      data.add(inst_co); 

      // Set instance's values for the attributes "latitude", "longitude", and 
      // "pollutant concentration" 
      inst_co.setValue(latitude, lat); 
      inst_co.setValue(longitude, lon); 
      inst_co.setValue(carbonmonoxide, co); 
      // inst_co.setMissing(cluster); 

      // load classifier from file 
      Classifier cls_co = (Classifier) weka.core.SerializationHelper 
        .read("/CO_J48Model.model"); 

      result = cls_co.classifyInstance(inst_co); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     return result; 
    } 
} 

Sie erstellen Datenobjekt aus Instanzen. Fügen Sie diesen Daten Ihre Instanz hinzu. Danach können Sie Ihre Werte in Instance einstellen.

Instances data = new Instances("TestInstances",attributeList,0); 
inst_co = new DenseInstance(data.numAttributes()); 
data.add(inst_co); 

Ich empfehle Header-Informationen und Instanzen Werte von externen Datei oder die Erstellung dieser Informationen nur einmal.

+0

Vielen Dank für die tolle Antwort. Nur um zu verdeutlichen, sind Klasse A und Klasse B die möglichen Ergebnisse der Klassifizierung, d. H. Meine Clusternamen, richtig? Ich denke, sie müssen mit denen identisch sein, die während der Erstellung des Modells verwendet wurden. – Erol

+0

Nicht funktioniert, ich bekomme weka.core.UnassignedDatasetException: DenseInstance hat keinen Zugriff auf einen Datensatz! Error. Ich denke, ich muss es einem Datensatz zuordnen, vielleicht dem, mit dem ich es trainiert habe? – Erol

+0

@babatenor Sie müssen es Datensatz mit dem gleichen Header zuweisen. Ihre Header-Informationen sollten die gleichen sein –

3

Eigentlich versuchte ich in meiner Situation ist die instance.setDataSet() -Methode aufrufen, nicht die addInstance-Methode.So Sie Code sollte inst_co.setDataSet (Daten) sein.