用Java创建weka需要的Instance对象和arff文件

在用Java使用weka时,我们需要weka支持的数据格式,weka官网上给出的大多是从arff文件中导入数据。从数据库中生成对系统环境要求也较高。因此本文介绍了如何通过普通的Java对象生成weka支持的Instance对象,并保存到arff文件中。

总体思路

首先创建一个Instances对象,为Instances对象设置属性(@Attribute),然后从对象创建Instance加入到Instances中,如果需要保存,可以直接将Instances对象保存为arff格式的文件。

Attribute

在介绍attribute之前首先简述一下arff的文件格式。官网上示例如下:

% 1. Title: Iris Plants Database
   % 
   % 2. Sources:
   %      (a) Creator: R.A. Fisher
   %      (b) Donor: Michael Marshall (MARSHALL%PLU@io.arc.nasa.gov)
   %      (c) Date: July, 1988
   % 
   @RELATION iris

   @ATTRIBUTE sepallength  NUMERIC
   @ATTRIBUTE sepalwidth   NUMERIC
   @ATTRIBUTE petallength  NUMERIC
   @ATTRIBUTE petalwidth   NUMERIC
   @ATTRIBUTE class        {Iris-setosa,Iris-versicolor,Iris-virginica}
   @DATA
   5.1,3.5,1.4,0.2,Iris-setosa
   4.9,3.0,1.4,0.2,Iris-setosa
   4.7,3.2,1.3,0.2,Iris-setosa
   4.6,3.1,1.5,0.2,Iris-setosa
   5.0,3.6,1.4,0.2,Iris-setosa
   5.4,3.9,1.7,0.4,Iris-setosa
   4.6,3.4,1.4,0.3,Iris-setosa
   5.0,3.4,1.5,0.2,Iris-setosa
   4.4,2.9,1.4,0.2,Iris-setosa
   4.9,3.1,1.5,0.1,Iris-setosa

因为arff文件和Instances是对应的,在创建Instances对象之前我们需要指定Instances的属性,对应到Java中,@ATTRIBUTE对应的是weka.core.Attribute对象。

Instance

Instance是一条数据,类似于数据库中的一行。在新版的weka(>3.5)中,Instance只是一个接口,在本文中以DenseInstance为例创建Instance,其他Instance可以在weka官方api中查到。

创建Instances

private Instances generatePopularInstance(List entities) {
        //set attributes
        ArrayList attributes = new ArrayList<>();
        attributes.add(new Attribute("fork"));
        attributes.add(new Attribute("size"));
        attributes.add(new Attribute("sum"));
        attributes.add(new Attribute("avg"));
        attributes.add(new Attribute("weight"));
        //set instances
        Instances instances = new Instances("repo_popular",attributes,0);
        instances.setClassIndex(instances.numAttributes() - 1);
        //add instance
        for (SecRepoEntity secRepoEntity: entities) {
            Instance instance = new DenseInstance(attributes.size());
            instance.setValue(0,secRepoEntity.getForkCount());
            instance.setValue(1,secRepoEntity.getSize());
            instance.setValue(2,secRepoEntity.getSumFollower());
            instance.setValue(3,secRepoEntity.getAvgFollower());
            instance.setValue(4,secRepoEntity.getWeightFollower());
            instances.add(instance);
        }
        return instances;
    }

保存Instances对象为arff文件

    /**
     * generate weka dataSource file
     * @param instances weka Instances
     */
    public void generateArffFile(Instances instances, String path) {
        ArffSaver saver = new ArffSaver();
        saver.setInstances(instances);
        try {
            saver.setFile(new File(path));
            saver.writeBatch();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

从arff文件导入Instances

weka官网有详细的说明,这里摘录新版的方法。(使用DataSource)

import weka.core.converters.ConverterUtils.DataSource;
 ...
 DataSource source = new DataSource("/some/where/data.arff");
 Instances data = source.getDataSet();
 // setting class attribute if the data format does not provide this information
 // For example, the XRFF format saves the class attribute information as well
 if (data.classIndex() == -1)
   data.setClassIndex(data.numAttributes() - 1);

你可能感兴趣的:(机器学习)