8

WEKA GUI를 사용하여 J48 모델을 교육하고 작성했습니다. 모델 파일을 내 컴퓨터에 저장 했으므로 이제 Java 코드의 단일 인스턴스를 분류하는 데이 파일을 사용하고 싶습니다. 나는 "cluster"속성에 대한 예측을하고 싶습니다.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); 
} 

는 그러나, 나는 선 inst_co.setValue(latitude, lat);상의 IndexArrayOutofBoundsException를 얻을 : 내가 뭘하면 다음과 같다. 이 예외에 대한 이유를 찾을 수 없습니다. 누군가가 올바른 방향으로 나를 가리킬 수 있다면 감사하겠습니다.

답변

8

데이터 세트 인 Instances 오브젝트에 inst_co를 추가해야합니다. 다음 코드가 작동해야합니다.

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; 
    } 
} 

인스턴스에서 데이터 개체를 만듭니다. 이 데이터에 인스턴스를 추가하십시오. 그 후에 인스턴스에 값을 설정할 수 있습니다.

외부 파일에서 헤더 정보 및 인스턴스 값을 가져 오거나이 정보를 한 번만 생성하는 것이 좋습니다.

+0

위대한 답변에 감사드립니다. 명확히하기 위해 classA와 classB가 분류의 가능한 결과입니다 (예 : 클러스터 이름). 나는 그들이 모델을 만드는 동안 사용 된 것들과 동일 할 필요가 있다고 생각한다. – Erol

+0

작동하지 않습니다. weka.core.UnassignedDatasetException가 발생합니다 : DenseInstance가 데이터 세트에 액세스 할 수 없습니다! 오류. 데이터 세트에 그것을 할당해야 할 것 같네요. 아마도 그것을 훈련시키는 데 사용 된 것일 겁니다. – Erol

+0

@babatenor 동일한 헤더가있는 데이터 세트에 할당해야합니다. 그들의 헤더 정보는 동일해야합니다 –

3

실제로 나는 내 상황에서 instance.setDataSet() 메서드가 아니라 addInstance 메서드를 호출합니다. 코드는 inst_co.setDataSet (data) 여야합니다.