2017-12-10 12 views
0

私はJuliaでツリーを操作しようとしています。ツリーはオブジェクトとして作成されます。私が望むのは、枝の一つを別の枝に置き換えることだけです。私は手動で行うことができますが、再帰関数を使用してそれを行うことはできません。ツリーをchaningためJuliaでツリーをトラバースしてサブツリーを割り当てる

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を使用することによって、私は枝の1つを変更し、サブツリーでそれを代用して喜んで、1つのオリジナルである。)である:

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.

base_learner = build_iterative_tree(labels, features, [1:20;]) 

が、他のサンプル1を与える:決定木を訓練するため

n, m = 10^3, 5 ; 
features = randn(n, m); 
lables = rand(1:2, n); 

編集#2 使用100のサンプル:データを生成するために

編集#1 1つ:

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) 

の指標は、サブツリーを構築し得る:私はまだMWEを欠場多分私ができる

traverse_and_assign(base_learner, subtree, lr_stack) 
+0

[mcve](https://stackoverflow.com/help/mcve)と書くことができますか? ([MWE](https://en.wikipedia.org/wiki/Minimal_Working_Example)としても知られています) – Liso

+0

実際に、私は[DecisionTree.jl](https://github.com/bensadeghi/DecisionTree.jl)パッケージ。ほぼ、私が使用しているすべての機能はそこからです。私は不変型を可変型に変更しました。それに加えて、私は、どのサブツリーを新しいものに置き換えるべきかを決定するためにスタックを保持しています。 –

+0

理解しようとするのは難しい仕事です。たとえば、あなたの目的は再帰を使用することですが、関数 'my_traverse_and_assign'は異なる名前の関数を呼び出すことです' traverse_and_assign'は必要ですか?誰がMWEなしで知ることができましたか? BTWに追加するコンベンションがあります!そのパラメータを変更する場合は関数名に変換します。だから、 'my_traverse_and_assign!'おそらくより良い名前です。 – Liso

答えて

0

subtree = build_iterative_tree(l, f, ids) 

アップデート元ツリー(base_learnerを)それなしで1つの問題に助けてください。

ジュリア値では、変数にバインドされます。関数内のパラメータは新しい変数です。テストは何を意味しますか:

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

+0

私を助けていただきありがとうございます。私は最終的に[作業サンプル](https://github.com/kadir-gunel/for_today)を作成しました。 –

関連する問題