我的代码有点问题。
我在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);
}
没有打印日志。所以,没有遗漏的属性。
答案 0 :(得分:0)
从日志中可以看出,您有一些未设置或缺失的值。你应该使用
data.setClassMissing();
将instances类值设置为missing。