Android上的WEKA:java.lang.ArrayIndexOutOfBoundsException:length = 30;指数= 30

时间:2017-05-19 20:22:19

标签: java android weka

我的代码有点问题。

我在Android项目中使用WEKA库。

我想从sqlite db获取数据。

我无法使用DatabaseLoader类,因此我以这种方式创建了Instances对象:

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.012316,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)

我不明白我的代码有什么问题。

Instances对象有31个属性[0-30],我不明白为什么限制是30。

更新

我测试是否有缺少值添加此代码:

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

没有打印日志。所以,没有遗漏的属性。

1 个答案:

答案 0 :(得分:0)

从日志中可以看出,您有一些未设置或缺失的值。你应该使用

data.setClassMissing();

将instances类值设置为missing。