文章目录

  • 1 环境配置
  • 2 数据模型
    • 2.1 Instances:数据集
    • 2.2 Instance:数据实例
    • 2.3 Attribute:属性类
  • 3 DataSource
  • 4 DataSink
  • 5 数据集处理
    • 5.1 创建数据集
    • 5.2 添加数据
  • 6 过滤
  • 7 分类
  • 8 聚类

1 环境配置

在 Idea 上创建 Maven Java 项目,并添加依赖:

    <dependency><groupId>nz.ac.waikato.cms.weka</groupId><artifactId>weka-stable</artifactId><version>3.8.6</version></dependency><!-- 下面是 weka 测试代码程序包 --><dependency><groupId>nz.ac.waikato.cms.weka</groupId><artifactId>weka-stable</artifactId><version>3.8.6</version><classifier>tests</classifier></dependency>

2 数据模型


Instances 是数据集类,可类似理解为数据表,Attribute 类描述了数据集中的属性定义,Instance 表示数据集中的一个数据实例,可类比理解为数据表中的一行数据。

2.1 Instances:数据集

Instances 类用来存储一个完整的数据集信息,其内部是基于行的数据结构,可以通过调用 instance(int) 方法来获取一行的数据,可以通过 attribute(int) 方法获取一列数据。

import weka.core.converters.ConverterUtils.DataSource;// Read all the instances in the file (ARFF, CSV, XRFF, ...)
DataSource source = new DataSource(filename);
Instances instances = source.getDataSet();// Make the last attribute be the class
instances.setClassIndex(instances.numAttributes() - 1);// Print header and instances.
System.out.println("\nDataset:\n");
System.out.println(instances);

2.2 Instance:数据实例

该类表示数据集中的一行,基本上是一个原始 double 数组的包装类。该类中不包含列的类型信息,可以通过访问关联的 Instances 数据集对象,来获取想要的信息。

AbstractInstance 类直接派生 weka.core.DenseInstance 类和 weka.core.SparseInstance 类,这两个类提供了实例的基本功能。前者处理实例速度较快,是更为优雅的面向对象方法;后者只存储非零值,因而节省一些存储空间。在后文的示例中,大部分都使用DenseInstance类,很少使用SparseInstance类,但两者的处理非常相似。

稠密数据在 arff 文件中如下:

@data  0, X, 0, Y, "class A"  0, 0, W, 0, "class B"

用稀疏格式表达的话,如下:

@data  {1 X, 3 Y, 4 "class A"}  {2 W, 4 "class B"}

每个实例用花括号括起来。实例中每一个非0的属性值用<index> <空格> <value>表示。<index>是属性的序号,从0开始计;<value>是属性值。属性值之间仍用逗号隔开。这里每个实例的数值必须按属性的顺序来写,如 {1 X, 3 Y, 4 "class A"} ,不能写成 {3 Y, 1 X, 4 "class A"}。注意在稀疏格式中没有注明的属性值不是缺失值,而是 0 值。若要表示缺失值必须显式的用问号表示出来。

实例中的所有值(数字、日期、标称值、字符串或关系型)都以浮点数的形式在内部存储,如果属性是标称(或字符串或关系),则存储的值是属性定义中相应标称(或字符串或关系)值的索引。这种实现方式在进行数据处理时,更优雅和高效。

// Create empty instance with three attribute values
Instance inst = new DenseInstance(3);// Set instance's values for the attributes "length", "weight", and "position"
inst.setValue(length, 5.3);
inst.setValue(weight, 300);
inst.setValue(position, "first");// Set instance's dataset to be the dataset "race"
inst.setDataset(race);// Print the instance
System.out.println("The instance: " + inst);

当添加字符串属性值时,实际上添加到数据数组中的是字符串属性的索引,具体过程如下列代码所示:

