2017-05-19 14 views
-1

私のコードに少し問題があります。Android上のWEKA:java.lang.ArrayIndexOutOfBoundsException:length = 30; index = 30

私はAndroidプロジェクトでWEKAライブラリを使用しています。

sqlite dbからデータを取得したいとします。

私はDatabaseLoaderクラスを使用することはできませんので、私はインスタンスがこの方法でオブジェクトを作成:

public Instances getDatasetFromDB(String tableName, String[] select){ 

     Log.i(TAG, "Getting instances from Db"); 

     Instances result = null; 
     open(); 

     Cursor csr = query(tableName, select, null, null, null); 
     if(csr.getCount() != 0){ 
      Weka weka = new Weka(); 
      Instances centroids = weka.create_Instances("Centroids"); 
      List<Instance> list = new ArrayList<>(); 
      List<String> classType = new ArrayList<>(); 
      while(csr.moveToNext()){ 
       String type = csr.getString(csr.getColumnIndex("classType")); 
       classType.add(type); 
       list.add(cursorToInstance(csr)); 
      } 
      result = new Instances(weka.addInstance(centroids, list, classType)); 
     } 
     close(); 
     return result; 
    } 

/*Function of Weka Object*/ 
public Instances create_Instances(String name){ 
     FastVector wekaAttributes = new FastVector(); 

     for (int i = 0; i<ApplicationProperties.getnFeature(); i++) 
      wekaAttributes.addElement(new Attribute(GenericUtils.typeData(i))); 

     Instances dataSet = new Instances(name, wekaAttributes, 0); 

     int n_activity = ApplicationProperties.getnActivity(); 
     FastVector classNominal = new FastVector(n_activity); 
     for (int i=0; i<n_activity; i++){ 
      classNominal.addElement(GenericUtils.idToActivity(i)); 
     } 
     dataSet.insertAttributeAt(new Attribute("classType", classNominal), dataSet.numAttributes()); 

     dataSet.setClassIndex(dataSet.numAttributes() - 1); 

     return dataSet; 
    } 

public Instances addInstance(Instances instances, List<Instance> list, List<String> type){ 
     Iterator<Instance> i = list.iterator(); 
     Iterator<String> j = type.iterator(); 
     while(i.hasNext() && j.hasNext()){ 
      Instance inst = i.next(); 
      inst.setDataset(instances); 
      double[] tmp = inst.toDoubleArray(); 

      String t = j.next(); 
      tmp[tmp.length-1] = GenericUtils.activityToId(t); 

      instances.add(new Instance(1.0, tmp)); 
     } 
     return instances; 
    } 

このコードは、この返します。

@relation Centroids 

@attribute acc_max_x numeric 
@attribute acc_min_x numeric 
@attribute acc_mean_x numeric 
@attribute acc_std_x numeric 
@attribute acc_rms_x numeric 
@attribute acc_max_y numeric 
@attribute acc_min_y numeric 
@attribute acc_mean_y numeric 
@attribute acc_std_y numeric 
@attribute acc_rms_y numeric 
@attribute acc_max_z numeric 
@attribute acc_min_z numeric 
@attribute acc_mean_z numeric 
@attribute acc_std_z numeric 
@attribute acc_rms_z numeric 
@attribute gyro_max_x numeric 
@attribute gyro_min_x numeric 
@attribute gyro_mean_x numeric 
@attribute gyro_std_x numeric 
@attribute gyro_rms_x numeric 
@attribute gyro_max_y numeric 
@attribute gyro_min_y numeric 
@attribute gyro_mean_y numeric 
@attribute gyro_std_y numeric 
@attribute gyro_rms_y numeric 
@attribute gyro_max_z numeric 
@attribute gyro_min_z numeric 
@attribute gyro_mean_z numeric 
@attribute gyro_std_z numeric 
@attribute gyro_rms_z numeric 
@attribute classType {Fermo,Cammino,Corro,Veicolo} 

