R:具有随机分裂的递归树算法

R:具有随机分裂的递归树算法,r,algorithm,recursion,tree,R,Algorithm,Recursion,Tree,我对编写递归二叉树算法感兴趣。给定以下数据,我已经对协变量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 我希望函数的最终输出返回一个包含所有节点的列表: > final_tree [[1]] [[1]][[1]] x y 1 10

我对编写递归二叉树算法感兴趣。给定以下数据,我已经对协变量
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
我希望函数的最终输出返回一个包含所有节点的列表:

> 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\u split\u ind
在每个节点上随机拆分树。如果
best\u split\u ind=1
,则这意味着
节点父节点中的第一个实例将在
节点左侧
结束,其余实例将在
节点右侧
结束。如果
best\u split\u ind=3
,则意味着
节点父节点中的前三个实例将在
节点左
中结束,其余实例将在
节点右
中结束

以下是我目前掌握的情况:

# 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)
#初始化空树

create_empty_tree我可能误解了您的意思,但是通过使用两个递归调用的函数,您可以在这里简化很多。不需要设置初始容器

第一个函数甚至不需要手动调用,但将从
grow_树
函数内部调用。它只是检查它是否未达到最大树深度,以及是否有足够的元素可以拆分。如果是这样,它将对其内容调用
grow\u tree
。否则,它将返回其内容不变:


conditional_split也许您可以尝试下面的代码,在
grow_tree
中定义了另一个自定义函数
rndsplit

create_empty_tree <- function(max_height) sapply(1:max_height, function(k) replicate(2**(k-1),c()))
grow_tree <- function(node_parent,max_height = nrow(node_parent)) {
  rndsplit <- function(x) {
    if (is.null(x) || nrow(x) <= 1) return(list(c(),c()))
    ind <- sample(nrow(x)-1,1)
    list(x[1:ind,],x[-(1:ind),])
  }
  tree_struc <- create_empty_tree(max_height)
  tree_struc[[1]][[1]] <- node_parent
  for (i in 2:max_height) {
    tree_struc[[i]] <- unlist(lapply(tree_struc[[i-1]], rndsplit),recursive = FALSE)
  }
  tree_struc
}


非常感谢你。我如何解释$right$left$left?也就是说,这是树上的哪个节点?@YQW它只是看起来的样子。从根开始,先取该节点的右分支,然后取该节点的左分支,然后再取左分支到下一个节点。在问题顶部的示例中,
[-10.5]
将是
$left
[-7.5]
将是
$right$right
,谢谢。作为旁注,是否有可能存储每次拆分的
break_at
值。试试这个不错的解决方案!以交互方式调用函数是明智的。向上投票!
grow_tree(mydata, max_depth = 3)
#> $left
#>    x     y
#> 1 10 -10.5
#> 
#> $right
#> $right$left
#> $right$left$left
#>    x   y
#> 2 20 6.5
#> 
#> $right$left$right
#>    x   y
#> 3 25 7.5
#> 
#> 
#> $right$right
#>    x    y
#> 4 35 -7.5
create_empty_tree <- function(max_height) sapply(1:max_height, function(k) replicate(2**(k-1),c()))
grow_tree <- function(node_parent,max_height = nrow(node_parent)) {
  rndsplit <- function(x) {
    if (is.null(x) || nrow(x) <= 1) return(list(c(),c()))
    ind <- sample(nrow(x)-1,1)
    list(x[1:ind,],x[-(1:ind),])
  }
  tree_struc <- create_empty_tree(max_height)
  tree_struc[[1]][[1]] <- node_parent
  for (i in 2:max_height) {
    tree_struc[[i]] <- unlist(lapply(tree_struc[[i-1]], rndsplit),recursive = FALSE)
  }
  tree_struc
}
> grow_tree(mydata,3)
[[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 20   6.5

[[2]][[2]]
   x    y
3 25  7.5
4 35 -7.5


[[3]]
[[3]][[1]]
   x     y
1 10 -10.5

[[3]][[2]]
   x   y
2 20 6.5

[[3]][[3]]
   x   y
3 25 7.5

[[3]][[4]]
   x    y
4 35 -7.5
> grow_tree(mydata)
[[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
2 20  6.5
3 25  7.5
4 35 -7.5


[[3]]
[[3]][[1]]
NULL

[[3]][[2]]
NULL

[[3]][[3]]
   x   y
2 20 6.5

[[3]][[4]]
   x    y
3 25  7.5
4 35 -7.5


[[4]]
[[4]][[1]]
NULL

[[4]][[2]]
NULL

[[4]][[3]]
NULL

[[4]][[4]]
NULL

[[4]][[5]]
NULL

[[4]][[6]]
NULL

[[4]][[7]]
   x   y
3 25 7.5

[[4]][[8]]
   x    y
4 35 -7.5