Мне интересно написать алгоритм рекурсивного двоичного дерева. Учитывая следующие данные, в которых я уже отсортировал ковариату x
mydata <- data.frame(x = c(10, 20, 25, 35), y = c(-10.5, 6.5, 7.5, -7.5))
> mydata
x y
1 10 -10.5
2 20 6.5
3 25 7.5
4 35 -7.5
Предположим, что мое окончательное дерево выглядит примерно так:
[-10.5, 6.5, 7.5, -7.5]
/ \
[-10.5] [6.5, 7.5, -7.5]
/ \
[6.5, 7.5] [ -7.5]
Мне нужен окончательный результат моей функции чтобы вернуть список, содержащий все узлы:
> final_tree
[[1]]
[[1]][[1]]
x y
1 10 -10.5
2 20 6.5
3 25 7.5
4 35 -7.5
[[2]]
[[2]][[1]]
x y
1 10 -10.5
[[2]][[2]]
x y
1 20 6.5
2 25 7.5
3 35 -7.5
[[3]]
[[3]][[1]]
NULL
[[3]][[2]]
NULL
[[3]][[3]]
x y
1 20 6.5
2 25 7.5
[[3]][[4]]
x y
1 35 -7.5
Я разбиваю свое дерево на каждом узле случайным образом, используя best_split_ind
. Если best_split_ind = 1
, то это означает, что 1-й экземпляр в node_parent
окажется в node_left
, а остальные окажутся в node_right
. Если best_split_ind = 3
, то это означает, что первые три экземпляра в node_parent
окажутся в node_left
, а остальные в node_right
.
Вот что у меня есть на данный момент:
# Initialize empty tree
create_empty_tree <- function(max_height) sapply(1:max_height, function(k) replicate(2**(k-1),c()))
# Create empty tree with max_height = 3
tree_struc <- create_empty_tree(max_height = 3)
grow_tree <- function(node_parent, max_height, tree_struc, height){
# Sort x
sorted_x <- sort(node_parent$x)
# Determine best split
best_split_ind <- sample(1:(nrow(node_parent) - 1), 1)
# Assign instances to left or right nodes
group <- ifelse(node_parent$x <= node_parent$x[best_split_ind], "left", "right")
node_left <- node_parent[which(group == "left"), ]
node_right <- node_parent[which(group == "right"), ]
# Recursive call on left and right nodes
if(height < max_height){
tree_struc[[height]] <- node_parent
tree_struc[[height + 1]][[1]] <- grow_tree(node_parent = node_left, max_height = max_height, tree_struc = tree_struc, height = height + 1)
tree_struc[[height + 1]][[2]] <- grow_tree(node_parent = node_right, max_height = max_height, tree_struc = tree_struc, height = height + 1)
}
return(tree_struc)
}
grow_tree(node_parent = mydata, max_height = 3, tree_struc = tree_struc, height = 1)
Полученное дерево неверно. Я думаю, это связано с тем, как я рекурсивно вызвал функцию на левом и правом дочерних узлах. Может ли кто-нибудь указать мне правильное направление?