@data 
0.020366,-0.049443,9.699037,0.011994,0.020186,0.050924,-0.010524,0.035161,0.,0.038155,9.739549,9.656769,0,9.715311,9.699051,0.078441,-0.078495,0.000719,0.02763,0.027849,0.024923,-0.026115,-0.000634,0.009217,0.009327,0.023255,-0.020865,0,0.007926,0 
0.839357,-0.582571,9.413732,0.264762,0.923015,-0.825299,-1.967114,-1.385451,0.210502,1.658316,10.171442,8.569599,0,9.459311,9.443481,0.564504,-0.654348,0.000326,0.123502,0.136114,0.707076,-0.658781,0.00107,0.134813,0.137025,0.628173,-0.686233,0,0.113967,1 
0.994211,-0.382427,6.74315,0.325523,0.683864,7.406008,6.538764,6.994379,0.1867,7.035604,7.668721,5.612368,0,6.779348,6.768002,0.11319,-0.174827,0.000703,0.019038,0.030755,0.482416,-0.118256,0.004761,0.038078,0.040536,0.315722,-0.143182,0,0.03144,2 
0.60635,-1.418608,9.763421,0.315172,0.320185,0.627898,-0.514171,-0.040041,0.201248,0.20899,9.885362,9.643541,0,9.779818,9.763464,6.832833,0,-0.02351,0.395488,0.396995,4.230241,-0.002749,0.014193,0.244926,0.244967,0.000917,-5.28093,0,0.312452,3 
... 
... 

コードは、このポイントに到着したときに問題があります:

Instances data = new Instances(database.getDatasetFromDB(TrainingSetModel.TBL_NAME, TrainingSetModel.COLUMNS_DATASET)); 
data.setClassIndex(data.numAttributes()-1); 
ibk.buildClassifier(data); 

これは、スタックトレースは次のとおりです。

W/System.err: java.lang.ArrayIndexOutOfBoundsException: length=30; index=30 
W/System.err:  at weka.core.Instance.isMissing(Instance.java:395) 
W/System.err:  at weka.core.Instance.classIsMissing(Instance.java:221) 
W/System.err:  at weka.core.Capabilities.test(Capabilities.java:1132) 
W/System.err:  at weka.core.Capabilities.test(Capabilities.java:1023) 
W/System.err:  at weka.core.Capabilities.testWithFail(Capabilities.java:1302) 
W/System.err:  at weka.classifiers.lazy.IBk.buildClassifier(IBk.java:487) 
W/System.err:  at com.unipa.uniar.classification.Knn.getInstances(Knn.java:36) 
W/System.err:  at com.unipa.uniar.classification.Knn.<init>(Knn.java:26) 
W/System.err:  at com.unipa.uniar.classification.ClassificationTask.doInBackground(ClassificationTask.java:54) 
W/System.err:  at com.unipa.uniar.classification.ClassificationTask.doInBackground(ClassificationTask.java:19) 
W/System.err:  at android.os.AsyncTask$2.call(AsyncTask.java:304) 
W/System.err:  at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
W/System.err:  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 
W/System.err:  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 
W/System.err:  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 
W/System.err:  at java.lang.Thread.run(Thread.java:762) 

私のコードの問題は分かりません。インスタンスオブジェクト

は31の属性[0-30]、私は制限がある理由を理解していないを持っている30

UPDATE:このコードを追加する値が不足している場合、私はテスト

private void getInstances() throws Exception { 
     UniAR_DBAdapter database = new UniAR_DBAdapter(context); 
     data = new Instances(database.getDatasetFromDB(TrainingSetModel.TBL_NAME, TrainingSetModel.COLUMNS_DATASET)); 
     data.setClassIndex(data.numAttributes()-1); 
     for (int i=0; i<data.numInstances(); i++){ 
      for (int j=0; j < data.numAttributes()-1; j++){ 
       if(data.instance(i).isMissing(j)) { 
        Log.e(TAG, "Instance: " + String.valueOf(i) + "Attribute: " + String.valueOf(j) + "Missing"); 
        data.instance(i).setClassMissing(); 
       } 
      } 
     } 
     ibk.buildClassifier(data); 
    } 

ログは出力されませんでした。したがって、欠落した属性はありません。

+0

これはありません。 30の属性、0-29を持っています。 30は範囲外です。それはそれが長さを言うとき意味するものです:30 –

+0

私はそれが "長さ:30"を意味することを知っています。属性の数を数えれば、それはclass属性を含む31です。なぜそれは30 [0-29]と言いますか?私は数え間違っていますか? – Federico

答えて

0

ログには、値が設定されていないか、設定されていないようです。

インスタンスクラスの値を欠損値に設定してください。

+0

私はすべての属性をチェックし、いくつかの値が設定されていないか見つからないかどうかを調べるコードを追加します。欠損値はありません。 – Federico

関連する問題