【问题标题】:ArrayList conversion to Instances objectArrayList 转换为 Instances 对象
【发布时间】:2014-04-28 15:59:02
【问题描述】:

我有一个 ArrayList 测试集。此列表包含我在 WEKA 中进行 SMO 评估的数据。我想使用评估 weka 类来对我的测试集进行分类。在最简单的情况下,我只有一个 ArrayList 中的一个图像提取了一个特征。为了在下面使用我的列表,必须进行什么转换:

Evaluation eval = new Evaluation(testset); // how can I cast testset2 Instances object?
eval.evaluateModelOnce(c, data);

此代码来自here:我正在使用它来训练 SMO 模型。训练数据集包含特征提取的训练图像,存储在 .arff 文件中。在测试过程中,我正在读取我的代码中计算特征的图像,将它们存储在 arrayList 中,而不将它们存储在 .arff 文件中。我想将列表直接转换为 Instances 对象并继续分类。

编辑:我尝试做其他事情,首先将 arrayList 转换为数组双精度数据,然后继续进行我的 trainSet:

int numAtts = data[0].length;
FastVector atts = new FastVector(numAtts);
for (int att = 0; att < numAtts; att++) {
 atts.addElement(new Attribute("Attribute" + att, att));
}

int numInstances = data.length;
Instances dataset = new Instances("Dataset", atts, numInstances);
for (int inst = 0; inst < numInstances; inst++) {
dataset.add(new Instance(1.0, data[inst]));
}

但是我收到了:

Exception in thread "main" java.lang.ClassCastException: javax.management.Attribute cannot be cast to weka.core.Attribute

编辑:

我修改了一些代码

double data[][] = new double[1][];
data[0] = dt;

System.out.println(args[1]);
System.out.println(args[2]);
ClothesAnalysis asdf = new ClothesAnalysis();
weka.classifiers.Classifier c = asdf.loadModel(new File(args[1]), args[2]);


String opt = ("-C 100 -K weka.classifiers.functions.supportVector.NormalizedPolyKernel");
    String[] options = opt.split(" ");

int numAtts = data[0].length;
FastVector atts = new FastVector(numAtts);
for (int att = 0; att < numAtts; att++) {
 atts.addElement(new weka.core.Attribute("Attribute" + att, att));
}

int numInstances = data.length;
Instances dataset = new Instances("Dataset", atts, numInstances);
for (int inst = 0; inst < numInstances; inst++) {
 dataset.add(new Instance(1.0, data[inst]));
}

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

Evaluation eval = new Evaluation(dataset);

eval.evaluateModel(c, dataset);
System.out.println(eval.toSummaryString("\nResults\n======\n", false));

我收到错误:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 84
at weka.filters.unsupervised.attribute.ReplaceMissingValues.convertInstance(ReplaceMissingValues.java:274)
at   weka.filters.unsupervised.attribute.ReplaceMissingValues.input(ReplaceMissingValues.java:140
     )
at weka.classifiers.functions.SMO.distributionForInstance(SMO.java:1368)
at weka.classifiers.Classifier.classifyInstance(Classifier.java:84)
at  
  weka.classifiers.Evaluation.evaluateModelOnceAndRecordPrediction(Evaluation.java:1448)
at weka.classifiers.Evaluation.evaluateModel(Evaluation.java:1407)
at LBP.LBPDemo.main(LBPDemo.java:466)

EDIT2:我的问题是我必须在最后一个属性中添加类标签,所以我正在尝试添加:

atts.addElement(new weka.core.Attribute(" class {1, 2, 3, 4, 5, 6, 7}" , numAtts-1));

这是我的问题的索引。但是,这不是向数据集添加索引的正确方法。当我在最后一个属性中打印数据集时,我得到:

@attribute ' class {1, 2, 3, 4, 5, 6, 7}' numeric

我想删除撇号和数字以便正确阅读。

【问题讨论】:

  • 如果您可以指定测试集和 crossValidateModel(可能还有分类器)的签名,那将非常有帮助。
  • 在我的情况下不需要交叉验证模型,因为我只使用一个样本。我的分类器 c 属于 weka 类分类器。
  • "线程 "main" java.lang.ClassCastException 中的异常:javax.management.Attribute 不能转换为 weka.core.Attribute" - 导入错误。
  • 小代码更改:不确定是什么问题; EDIT2:我认为 Attribute 构造函数不解析其内容,所以我不希望它按您的预期工作,这只是列的名称,而不是列的内容。

标签: java casting weka


【解决方案1】:

假设您需要一个 Instances 对象,则不能将 ArrayList 强制转换为该对象。

我认为您需要将DataSourcegetDataSet() 与自定义Loader (constructor) 一起使用。

我想它应该像这样工作:

new DataSource(new ListLoader(testData)).getDataSet();

【讨论】:

  • 我正在尝试类似:Instances data = new weka.core.converters.ConverterUtils.DataSource(testset.getDataSet());但这不是我想要的。
  • 没有任何方法可以将 ArrayList 转换为 FastVector??
  • 我更新了我的帖子。您通常阅读文档吗?这些问题似乎在那些页面上得到了回答。此外,IDE 在代码探索过程中也有很大帮助。
  • 我越来越找不到 ListLoader 类。
【解决方案2】:

我不确定这是否彻底回答了您的问题,但如果您想使用 ArrayList&lt;Attribute&gt;而不是FastVector作为生成实例时的参数,尝试为Instances实现一个新的构造函数:

 /**
   * Creates an empty set of instances. Uses the given
   * attribute information. Sets the capacity of the set of 
   * instances to 0 if its negative. Given attribute information
   * must not be changed after this constructor has been used.
   *
   * @param name the name of the relation
   * @param attInfo the attribute information
   * @param capacity the capacity of the set
   * @throws IllegalArgumentException if attribute names are not unique
   */

public Instances(String name, ArrayList<Attribute> attInfo, int capacity) {

// check whether the attribute names are unique
HashSet<String> names = new HashSet<String>();
StringBuffer nonUniqueNames = new StringBuffer();
for (Attribute att: attInfo) {
  if (names.contains(att.name())) {
    nonUniqueNames.append("'" + att.name() +"' ");
  }
  names.add(att.name());
}
if (names.size() != attInfo.size())
  throw new IllegalArgumentException("Attribute names are not unique!" +
        " Causes: " + nonUniqueNames.toString());
names.clear();

m_RelationName = name;
m_ClassIndex = -1;
m_Attributes = attInfo;
for (int i = 0; i < numAttributes(); i++) {
  attribute(i).setIndex(i);
}
m_Instances = new ArrayList<Instance>(capacity);
} 

...您可以将此代码复制粘贴到 weka.core.Instances 类

【讨论】:

    【解决方案3】:

    我找到了将数据从内存加载到 weka 实例的解决方案。不是最漂亮的,但它有效。 基本上,您将 arff 文件内容生成为字符串,然后从该字符串的 StringReader 创建 Instances 对象。

    String arffString = "@relation RelationName\n\n@attribute attributeName1\n@attribute attributeName2 {No,Yes}\n\n@data\n'atribute1value',?\n";
    unlabeledData = new Instances(
    new BufferedReader(new StringReader(arffString)));
    

    【讨论】:

      猜你喜欢
      • 2020-10-29
      • 2013-10-16
      • 1970-01-01
      • 1970-01-01
      • 2011-02-14
      • 2012-10-21
      • 2016-01-24
      • 2018-11-06
      • 2014-08-28
      相关资源
      最近更新 更多