我正试图操纵朱莉娅的一棵树。树被创建为对象。我只想用另一个分支替换其中一个分支。我可以手动完成,但不能通过使用递归函数来完成。
mutable struct ILeaf
majority::Any # +1 when prediction is correct
values::Vector # num_of_samples
indicies::Any # holds the index of training samples
end
mutable struct INode
featid::Integer
featval::Any
left::Union{ILeaf,INode}
right::Union{ILeaf,INode}
end
ILeafOrNode = Union{ILeaf,INode}
我修剪树的功能是(树是原始的,通过使用LR_STACK,我愿意更改其中一个分支并用子树替换它。):
function traverse_and_assign(tree, subtree, lr_stack) # by using Global LR_stack
if top(lr_stack) == 0
tree = subtree
elseif top(lr_stack) == :LEFT
pop!(lr_stack)
return traverse_and_assign(tree.left, subtree, lr_stack)
else # right otherwise
pop!(lr_stack)
return traverse_and_assign(tree.right, lr_stack)
end
end
发生的事情是我无法更改原始树。
另一方面:
tree.left.left = subtree
完美无缺。
我的代码出了什么问题?我必须为此写一个宏吗? B.R。
修改#1 为了生成数据:
n, m = 10^3, 5 ;
features = randn(n, m);
lables = rand(1:2, n);
修改#2 使用100个样本来训练决策树:
base_learner = build_iterative_tree(labels, features, [1:20;])
然后逐一提供其他样本:
i = 21
feature = features[21, :], label = labels[21]
gtree_stack, lr_stack = enter_iterate_on_tree(base_learner, feature[:], i, label[1])
获取错误样本的索引
ids = subtree_ids(gtree_stack)
构建子树:
subtree = build_iterative_tree(l, f, ids)
更新原始树(base_learner):
traverse_and_assign(base_learner, subtree, lr_stack)
答案 0 :(得分:0)
我仍然想念MWE,但也许我可以帮助解决一个没有它的问题。
在Julia中,value绑定到变量。函数中的参数是新变量。让我们来测试它的含义:
function test_assign!(tree, subtree)
tree = subtree
return tree
end
a = 4;
b = 5;
test_assign!(a, b) # return 5
show(a) # 4 ! a is not changed!
发生什么事了?值4绑定到tree
,值5绑定到subtree
。
subtree
的值(5)与tree
绑定。
没有别的!方法a
与4绑定。
如何更改a
?这将有效:
mutable struct SimplifiedNode
featid::Integer
end
function test_assign!(tree, subtree)
tree.featid = subtree.featid
end
a = SimplifiedNode(4)
b = SimplifiedNode(5)
test_assign!(a, b)
show(a) # SimplifiedNode(5)
为什么呢?发生了什么事?
a
的值(类似于指向可变结构的指针)绑定到tree
,b
的值绑定到subtree
。
所以a
和tree
绑定到相同的结构!意味着如果我们更改该结构a
将绑定到更改的结构。