我正在尝试操纵朱莉娅的一棵树。该树是作为对象创建的。我只想用另一个分支代替其中一个。我可以手动执行此操作,但无法通过使用递归功能来做到这一点。
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)
我仍然想念MWE,但也许没有它可以解决一个问题。
在朱莉娅的值中是与变量结合的。功能中的参数是新变量。让我们测试这是什么意思:
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
被绑定到更改的结构。