Weka决策树Java到列表
我想建立一个决策树,并将其分解为列表(名称、符号、val)。 我用以下代码创建了树:Weka决策树Java到列表,java,weka,decision-tree,Java,Weka,Decision Tree,我想建立一个决策树,并将其分解为列表(名称、符号、val)。 我用以下代码创建了树: //Get File BufferedReader reader = new BufferedReader(new FileReader(PATH + "TempArffFile.arff")); //Get the data Instances data = new Instances(reader); reader.close
//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)
标题1
|位置匹配1:良好(4.0/1.0)
因此,我想从该树中获取4个列表:
- 标题(坏)
- 职位(>1)->职位(国家代码(良好
- 标题(>1)->职位(国家代码(>1)->错误
- 标题(>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());
}
publicstaticvoidsplit(字符串树){
String[]line=tree.split(“\n”);
List lists=新建ArrayList();
用于(字符串行:行){
List temp=new ArrayList();
while(line.indexOf(“|”)!=-1){
临时添加(“|”);
line=line.replaceFirst(“\\\\”,“”);
}
临时添加(line.trim());
列表。添加(临时);
}
对于(int i=0;i<3;i++){
列表。删除(0);
}
对于(int i=0;i<4;i++){
lists.remove(lists.size()-1);
}
列表替代项=新的ArrayList();
用于(列表:列表){
对于(int i=0;i
输入
J48未修剪树
瓣宽0.6
|花瓣宽1.7:维吉尼亚鸢尾(46.0/1.0)
假期数:5
树的大小:9
输出:
花瓣宽度0.6花瓣宽度1.5:鸢尾花色(3.0/1.0)
petalwidth>0.6 petalwidth>1.7:Iris virginica(46.0/1.0)首先,解析行的答案似乎有问题(我无法对此发表评论:(),它似乎用parent子句替换了每个“|”,但对于一个类似以下的树: A |C B |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");
}
}
private void字符串(J48 J48){
字符串树=j48.toString();
String[]line=tree.split(“\n”);
List lists=新建ArrayList();
//把线分成几部分。
用于(字符串行:行){
List temp=new ArrayList();
while(line.indexOf(“|”)!=-1){
临时添加(“|”);
line=line.replaceFirst(“\\\\”,“”);
}
临时添加(line.trim());
列表。添加(临时);
}
//删除输出的前3行。
对于(int i=0;i<3;i++){
列表。删除(0);
}
//删除输出的最后4行。
对于(int i=0;i<4;i++){
lists.remove(lists.size()-1);
}
//这是遍历树时任何给定节点的父节点的有序列表。
List parentClauses=new ArrayList();
//这描述了深度
//整数深度=-1;
//树上所有的路径。
列表路径=新的ArrayList();
用于(列表:列表){
int currDepth=0;
对于(int i=0;i
我希望有内置的东西。非常感谢,这将节省我很多时间。一个可能的解决方案是扩展Weka的J48,并根据需要覆盖toString方法。