idea中集成weka

蓝亚之舟
蓝亚之舟
蓝亚之舟
57
文章
17
评论
2021年4月20日16:28:22
评论
5,9271 3710字阅读12分22秒

一、前期准备

1、加入依赖

百度搜索 maven,找到 maven 的 repository 仓库,寻找 weka 的依赖包:

idea中集成weka

找到稳定版本(我下载 weka 软件的时候就是这个版本,没有犹豫,就是它了),点击进去选择对应版本,依然是和自己软件版本一致:

idea中集成weka

点击进去可以看到对应的依赖语句代码了,当然也可以下载 jar 包,不过能偷懒就偷懒一下吧:

idea中集成weka

2、新建 spring 项目,加入 weka 依赖

这里我创建的是 SpringBoot 项目,具体过程就不说了,超级简单。

创建一个 test 包,在建一个相关类就可以开始搞起了。

3、初步尝试

在网上找了半天,发现 weka 的实例代码比较少,搜关键词一大半网页都是软件 weka 的介绍,不得不说 java 搞 weka 实在是太过于小众了。

最终,皇天不负有心人,还是找到了一个代码实例:

有了代码实例,接下来就相对容易一些,至少有一个大体框架的实例可供参考。

二、逐步提升

1、任务:加载 arff 文件、csv 与 arff 文件之间转换

加载 arff 的两种方法:

将 arff 保存为 csv 文件:

将 csv 文件保存为 arff 文件:

2、任务:切分数据集

代码例子中训练集和测试集用的都是同一个数据,这个就有点搞笑了,第一步认为暂定为学习切分数据集,至少也要有合适的训练集和测试集。

切分代码如下:

3、任务:修改测试数据一条一条进行测试

划分好了训练数据和测试数据,本打算将这个测试数据一起进行评估,结果报错如下:

idea中集成weka

查看源代码,找到原因在于 evaluateModelOnceAndRecordPrediction 函数本身只接受一条记录:

通过查看源代码,找到了一个可以一次性评估整个数据集的:

除了查看源代码,也可以通过输入 Evaluation 加点的方式查看评估器对象有哪些函数,主要看函数参数里面有 classifier 同时还有 Instances 的,如果有,再看看函数名,基本上就可以确定。

最终原代码中的 for 循环测试,修改如下:

测试了一下,准确率和一条条测试一模一样。

4、任务:测试模型几种模式

idea中集成weka

如上图所示,在 weka 软件上,测试模型分为四种方法,那么对应的使用 java 代码也可以还原上面四种方法。

(1)Use traning set

第一种方法就是从网上搬运过来的原版代码——使用训练数据测试模型:

(2)Supplied test set

也就是重新加载一个新的数据集作为测试集,这个比较简单,仿照着数据集加载模式再来一次即可:

(3)Cross-validation

也就是交叉验证,这个原理大概说一下:

    将整个数据集分为 k 份(也叫 k 折),做 k 次试验,每次取其中 k-1 份作为训练数据,另外一份作为测试数据,最后综合 k 次试验的结果来验证模型。

要进行交叉验证,要使用 Evaluation 类,该类就是用来评估测试机器学习模型的。

Evaluation 评估器有两种评估方法:

  • 如果测试集和训练集没有分开,可以使用 crossValidateModel 方法,Evaluation 中crossValidate Model方法的四个参数分别为:
    • 第一个是分类器
    • 第二个是整个数据集(前面提到了测试集和训练集没有分开才使用这个)
    • 第三个参数是交叉检验的次数(10 是比较常见的)
    • 第四个是一个随机数对象。
  • 如果有训练集和测试集,可以使用 Evaluation 类中的 evaluateModel 方法,方法中的参数为:第一个为一个训练过的分类器,第二个参数是测试数据集。

注意:如果采用crossValidateModel方法,是不能进行训练的,因为这个方法本身包含训练过程。

我们所说的交叉验证就是指第一种方法,也就是采用 crossValidateModel 方法进行测试,先看一下源代码:

问题一

这里有一个疑问的地方,就是评估器在构建对象的时候,需要一个数据集,那么这个数据集有什么用?必须是训练数据,还说什么数据集都可以?

我查看了一下源代码(在安装目录 Weka-3-8-5/doc/index.html):

idea中集成weka

