简介:面向数据挖掘初学者的 WEKA 操作入门文档,系统讲解开放数据挖掘平台 WEKA 的核心概念与基础使用流程。内容涵盖 ARFF 数据格式、实例与属性术语、数据预处理、分类、回归、聚类、关联规则及可视化等主要功能,并介绍了接口开放、算法集成和 CSV 数据导入等实用方法,适合刚接触数据挖掘工具的学生或研究人员快速建立整体认知。文档从 weather.arff 示例入手,梳理头信息、属性声明、数据类型等关键细节,让读者理解 WEKA 读取二维表数据的基本逻辑;还提及通过 Excel、Matlab 预处理数据后再导入 WEKA 的常见流程,便于后续开展真实数据集分析。压缩包共 1 个 doc 文件,容量 172KB,为图文型教程,便于按章节查阅和离线学习。该资源已有 791 人学习下载,适合作为数据挖掘课程配套或自学辅助材料,阅读后可掌握 WEKA 的数据组织方式与基本操作路径,为分类、聚类与关联分析实践打下基础。
1. WEKA 操作入门:第一关不是算法,是数据格式
做数据挖掘绕不开 WEKA 操作入门这个坎。很多新同学装好工具后第一件事就是找分类器,结果数据导不进去,卡在“xls 怎么转 csv”“csv 怎么变成 arff”“第一行到底要不要表头”这类基础问题上。WEKA 是某高校团队维护多年的开源数据挖掘平台,自带数据预处理、分类、回归、聚类、关联规则和可视化,核心输入是 ARFF 格式文件。它能解决的是“把一份乱七八糟的表格干净地送进算法”这件事,适合刚接触数据挖掘、暂时不想写代码、又想完整走一遍数据到模型流程的从业者。本文用自带示例 weather.arff 和 bank-data.csv 做素材,把 ARFF 格式拆解、CSV 转换、Explorer 预处理和常见坑一次讲透。
2. 把 weather.arff 拆开看:ARFF 头信息与数据区的完整规则
很多人第一次打开 WEKA 安装目录下的 data 文件夹,看到一堆 .arff 文件不知道从哪下手。我建议拿 weather.arff 当第一个解剖对象,它只有 14 行数据、5 个属性,能在一屏之内看清 ARFF 的全部规则。ARFF 全称是 Attribute-Relation File Format,是一种纯 ASCII 文本格式,任何文本编辑器打开都能直接读懂,这也意味着你完全可以手工维护它。
2.1 表格、实例与属性:先统一术语
ARFF 描述的数据集是一张二维表,表格里的一个横行叫一个实例(Instance),相当于统计学里的一个样本,或者数据库里的一条记录;一个竖列叫一个属性(Attribute),相当于一个变量或者一个字段。在 WEKA 看来,这样一张表描述的是属性之间的一种关系(Relation),所以文件头的@relation weather就是在给这个关系起名字。
这个术语对应关系非常重要,后面你在 Explorer 界面里看到的每一条信息,本质都是在对这张二维表做“行”和“列”的操作。删除属性是删列,删除实例是删行,离散化是改列的取值类型,过滤是整体变形。如果脑子里没有这张表,操作面板上的按钮就只是一堆按钮。
2.2 @relation 与 @attribute:头信息的三个硬性要求
我把 weather.arff 完整写在下面,文件名就叫 weather.arff,WEKA 安装目录的 data 子目录下能直接找到:
% WEKA 自带示例数据:天气与是否外出游玩 @relation weather @attribute outlook {sunny, overcast, rainy} @attribute temperature real @attribute humidity real @attribute windy {TRUE, FALSE} @attribute play {yes, no} @data sunny,85,85,FALSE,no sunny,80,90,TRUE,no overcast,83,86,FALSE,yes rainy,70,96,FALSE,yes rainy,68,80,FALSE,yes rainy,65,70,TRUE,no overcast,64,65,TRUE,yes sunny,72,95,FALSE,no sunny,69,70,FALSE,yes rainy,75,80,FALSE,yes sunny,75,70,TRUE,yes overcast,72,90,TRUE,yes overcast,81,75,FALSE,yes rainy,71,91,TRUE,no以%开始的行是注释,WEKA 解析时直接忽略。去掉注释后,整个文件分成两部分:头信息和数据信息。头信息包括@relation和若干条@attribute,从@data开始是真正的数据区。
这里有几个容易被忽略的规则。第一,属性声明的顺序就是数据区列的顺序,humidity 是第三个被声明的属性,那数据区每一行被逗号分开的第三列就必须是 humidity 的值,这个顺序错一个位置,后面所有算法都会跑偏。第二,最后一个声明的属性被称作 class 属性,在分类和回归任务里它是默认的目标变量。weather 里最后一个属性是 play,所以 WEKA 默认尝试预测“是否去玩”,这个默认行为后面还会反复提到。第三,属性名和关系名如果包含空格,必须用英文单双引号包起来,比如@relation 'bank data'是合法的,裸写bank data会直接报错。
2.3 四种数据类型:WEKA 只认这几种列类型
属性声明的格式是固定的:@attribute <属性名> <数据类型>。属性名必须以字母开头,这是 ARFF 语法的硬指标。WEKA 支持的数据类型一共有四种,新手最容易混淆的是 nominal 和 string。
| 类型写法 | 含义 | 典型示例 |
|---|---|---|
numeric | 数值型,整数小数均可 | @attribute temperature real |
{a, b, c} | 分类(nominal)型,列出所有合法取值 | @attribute outlook {sunny, overcast, rainy} |
string | 字符串型,内容任意文本 | @attribute address string |
date [格式] | 日期时间型,格式遵循 Java 日期语法 | @attribute birthday date yyyy-MM-dd |
一个容易踩的细节:windy {TRUE, FALSE}里的 TRUE 和 FALSE 在 WEKA 眼里只是两个离散取值,属性类型依然是 Nominal,不是布尔型。另一个细节是 date 类型,@attribute created date不写格式时,默认按 ISO-8601 的yyyy-MM-ddTHH:mm:ss解析数据区的值,T是个字母而不是占位符。如果数据区写成2024-03-05 10:30:00,带空格不带 T,就会报格式错误。需要自定义时在 date 后面写格式,数据区的字符串必须严格匹配,否则这一行数据会被当成无效值。
2.4 @data 数据区:每一行都与声明顺序严格对应
数据区从@data标记开始,之后每一行是一条实例,逗号分隔各属性值。拿 weather 的第一行数据说:
sunny,85,85,FALSE,no它按顺序依次对应 outlook=sunny,temperature=85,humidity=85,windy=FALSE,play=no。如果某个位置的属性值缺失,WEKA 的惯例是写一个英文问号?,而不是留空,也不是写 NULL。字符串类型的值即使不含特殊字符,也建议用引号包起来,避免逗号把字符串切开造成列数错位。
到这里可以下一个重要结论:ARFF 的头信息不是摆设,它就是数据区的“表结构约束”。声明顺序决定列位置,声明类型决定合法值范围,想清楚这一点,后面手工改文件、写转换脚本时就能少踩一半的坑。
3. 从 CSV 到 ARFF:三种转换方式与字段类型边界
实际工作中,拿到手的数据很少直接是 ARFF。最常见的来源是表格软件导出的 CSV、数据库导出的文本、或者从统计软件里生成的矩阵文件。WEKA 官方支持通过 JDBC 直连数据库,但对多数人来说,先把数据规整成 CSV,再转成 ARFF,是最稳、最好排查问题的路径。
3.1 表格软件与统计软件:先把源数据导成 CSV
在常见表格软件里,一个工作簿可能包含多个工作表,每个工作表都是一张二维表。转换时只能把当前工作表另存为 CSV 类型,切换工作表要重新另存一次。如果是矩阵计算软件,二维表格本质是一个矩阵,通常用一行类似csvwrite('filename', matrixname)的命令就能把矩阵导出成 CSV。
这里有一个高频翻车点:表格软件和矩阵软件导出的 CSV 往往没有属性名,而 WEKA 转换器默认从 CSV 第一行读取属性名。如果第一行直接是数据,WEKA 就会把第一行的属性值当成变量名。解决方法是先用文本编辑器打开 CSV,手工补一行属性名,注意属性名的数量必须与列数一致,仍然用逗号分隔。我一般会顺手把英文空格也替换成下划线,省得后面 ARFF 里还要加引号。
3.2 Simple CLI 一行命令:CSVLoader 转换
启动 WEKA 主程序后,界面下方有一排按钮,点击进入 Simple CLI 模块,这是一个命令行窗口,最底部是输入行。转换命令非常短:
java weka.core.converters.CSVLoader bank-data.csv > bank-data.arff这条命令做了三件事:读入 bank-data.csv,调用 CSVLoader 解析格式,把结果重定向写到 bank-data.arff。>是重定向符号,这样屏幕上不会刷出一堆数据集内容,而是直接落盘。CSVLoader 默认会做类型推断:整列都是数字就识别成 numeric,都是有限几个离散字符串就识别成 nominal,遇到符合日期格式的字符串会尝试识别成 date。
如果 CSVD 文件没有表头,可以给 CSVLoader 加-noHeader参数让它自动生成属性名,但我个人不太推荐,因为自动生成的 att1、att2 可读性太差,后面在 Explorer 里看着难受。我一般更愿意手工补一行表头再转,也就多花半分钟。
3.3 Explorer 与 Arff Viewer:可视化转换适合第一次
不想敲命令时,WEKA 也提供了图形化转换路径。进入 Explorer 模块,用 Open 按钮选 CSV 文件,WEKA 会按同样规则解析并显示属性摘要,确认无误后点 Save,把文件另存为 ARFF 即可。WEKA 3.5 起的 Arff Viewer 模块也能实现类似操作,打开 CSV 预览后另存为 ARFF,适合拿不准类型推断结果时先用眼睛确认一遍。
这两种方式适合小文件,CSV 如果几十兆以上,Explorer 打开会明显变慢。批量转换时建议走命令行脚本,下面这段脚本会把当前目录下所有 csv 一次性转换成同名 arff:
#!/bin/bash WEKA_JAR=/path/to/weka.jar for f in *.csv; do java -cp "$WEKA_JAR" weka.core.converters.CSVLoader "$f" > "${f%.csv}.arff" echo "converted: ${f} -> ${f%.csv}.arff" done脚本里最需要改的是WEKA_JAR,它指向实际安装的 weka.jar 路径,在 Windows 上写法类似D:/weka/weka.jar。${f%.csv}是 Bash 语法,表示去掉文件名结尾的.csv,这样输出文件名能自然替换扩展名。批量转换之后一定要抽样检查几个输出文件,因为某个 CSV 里如果多了一列引号括号,整个文件列数就会不一致,但脚本不会报错。
三种转换方式对比一下:Simple CLI 最快且适合批量;Explorer 可视化,适合第一次接触时确认类型推断;文本编辑器手工改 ARFF 最灵活,适合小文件微调。我的习惯是批量数据全走命令行,单文件小数据直接 Explorer 另存。
| 方式 | 速度 | 适用场景 | 主要风险 |
|---|---|---|---|
| Simple CLI | 快 | 单文件、批量转换 | 看不到中间推断结果 |
| Explorer 打开后另存 | 慢 | 第一次使用、文件较小 | 大文件卡顿 |
| 文本编辑器手工改 | 中 | 微调类型、修正格式 | 手误改错列数 |
4. Explorer 预处理实战:删属性、改类型与 Discretize 参数设置
数据导入只是第一步,真正花时间的是预处理。WEKA 的 Explorer 是使用频率最高的模块,分类、聚类、关联规则都在这里启动,但数据准备的绝大多数动作集中在 Preprocess 面板。下面以 bank-data.csv 转换后的 bank-data.arff 为操作对象,走一遍预处理完整流程。
4.1 界面分区:八个区域各自管什么事
第一次打开 Explorer 的人容易懵,因为面板上信息太多。我按使用频率把它拆成八块来记:
- 任务切换选项卡:Preprocess、Classify、Cluster、Associate、Select attributes、Visualize 六个面板,预处理只在 Preprocess 里做。
- 常用按钮区:Open 打开文件,Save 保存,Undo 撤销,Edit 手工编辑。Undo 是后悔药,刚做完的误删操作能一键返回。
- Filter 选择区:点 Choose 弹出一棵 Filter 树,选择过滤器后,旁边的文本框显示具体参数。
- 数据集概况:显示当前关系名、实例数、属性数、总权重,一眼确认数据有没有读全。
- 属性列表:列出所有属性名,勾选后点 Remove 删除;上方一排按钮用于快速全选、全不选、反选。
- 属性摘要:选中某个属性后,这里显示它的类型、缺失值数量、唯一值数量,数值属性还会有 min、max、mean、stddev。
- 直方图:选中属性的分布可视,如果最后一个属性是分类变量,直方图每个条形会按各类比例分段,方便观察不同取值下的分布差异。
- 状态栏与 Log:运行任务时右侧小鸟图标在动,说明 WEKA 正在工作;右键状态栏还能手动触发 Java 垃圾回收。
最初我只盯着区域 5 和 6,后来发现区域 7 对判断“属性是否跟目标有关”特别有帮助。下拉框选不同分类属性,直方条的颜色比例变化越明显,说明该属性和选中分类的相关性越强,这一步能在建模前提供直觉。
4.2 删除 id 并手工把 children 改成 Nominal
bank-data 数据里有一个 id 属性,它是客户唯一编号。编号对预测任务毫无帮助,而且会在建模时被某些算法当普通数值属性使用,产生虚假的高相关性。预处理第一步就是勾选属性列表里的 id,点 Remove 删除。删除后点 Save 保存,再用文本编辑器打开这个 ARFF 文件,你会看到 WEKA 已经自动给每个属性声明了合适类型。
观察数据会发现 children 这个属性取值只有 0、1、2、3 四种,但它被声明成 numeric。有些算法只接受全部分类属性的输入,当它遇到 numeric 列会直接拒绝运行。既然 children 的取值集合已经明确,直接在文本编辑器里把这行:
@attribute children numeric改成:
@attribute children {0,1,2,3}然后在 Explorer 里重新打开,选中 children 属性,区域 6 的 Type 就会显示为 Nominal。这种枚举值声明方式同样适用于一切低基数数值列,比如状态码、等级、开关标识,没必要让算法把编号当连续数值处理,离散化反而能提高模型可解释性。
4.3 Discretize 过滤器:把 age 和 income 分成三段
age 和 income 是真正的连续变量,如果算法要求全 nominal,就需要离散化。WEKA 的 Discretize 过滤器是专门干这个的。在区域 2 点 Choose,弹出 Filter 树,按路径找到weka.filters.unsupervised.attribute.Discretize。选中后,Choose 旁边的文本框会显示默认参数:
weka.filters.unsupervised.attribute.Discretize -B 10 -M -0.1 -R first-last点这个文本框会弹出参数配置窗口,这里的默认参数容易误伤。-B 10表示默认分成 10 段,-R first-last表示应用于第一个到最后一个属性,也就是把所有属性都离散化。如果直接点 Apply,最后一列的 play 也会从 yes/no 被分箱成区间,那后面分类就没法做了。
我在这份数据上只处理第 1 个属性 age 和第 4 个属性 income,所以把参数窗口里的 attributeIndices 改成1,4,bins 改成3。其他参数保持默认。常用参数解释如下:
| 参数 | 本次值 | 作用 |
|---|---|---|
| attributeIndices | 1,4 | 指定要处理的属性位置,从 1 开始计数 |
| bins | 3 | 每个属性分成 3 段 |
| useBinLabels | false | 为 true 时生成可读标签,false 时生成区间表达式 |
| findNumBins | false | 自动搜索最优分箱数,覆盖 bins 设置 |
| invertSelection | false | 为 true 时处理未选中的属性 |
参数设好后点 OK 回到 Explorer,再点 Apply。此时 Log 会输出执行信息,属性列表里的 age 和 income 后面的类型会变成 Nominal,区域 6 的摘要里能看到类似(-inf-34.333333]的区间名。这种区间名可读性很差,如果介意,可以再用文本编辑器打开保存后的 ARFF,把区间字符串统一替换成0_34这类标签,换算逻辑是左开右闭,注意不要让替换后的标签破坏逗号分隔结构。更省事的办法是从一开始就把 useBinLabels 设为 true,它会生成'(-inf-34.333333]'之外更友好的命名,但不同版本生成的标签风格略有差异。
5. 数据准备避坑:五条实测翻车记录与修复方法
带新同学做数据挖掘这几年,翻车最狠的永远不是算法调参,而是数据准备阶段的“低级错误”。下面五条是我在真实项目里反复遇到过的,全部按现象、原因、解决的顺序写,每一条都能照抄修复。
5.1 导入与转换阶段的坑
坑 1:CSV 没有表头,属性名变成第一行数据
现象:转换后打开 Explorer,属性列表里出现sunny、85这种看起来像数据值的名字;或者系统直接提示属性数量与数据列数不一致。
原因:CSVLoader 默认把第一行当作属性名行,源文件没有表头时,第一行数据就被误读成变量名。表格软件和统计软件导出的 CSV 经常没有表头。
解决:转换前用文本编辑器打开 CSV 看第一行,没有表头就补一行,列数必须与数据完全一致。也可以用-noHeader参数让转换器自动生成 att1 这类名称,但可读性差,我一般手动补,多花 30 秒换后面几小时的省心。
坑 2:@attribute 声明顺序与数据区列顺序错位
现象:某个属性的摘要里出现了另一个属性的值,比如 temperature 的离散值计数长得像 outlook 的 sunny、overcast、rainy;建模结果完全看不懂。
原因:用文本编辑器手工调整过@attribute行,或者把 Excel 里的列重新排过,但@data区域没有同步调整顺序。ARFF 中属性声明顺序就是数据列顺序,声明是第三行,数据区第三列就必须是它。
解决:改 ARFF 先改数据区,再改头信息,始终让两者一一对应。改完重新打开 Explorer,先随机点几个属性看摘要,再做一次全量数据检查。
5.2 属性声明与预处理阶段的坑
坑 3:children 只有 0 到 3 四个值,却声明成 numeric 导致算法拒绝执行
现象:在 Classify 面板选好分类器点 Start,立刻弹出错误,提示不能处理 numeric 分类属性;或者模型跑完,children 被当成连续变量切分了。
原因:数值型属性在 WEKA 里默认是连续变量,很多算法不区分“取值只有四个的连续变量”和“真正的连续变量”。children 这类低基数数值列本质上是离散枚举,需要显式声明为 nominal。
解决:把@attribute children numeric手工改成@attribute children {0,1,2,3},注意枚举值必须与数据区出现的值完全一致,缺一个都会导致对应行报错。改完重新打开确认 Type 变成 Nominal 再往下走。
坑 4:Discretize 默认作用于全部属性,把 class 属性也离散化了
现象:对数据集执行 Discretize 后,最后一个目标变量从 yes/no 变成了区间标签,后续分类任务做不了。
原因:Discretize 的默认范围-R first-last包含所有属性,最后一个属性只要没被显式排除,同样会被分箱。目标变量变成连续区间后,分类目标就丢失了。
解决:在参数窗口把 attributeIndices 从 first-last 改成具体索引,比如1,4,或者离散化前把目标变量临时移到别处。执行前在区域 6 看一眼最后一个属性的摘要,确认它没有被改动。
坑 5:class 索引没设对,模型拿客户编号当输出
现象:分类准确率高得离谱,接近 99% 甚至 100%,但模型结果没有任何业务解释力。
原因:ARFF 中最后一个属性默认是 class 属性。如果原始数据把 id、编号这类无意义字段放在最后一列,WEKA 就会拿编号当分类目标,模型当然能“完美”预测自己。
解决:预处理时把真正要预测的目标变量挪到最后一个属性位置再保存;切换到 Classify 面板后,在实例类属性下拉框里确认选中的是目标变量。这一步是最值的 30 秒,它能避免一整天的无效实验。
6. 数据预处理后的三查验证:避免模型跑空了再后悔
每次数据处理完,先别急着切到 Classify 面板,花三分钟做一次三查验证。这三查已经不是可选项,而是我的固定动作,它能拦下上面五种坑里至少三种。
一查属性声明是否完整。在 Simple CLI 里或者文本编辑器里执行:
grep -n "^@attribute" bank-data.arff正常情况会输出每个属性名和类型,数量应该和你预期的列数一致。如果少了某个属性,说明数据区对应的那列数据可能是空列,被转换器丢弃了。
二查数据行列数是否一致。ARFF 文件数据区某些行如果混入了多余逗号,会出现列数不一致,这在后续算法里会变成莫名其妙的“找不到属性值”错误:
awk -F',' 'NR>1{print NF}' bank-data.arff | sort -u-F','指定逗号为分隔符,NR>1跳过 @data 之后第一行可能存在的空行,sort -u让所有不同的列数值集中显示。如果输出只有一个数字,比如 5,说明所有数据行都是 5 列,格式正常;如果出现了多个数字,就要回到数据区逐行排查了。
三查目标变量是否在最后一列且类型正确。直接看文件尾部:
tail -n 3 bank-data.arff理想情况是最后几行数据看起来和其他行一致,最后一列的值正好是目标变量的合法取值。如果看到 id 编号或者离散化后的区间表达式,class 属性就没设对,需要回到预处理步骤调整。
6.1 一个稳定的进阶习惯:先定 class,再动 Filter
除了三查,我现在还强制自己养成一个习惯:打开数据集后,先在属性列表里找到目标变量,确认它在最后一个属性的位置,并且确认它的类型和取值集合符合预期,然后再处理其他属性。为什么要强制这个顺序?因为很多 Filter 的执行行为依赖 class 属性,比如监督式离散化、特征选择、属性加权,它们会把最后一个属性当作监督信号。如果 class 是错的,这些过滤器会默默把噪声当成目标,产出一份看起来很合理、实际没法用的数据。
6.2 这个习惯把我捞回来过一次
有一次我处理一份某营销活动数据,6000 多行,字段有客户编号、收入、地区、是否购买。我按老流程直接导入、删掉几个不相关字段、一键离散化,然后丢给 J48 分类器。训练集准确率 99.8%,当时还觉得数据质量真好。后来偶然看了眼分类结果,发现模型输出的是客户编号而不是“是否购买”,我才意识到编号字段当时正好排在最后一列,WEKA 默认把它当成了 class。从那以后我每次打开数据后第一件事就是看最后一个属性摘要,并在跑模型前到 Classify 面板确认实例类属性下拉框里的选择。这个习惯不花时间,但能把人从“模型跑完了但白跑”的窘境里捞出来。
数据格式这东西,看起来琐碎,却决定了后面每一个环节是否靠谱。把 ARFF 读透、转换流程跑顺、预处理习惯固定住,再往后上分类器、调参数,都是水到渠成的事。希望这份 WEKA 操作入门能帮你少走一段冤枉路。
本文还有配套的精品资源,点击获取