Weka中Remove过滤器Invalid Range List异常的技术求助
我之前在做Weka属性选择的时候也碰到过一模一样的异常,大概率是属性索引列表的格式问题搞的鬼,毕竟Weka对Remove过滤器的参数格式要求特别严,给你梳理几个排查和解决的关键点:
先检查索引字符串的格式,重点看有没有多余空格
Weka的attributeIndices参数完全不允许列表里出现空格,必须是紧凑的无空格格式。比如你控制台输出的4,7-8,19,23是完全正确的,但如果你的代码里生成的字符串是4, 7-8, 19, 23(逗号后面带空格),就会触发解析错误,抛出你遇到的Invalid range list异常。
解决办法:构造索引字符串时一定要去掉所有空格,比如用String.join(",", 索引字符串列表)这种方式生成,避免手动拼接时不小心加了空格。确认索引的基数(1-based vs 0-based)是否匹配
这里要注意:AttributeSelection类返回的选中属性索引是0-based的,而Remove过滤器的attributeIndices参数要求的是1-based的索引。如果你直接把0-based的索引转成字符串传给Remove,很容易出现索引无效的问题。
比如你控制台输出的7-8如果是0-based的范围,对应的1-based应该是8-9,直接用0-based的范围字符串就会导致Weka解析出错。建议你检查代码里是否做了0到1的索引转换,确保传给Remove的是1-based的索引范围。检查
dontRemoveLastAttribute参数的干扰Remove过滤器默认开启dontRemoveLastAttribute=true,也就是会自动保留最后一个属性(你的标称型类属性)。如果你在选中的属性里已经包含了类属性,同时设置inverseSelection=true,理论上没问题,但如果索引列表格式有问题,或者重复指定了类属性,也可能触发异常。可以先尝试关闭这个参数(setDontRemoveLastAttribute(false))测试一下,看是否还会报错。验证索引范围的有效性
虽然你说选中的属性都存在,但还是要确认一下:你的数据集共23个属性,1-based索引范围是1-23,4,7-8,19,23确实都是有效的。不过如果代码里生成的范围不小心超出了这个区间(比如误写成7-24),也会报错,但你的情况更倾向于前两个原因。
给你一个参考的代码片段,确保格式和基数都正确:
// 假设已经通过AttributeSelection得到0-based的选中属性索引数组int[] selectedAttrIndices // 转换为1-based的字符串列表 List<String> idxStrList = new ArrayList<>(); for (int idx : selectedAttrIndices) { idxStrList.add(String.valueOf(idx + 1)); // 0转1基数 } // 生成无空格的紧凑索引字符串 String rangeString = String.join(",", idxStrList); // 初始化Remove过滤器 Remove removeFilter = new Remove(); removeFilter.setAttributeIndices(rangeString); removeFilter.setInverseSelection(true); removeFilter.setDontRemoveLastAttribute(false); // 可选关闭默认保留类属性的设置 removeFilter.setInputFormat(originalDataset); // 应用过滤器得到结果 Instances filteredDataset = Filter.useFilter(originalDataset, removeFilter);
内容的提问来源于stack exchange,提问作者astubenbord