大家可以看到,data 参数的目的是为了获取信息的头部(估计是第一行信息,也就是特征名称)还有先验标签分布信息。

所有说,只要有这两个特征数据集即可,不过最好还是训练集为佳,毕竟这个先验标签分布信息不好说。

问题二

在网上查找代码的时候,发现一部分人在使用交叉验证的时候,用了 for 循环,而有的则没有使用,我上面的代码实例是后者,使用 for 循环的代码如下:

到底用不用 for 循环,我特意查看了一下 crossValidateModel 函数的源代码(按住 Ctrl+点击鼠标),有这么一段代码:

可以看到,crossValidateModel 方法中本身进行了一个 for 循环,每次循环生成一次训练集和测试集(基于第二个参数),还有分类器,在评估分类器时,本质还是调用的 evaluateModel 方法。

问题三

交叉验证的目的是什么?很多帖子都说是用来测试模型的,但是交叉验证中本身是有训练过程的,你测试模型过程中,又训练了模型(会使模型参数发生变化),那么交叉验证完后的模型还是原来的模型吗?或者说你测试的模型还是原来的模型吗?

这个问题,在一个帖子上找到了答案:

    交叉验证本身不是用来选择模型的,或者说它不单单是用来选择模型的,它集成了训练、测试和选择模型三个过程。

(4)percentage split

这个就是按照比例切分了,代码如下:

5、任务:初始化分类器与配置参数

初始化分类器:

分类器说好了,再来说一下配置参数问题,这个折腾了半天,主要是网上的资料太少了,找到一个源代码,还是错误的:

运行上述代码会报错如下:

idea中集成weka

根据错误提示,显然是配置参数格式有问题,于是开始查看 setOptions 方法源代码:

可以看到,只有参数含义,并没有我们想要的实例,后来,看到分类器还有一个 getOptions 方法,眼睛一亮,想到可以查看一下默认参数的格式是怎么样的,源代码如下:

输出打印如下:

idea中集成weka

看到打印结果,果断知道了网上的实例为什么错误了,人家一个设置要分两个字符串来写,于是修改如下:

结果还是报错,也是佛了,最后的最后,想到了 weka 软件的参数设置:

idea中集成weka

看到上面 J48 后面出现的字符和通过 getOptions 打印出来的一样,点击进去,修改二分叉的属性(将 binarySplits 的 False 修改为 True),再看看果然发生了变化:

idea中集成weka

看到这里我才明白,根部不需要什么 true,对于这种非数值型参数设置只要一个字符串就可以,于是再次修改参数设置:

再次运行,没有报错,完美运行。

建议:先使用weka软件设置完参数,然后将参数复制粘贴过来就行了。

问题一

有一问题是,除了 J48 classifier = new J48();创建的对象能够使用 setOptions 方法,其他两种创建对象方式都不能使用该方法,不知道哪里有问题,查看源代码,三种方式指向的类都是同一个类,这个后续有时间再解决一下。

6、任务:从数据库读取数据生成 Instances

从 oracle 数据库读取:

从 mysql 数据库读取:

7、任务:保存模型与加载模型

这个相对简单一下:

说实话,这一顿搞后,还是觉得通过 java 使用 weka 远没有软件方便,建议可以使用 weka 软件生成模型,再通过 java 直接调用模型即可,感觉会方便很多。

继续阅读
weka最后更新:2021-4-27
蓝亚之舟
JavaWeb开发

Vue项目创建详解

1、前提 第一步:安装node.js 什么是nodejs? 简单的说 Node.js 就是运行在服务端的 JavaScript。 Node.js是一个基于 Chrome V8 引擎的 JavaScri...
JavaWeb开发

springboot实战(2):maven多项目模块整合

1、前言 1.1 初衷 本来接下来应该是实战一个登陆页面的,但是感觉每个实战应该可以分开来,这样有个循序渐进的过程,我想的是整合成类似下面的形式: 一个项目中有多个模块,每个模块负责不同的实战内容,相...
idea使用

idea使用(1):依赖包详细图解

1、如何导包 idea 中导包,分为两种,pom 文件导包和手动导包,这里说一下如何 pom 文件导包。 1.1 Maven 仓库 首先,百度 maven,找到对应的仓库(repository)官方网...

发表评论