Weka 决策树 Java 到列表
Posted
技术标签:
【中文标题】Weka 决策树 Java 到列表【英文标题】:Weka Decision tree Java to lists 【发布时间】:2014-11-25 05:42:36 【问题描述】:我想创建一个决策树并将其分解为列表(名称、符号、值)。 我用这段代码制作了树:
//Get File
BufferedReader reader = new BufferedReader(new FileReader(PATH + "TempArffFile.arff"));
//Get the data
Instances data = new Instances(reader);
reader.close();
//Setting class attribute
data.setClassIndex(data.numAttributes() - 1);
//Make tree
J48 tree = new J48();
String[] options = new String[1];
options[0] = "-U";
tree.setOptions(options);
tree.buildClassifier(data);
//Print tree
System.out.println(tree);
现在我需要将它分解为数组我该怎么做?
示例: 我得到了这棵树:
title <= 1: bad (4.0)
title > 1
| positionMatch <= 1
| | countryCode <= 1: good (3.0/1.0)
| | countryCode > 1: bad (8.0/3.0)
| positionMatch > 1: good (4.0/1.0)
所以我想从该树中获取 4 个列表:
title( 不好 title(> 1) -> position( countryCode( 好 title(> 1) -> position( countryCode(> 1) -> 错误 title(> 1) -> position(> 1) -> 好
我该怎么做?
【问题讨论】:
【参考方案1】:没那么好,但也许比没有更好... 也许它会给你一个想法。
public static void split(String tree)
String[] lines = tree.split("\n");
List<List<String>> lists = new ArrayList<List<String>>();
for(String line : lines)
List<String> temp = new ArrayList<String>();
while(line.indexOf("|") != -1)
temp.add("|");
line = line.replaceFirst("\\|", "");
temp.add(line.trim());
lists.add(temp);
for(int i = 0; i < 3; i++)
lists.remove(0);
for(int i = 0; i < 4; i++)
lists.remove(lists.size()-1);
List<String> substitutes = new ArrayList<String>();
for(List<String> list : lists)
for(int i = 0; i < list.size(); i++)
if(!list.get(i).contains(":") && !list.get(i).equals("|") && !substitutes.contains(list.get(i)))
substitutes.add(list.get(i));
for(List<String> list : lists)
for(int i = 0; i < list.size(); i++)
if(list.get(i).equals("|"))
list.set(i, substitutes.get(i));
StringBuilder sb = new StringBuilder();
for(List<String> list : lists)
String line = "";
for(String s : list)
line = line+" "+s;
if(line.endsWith(")"))
sb.append(line+"\n");
System.out.println(sb.toString());
输入
J48 未修剪的树
花瓣宽度
花瓣宽度 > 0.6
|花瓣宽度
| |花瓣长度
| |花瓣长度 > 4.9
| | |花瓣宽度
| | |花瓣宽度 > 1.5:鸢尾花 (3.0/1.0)
|花瓣宽度 > 1.7: Iris-virginica (46.0/1.0)
叶子数:5
树的大小:9
输出:
花瓣宽度
花瓣宽度 > 0.6 花瓣宽度
花瓣宽度 > 0.6 花瓣宽度 4.9 花瓣宽度
花瓣宽度 > 0.6 花瓣宽度 4.9 花瓣宽度 > 1.5:Iris-versicolor (3.0/1.0)
petalwidth > 0.6 petalwidth > 1.7: Iris-virginica (46.0/1.0)
【讨论】:
我希望有一些内置的东西。非常感谢它可以节省我很多时间。 一个可能的解决方案是扩展 Weka 的 J48 并根据您的需要覆盖 toString 方法。【参考方案2】:首先,解析行的答案似乎有问题(我无法评论它:(),它似乎用父子句替换了每个'|',但是对于像这样的树:
一个 | C 乙 | D
替换将是错误的,两个'|' C 和 D 前面的将被 A 替换。
此外,扩展类 J48 并重新实现 toString() 也无济于事,因为该树实际上存在于私有变量 m_root 中。
更新:
解析字符串的更好解决方案。
private void string(J48 j48)
String tree = j48.toString();
String[] lines = tree.split("\n");
List<List<String>> lists = new ArrayList<List<String>>();
// Break lines into parts.
for(String line : lines)
List<String> temp = new ArrayList<String>();
while(line.indexOf("|") != -1)
temp.add("|");
line = line.replaceFirst("\\|", "");
temp.add(line.trim());
lists.add(temp);
// remove first 3 lines of the output.
for(int i = 0; i < 3; i++)
lists.remove(0);
// remove last 4 lines of the output.
for(int i = 0; i < 4; i++)
lists.remove(lists.size()-1);
// This is a ordered list of parents for any given node while traversing the tree.
List<String> parentClauses = new ArrayList<String>();
// this describes the depth
//int depth = -1;
// all the paths in the tree.
List<List<String>> paths = new ArrayList<List<String>>();
for (List<String> list : lists)
int currDepth = 0;
for(int i = 0; i < list.size(); i++)
String token = list.get(i);
// find how deep is this node in the tree.
if (token.equals("|"))
currDepth++;
else // now we get to the string token for the node.
// if leaf, so we get one path..
if (token.contains(":"))
List<String> path = new ArrayList<String>();
for (int index = 0; index < currDepth; index++)
path.add(parentClauses.get(index));
path.add(token);
paths.add(path);
else
// add this to the current parents list
parentClauses.add(currDepth, token);
// print each of the paths.
for (List<String> path : paths)
String str = "";
for (String token : path)
str += token + " AND ";
LOG.info(str + "\n");
【讨论】:
以上是关于Weka 决策树 Java 到列表的主要内容,如果未能解决你的问题,请参考以下文章