// 添加字符串属性值;
public final void setValue(int attIndex, String value) {int valIndex;if (m_Dataset == null) { // m_Dataset 是该数据实例所在数据集的引用throw new UnassignedDatasetException("Instance doesn't have access to a dataset!");}// 判断该属性的类型,是否为字符串型if (!attribute(attIndex).isNominal() && !attribute(attIndex).isString()) {throw new IllegalArgumentException("Attribute neither nominal nor string!");}// 判断值为 value 的属性是否已存在?valIndex = attribute(attIndex).indexOfValue(value);if (valIndex == -1) {if (attribute(attIndex).isNominal()) {throw new IllegalArgumentException("Value not defined for given nominal attribute!");} else {attribute(attIndex).forceAddValue(value); // 新建属性valIndex = attribute(attIndex).indexOfValue(value);}}setValue(attIndex, valIndex); // 实际添加的是属性值的索引!}

2.3 Attribute:属性类

该类保存数据集中的属性的元信息,如属性的类型,以及标称型属性的标签、字符串属性的全部值,以及关系属性的数据集。

支持以下数据类型:

  • numeric : 数值型,表示一个浮点数据;
  • nominal : 标称型,可以理解为枚举型;
  • string:字符串;
  • date:日期型,实际保存的是其相应的浮点型时间戳值;
  • relational:关系型,保存的是其他实例的引用。

示例:

// Create numeric attributes "length" and "weight"
Attribute length = new Attribute("length");
Attribute weight = new Attribute("weight");// Create list to hold nominal values "first", "second", "third"
List my_nominal_values = new ArrayList(3);
my_nominal_values.add("first");
my_nominal_values.add("second");
my_nominal_values.add("third");// Create nominal attribute "position"
Attribute position = new Attribute("position", my_nominal_values);

3 DataSource

Weka 支持多种格式的数据文件,比如 arff,csf,xrff 等,加载文件数据时,weka 会通过文件扩展名来推断文件内容的数据格式,然后选择合适的加载类。

可用的文件数据加载器放在 weka.core.converters 包中:

ConverterUtils 是一个工具类,其中定义了两个重要的内部类:DataSource, DataSink;DataSource 用于从文件中读取数据,DataSink 用于保存数据到文件。

 Instances data1 = DataSource.read("/some/where/dataset.arff");Instances data2 = DataSource.read("/some/where/dataset.csv");Instances data3 = DataSource.read("/some/where/dataset.xrff");// 也可以通过指定加载器的方式来加载文件:此时的文件扩展名,不受约束。CSVLoader loader = new CSVLoader();loader.setSource(new File("/some/where/some.data"));Instances data = loader.getDataSet();

DataSource 是用于从文件和URL加载数据的帮助类。通过 ConverterUtils 类,它决定使用哪个转换器将数据加载到内存中。如果选择的转换器是增量转换器,则数据将以增量方式加载,否则将以批处理方式加载。在这两种情况下,将使用相同的接口(hasMoreElements,nextElement)。在再次读取数据之前,必须调用重置方法。

4 DataSink

所有的保存器(saver)都位于 weka.core.converters 包中,保存数据既可以让 Weka 选择合适的转换器,也可以指定显示转换器。

     // 要保存的数据结构Instances data = DataSource.read("/some/where/dataset.arff");// 保存为ARFFDataSink.write("/some/where/data.arff", data);// 保存为CSVDataSink.write("/some/where/data.csv", data);// 保存为CSVCSVSaver saver = new CSVSaver();saver.setInstances(data);saver.setFile(new File("/some/where/data.csv"));saver.writeBatch();

5 数据集处理

5.1 创建数据集

创建数据集是指在内存中生成 Instances 对象,这个一个两阶段的过程:1, 通过设置属性定义数据格式;2,添加数据记录。其中数据定义可以理解为数据库操作中的 create table 操作,添加数据记录,可以理解为 insert 操作。

Weka目前有以下五种不同的属性类型。

  • numeric(数值型):连续变量。
  • date(日期型):日期变量。
  • nominal(标称型):预定义的标签。
  • string(字符串型):文本数据。
  • relational(关系型):包含其他关系。例如,多个实例数据组成的包(bags)。
// 1. 数值型
Attribute numeric = new Attribute("numeric_test");// 2. 日期型
Attribute date = new Attribute("date_test ", "yyyy-MM-dd");// 3. 标称型
ArrayList<String> labels = new ArrayList<String>();labels.add ("label_a");labels.add ("label_b");labels.add ("label_c");labels.add ("label_d");
Attribute nominal = new Attribute("nominal_test", labels);/*** 4. 字符串型* * 与标称属性不同,字符串类型不需要存放预定义的标签列表。通常用于存储文本数据,即文本分类的文档内容。* 字符串型使用与标称属性相同的构造函数,但需要提供一个null值,而非java.util.ArrayList<String>的实例。
*/
Attribute string = new Attribute("attribute_name", (ArrayList<String>)null);

5.2 添加数据

用户可以使用 DenseInstance 类的两种构造函数来实例化一个数据行,两种构造函数的功能如下。

  1. DenseInstance(double weight, double[] attValues):

该构造函数生成一个指定权重及给定 double 数组的 DenseInstance 对象。在 Weka 内部,全部五种属性类型都使用 double 格式。double格式表示数值型和日期型肯定没有问题,在Java内部,日期型也是用数值来表示的。对于标称型、字符串型和关系型属性,仅仅需要存放存储值的索引。

  1. DenseInstance(int numAttributes):

该构造函数生成一个新的、权重为1.0,全部值都缺失的DenseInstance对象。

double[] values = new double[data.numAttributes()]; // 创建示例数据// 添加属性值;
values[0] = 1.23;
values[1] = data.attribute(1).parseDate("2013-05-11");
values[2] = data.attribute(2).indexOf("label_b");
values[3] = data.attribute(3).addStringValue("A string");Instances dataRel = new Instances(data.attribute(4).relation(), 0); // 创建数据集
valuesRel = new double[dataRel.numAttributes()];
valuesRel[0] = 2.34;
valuesRel[1] = dataRel.attribute(1).indexOf("val_C");
dataRel.add(new DenseInstance(1.0, valuesRel));
values[4] = data.attribute(4).addRelation(dataRel);Instance inst = new DenseInstance(1.0, values); // 创建数据实例
data.add(inst); // 将实例添加到数据集

创建 Instances 的完整示例:

 private Instances relationInstances() {ArrayList<Attribute> attrRelation = new ArrayList<>();//      -- 关系属性 1:数值型attrRelation.add(new Attribute("att5.1"));//      -- 关系属性 2:标称型ArrayList<String> attValsRel = new ArrayList<>();for (int i = 0; i < 5; i++){attValsRel.add("val5." + (i + 1));}attrRelation.add(new Attribute("att5.2", attValsRel));return new Instances("att5", attrRelation, 0);}@Testpublic void printInstancesTest() throws Throwable {// 属性定义ArrayList<Attribute> attributes = new ArrayList<>();// - 属性1:数值型attributes.add(new Attribute("att1"));// - 属性2:标称型ArrayList<String> attrTags = new ArrayList<>();  // 为标称值创建标签for (int i = 0; i < 5; i++){attrTags.add("val" + (i + 1));}attributes.add(new Attribute("att2", attrTags));// - 属性3:字符串型attributes.add(new Attribute("att3", (ArrayList<String>) null));// - 属性4:日期型attributes.add(new Attribute("att4", "yyyy-MM-dd"));// - 属性5:关系型attributes.add(new Attribute("att5", relationInstances(), 0));Instances data = new Instances("MyRelation", attributes, 0);// 3. 添加数据// 第一个实例Instances dataRel = new Instances(data.attribute(4).relation(), 0);// -- 第一个实例dataRel.add(new DenseInstance(1.0, new double[]{Math.PI + 1,dataRel.attribute(1).indexOfValue("val5.3")}));// -- 第二个实例dataRel.add(new DenseInstance(1.0, new double[]{Math.PI + 2,dataRel.attribute(1).indexOfValue("val5.2")}));// 添加实例1// 2. 创建Instances对象data.add(new DenseInstance(1.0, new double[]{Math.PI, // - 数值型attrTags.indexOf("val3"), // - 标称型data.attribute(2).addStringValue("A string."), // - 字符串型data.attribute(3).parseDate("2013-04-05"), // - 日期型data.attribute(4).addRelation(dataRel) // 关系型}));// 4. 输出数据System.out.println(data);}

输出的数据集:

@relation MyRelation@attribute att1 numeric
@attribute att2 {val1,val2,val3,val4,val5}
@attribute att3 string
@attribute att4 date yyyy-MM-dd
@attribute att5 relational
@attribute att5.1 numeric
@attribute att5.2 {val5.1,val5.2,val5.3,val5.4,val5.5}
@end att5@data
3.141593,val3,'A string.',2013-04-05,'4.141593,val5.3\n5.141593,val5.2'

6 过滤

在 Weka 中,使用过滤器进行数据预处理。

在 weka.filters 包下可以找到这些过滤器,过滤器分为有监督过滤器和无监督过滤器两类。前者需要设置一个类别属性,后者不需要;过滤器还可以分为基于属性和基于实例两个子类,前者针对列的处理,例如,添加或删除列;后者针对行的处理,例如,添加或删除行。

除此之外,过滤器还可以分为流式过滤器或批处理过滤器。

 String[] options = new String[2];options[0] = "-R";                                       // 范围options[1] = "1";                                        // 第一个属性Remove remove = new Remove();                            // 构建过滤器实例remove.setOptions(options);                              // 设置选项remove.setInputFormat(data);                             // 设置输入格式,一定要在 setOptions 后面;Instances newData = Filter.useFilter(data, remove);      // 应用过滤器

批量过滤器可以同时处理多个数据集。

7 分类

在 Weka 中,分类和回归算法都称为“分类器”,位于 weka.classifier 包下。

所有的 Weka 分类器都设计为可批量训练的,即分类器对整个数据集一次就能训练好;还有一些算法可以随时随机地更新自己的内部模型,称为增量分类器。

批量分类器的构建非常简单:

  1. 设置选项;
  2. 进行训练;
import weka.classifiers.trees.J48;import weka.core.Instances;import weka.core.converters.ArffLoader;import java.io.File;/*** 批量方式构建J48分类器,并输出决策树模型*/public class BatchClassifier {public static void main(String[] args) throws Exception {// 加载数据ArffLoader loader = new ArffLoader();loader.setFile(new File("C:/Weka-3-7/data/weather.nominal.arff"));Instances data = loader.getDataSet();data.setClassIndex(data.numAttributes() - 1);// 训练J48分类器String[] options = new String[1];options[0] = "-U"; // 未裁剪树选项J48 tree = new J48(); // J48分类器对象tree.setOptions(options); // 设置选项tree.buildClassifier(data); // 构建分类器// 输出生成模型System.out.println(tree);}}

Evaluation 分类评估器,用于评估分类的性能,Weka 支持两种类型的评估,1,交叉验证,2,专用测试集验证。

Evaluation 中的常见方法:

方法名 说明
toSummaryString() 以摘要的形式输出性能统计数据,第一个参数为摘要标题,第二个参数为是否打印复杂的性能统计数据;
toMatrixString() 输出混淆矩阵;
toClassDetailsString() 输出TP / FP率、查准率、查全率、F-度量、AUC(每个类别);
toCumulativeMarginDistributionString() 输出累计边距分布;
correct() 正确分类的实例数量,不正确分类的实例数量可调用 incorrect() 方法得到;
pctCorrect() 正确分类的实例的百分比(查准率)。pctIncorrect() 返回错误分类的实例的百分比;
areaUnderROC(int) 指定的类别标签索引(基于0的索引)的AUC;
correlationCoefficient() 相关系数
meanAbsoluteError() 平均绝对误差
rootMeanSquaredError() 均方根误差
numInstances() 类别值的实例数量
unclassified() 未分类的实例数量
pctUnclassified() 未分类的实例的百分比

8 聚类

聚类是一种在数据中发现模式的无监督机器学习技术,也就是说,这些算法没有类别属性,这与分类不同,分类算法需要有一个类别属性,是有监督的机器学习算法。

执行聚类算法的步骤:

  1. 构建聚类器;
  2. 评估:对构建的聚类器进行评估;
  3. 执行聚类:对未知的实例进行聚类;
 Instances train = DataSource.read("C:/Weka-3-7/data/segment-challenge.arff");Instances test = DataSource.read("C:/Weka-3-7/data/segment-test.arff");String[] options = new String[2];options[0] = "-I";                   // 最大迭代次数options[1] = "100";EM clusterer = new EM();             // 聚类器的新实例clusterer.setOptions(options);       // 设置选项clusterer.buildClusterer(train);     // 构建聚类器// 评估ClusterEvaluation eval = new ClusterEvaluation();eval.setClusterer(cl);eval.evaluateClusterer(new Instances(train));System.out.println(eval.clusterResultsToString());// 执行聚类for (int i = 0; i < test.numInstances(); i++) {int cluster = clusterer.clusterInstance(test.instance(i));double[] dist = clusterer.distributionForInstance(test.instance(i));System.out.print((i + 1));System.out.print(" - ");System.out.print(cluster);System.out.print(" - ");System.out.print(Utils.arrayToString(dist));System.out.println();}

聚类器评估不像分类器评估那样容易做得很全面,由于聚类是无监督的,因此很难确定一个模型的性能到底有多好。 Weka 用于评估聚类算法的是 weka.clusters 包的 ClusterEvaluation 类。

数据挖掘与机器学习:Weka Java 编程接口 API相关推荐

  1. [转载]Z-stack 应用程序编程接口(API)-网络层

    原文地址:Z-stack 应用程序编程接口(API)-网络层作者:vexation NWK  层为更高层提供了如下功能:· ·  网络管理 ·  地址管理 ·  网络参数与功能函数 除了管理功能,NW ...

  2. USB联机线编程接口(API)

    USB联机线编程接口(API) 2013-10-19 本页面的文字允许在知识共享 署名-相同方式共享 3.0协议和GNU自由文档许可证下修改和再使用. 关键字:USB隔离线.USB点对点通讯.USB通 ...

  3. USB数据共享、联机线、联网线编程接口(API)

    本页面的文字允许在知识共享 署名-相同方式共享 3.0协议和GNU自由文档许可证下修改和再使用. USB联机线编程接口(API) 2017-11-26 一.概述 USB2.0理论传输速率最高为480M ...

  4. java api接口报500_应用程序编程接口API,我们来聊一聊这个熟悉的名词

    API,全称叫做Application Programming interface,也就是应用程序接口,API是一些预先定义的函数,我是学Java的,当我要使用这些函数的时候,便可以直接调用Java ...

  5. FTK应用程序编程接口(API)手册-1

    框架函数 框架函数支撑FTK的主体,它负责初始化应用程序,启动主循环和退出主循环.它对任何一个FTK应用程序都是不可缺少的,即使应用程序没有使用任何控件(当然这也没有什么意义),所以我们先介绍这些函数 ...

  6. FTK应用程序编程接口(API)手册-2

    全局对象存取函数 FTK中有一些单实例的对象,这些对象是以全局变量的形式存在的,为了有效的控制对这些对象的访问,我们提供了相应的存/取函数.这些对象都是在FTK初始化时创建的,所以开发人员无需要再调用 ...

  7. api有哪些 javasocket_基于java的socket编程及API解析

    一.socket通讯过程 1.socket与socket编程简介: socket 被翻译为"套接字",它是计算机之间进行通信的一种约定或一种方式.通过 socket 这种约定,一台 ...

  8. java扫描接口_一种扫描接口并生成可调用API接口文档的方法与流程

    本发明属于JavaWeb开发技术领域,涉及一种API接口文档的生成方法,尤其是一种扫描接口并生成可调用API接口文档的方法. 背景技术: API(Application Programming Int ...

  9. Java接口调用的安全性_java编程接口调用安全性都有哪些要求

    接口调用是我们在使用java编程开发语言的时候会经常使用到的一个功能,而今天我们就通过案例分析来了解一下,java编程接口调用安全性都有哪些要求. 1.调用接口的先决条件-token 获取token一 ...

最新文章

  1. 我一个普通程序员,光靠GitHub打赏就年入70万,要不你也试试
  2. HDU 1008 Elevator
  3. 弹出提示框 自动消失
  4. C#中简单的正则表达式(也经常会用到的)
  5. JavaScript二叉搜索树
  6. Python应用实战-LUX在pandas中智能可视化分析
  7. 解决RabbitMQ service is already present - only up...
  8. 好大夫王航:长尾开发者应尽快接入百度轻应用
  9. 通过文件锁 Lockfile/flock 让脚本单实例运行
  10. SQOOP --hive-import 错误(Sqoop Hive exited with status 1)及解决
  11. 力扣-面试题 10.05 稀疏数组搜索
  12. 机器字长 存储字长 指令字长 机器字长
  13. 正方形面积圆形面积Java
  14. 马哥教育42期第二周作业
  15. 虚无世界java路_[AoA3]虚无世界3 (Advent of Ascension 3)
  16. 【软件介绍】IGV软件的安装和基本介绍
  17. 副连长是什么级别_军改后连长工资有多少?军改后军队各级别工资待遇标准
  18. 解决Failed to introspect Class KafkaMetricsAutoConfiguration
  19. 移动端meta设置大全(持续收集中。。。。)
  20. 第一啪,第一啪电影网,第一啪电影网用的哪里的模板diyipa.cc

热门文章

  1. sqlite3.OperationalError: near “(“: syntax error
  2. kingmax超棒启动制作
  3. 一款典型的智慧电力物联网关的技术要求
  4. 华为OD机试真题 Python 实现【工单调度策略】【2023 Q1 | 100分】
  5. IT、CS、IS, 计算专业傻傻分不清楚? 这有何难
  6. 记两个国外CTF的弱pwn
  7. 【基础练习】【模拟】Uva489 - Hangman Judge题解
  8. BJDctf2020 Ezphp
  9. 隐函数及参数方程求导——“高等数学”
  10. Laravel 5.0 框架查看执行过的SQL语句