首页 文章

如何从回归树中识别每个叶子中的序列?

提问于
浏览
2

使用biofam数据集

library(TraMineR)
data(biofam)
lab <- c("P","L","M","LM","C","LC","LMC","D")
biofam.seq <- seqdef(biofam[,10:25], states=lab)
head(biofam.seq)

 Sequence                                    
1167 P-P-P-P-P-P-P-P-P-LM-LMC-LMC-LMC-LMC-LMC-LMC
514  P-L-L-L-L-L-L-L-L-L-L-LM-LMC-LMC-LMC-LMC    
1013 P-P-P-P-P-P-P-L-L-L-L-L-LM-LMC-LMC-LMC      
275  P-P-P-P-P-L-L-L-L-L-L-L-L-L-L-L             
2580 P-P-P-P-P-L-L-L-L-L-L-L-L-LMC-LMC-LMC       
773  P-P-P-P-P-P-P-P-P-P-P-P-P-P-P-P

我可以适应并显示回归树:

seqt <- seqtree(biofam.seq~sex + birthyr, data=biofam)

seqtreedisplay(seqt, type="I", border=NA, withlegend= TRUE, legend.fontsize=2, legendtext = "Biofam Regression Tree")

然后我可以识别叶子成员资格:

seqt$fitted[,1]

然而,这是我感到困惑的地方 . 我如何知道哪个叶子编号对应于图中的哪个叶子?该图似乎没有显示它,并且运行 print(seqt) 似乎也没有给出叶号 .

我想要实现的是分离每个叶子中的序列,以便我可以分别在每个叶子上运行描述 . 我怎么能做到这一点?

2 回答

  • 2

    目前,此信息无法从树中轻松恢复 . 以下函数使用树的完整条件而不是节点标签返回拟合值的向量 .

    dtlabels <- function(tree){
        if (!inherits(tree, "disstree")) {
            stop("tree should be a disstree object")
        }
    
        split_s <- function(sp){
            formd <- function (x){
                return(format(x, digits =getOption("digits")-2))
            }
            str_split <- character(2)
            vname <- colnames(tree$data)[sp$varindex]
            if (!is.null(sp$breaks)) {
                str_split[1] <- paste("<=", formd(sp$breaks))
                str_split[2] <- paste(">", formd(sp$breaks))
            }
            else {
                str_split[1] <- paste0("[", paste(sp$labels[sp$index==1], collapse=", "),"]")
                str_split[2] <- paste0("[", paste(sp$labels[sp$index==2], collapse=", "),"]")
            }
            if(!is.null(sp$naGroup)){
                str_split[sp$naGroup] <- paste(str_split[sp$naGroup], "with NA")
            }
            return(paste(vname, str_split))
        }
        labelEnv <- new.env()
        labelEnv$label <- list()
        addLabel <- function(n1, n2, val){
            id1 <- as.character(n1$id)
            id2 <- as.character(n2$id)
            labelEnv$label[[id2]] <- c(labelEnv$label[[id1]], val)
        }
        nodeRec <- function(node){
            if(!is.null(node$split)){
                spl <- split_s(node$split)
                addLabel(node, node$kids[[1]], spl[1])
                addLabel(node, node$kids[[2]], spl[2])
                nodeRec(node$kids[[1]])
                nodeRec(node$kids[[2]])
            }
        }
        nodeRec(tree$root)
        l2 <- list()
        for(nn in names(labelEnv$label)){
            l2[[nn]] <- paste0(labelEnv$label[[nn]], collapse=" & ")
        }
        l3 <- as.character(l2)
        names(l3) <- names(l2)
        return(factor(factor(tree$fitted[, 1], levels=as.numeric(names(l3)), labels=l3)))
    
    }
    

    然后可以按以下方式使用该功能 .

    fitted <- dtlabels(seqt)
    print(table(fitted))
    

    希望这可以帮助!

  • 3

    实际上,您正在寻找树定义的规则 . 你可以通过查看树来看到它们 .

    例如,示例 seqt 的最左侧分支定义规则:

    birthyr <= 1940 & birthyr <= 1928
    

    最左边的叶子是由左边定义的

    birthyr <= 1940 & birthyr > 1928 & sex == "man"
    

    但是,我很害怕 . 你是对的 . TraMineR (您的 seqt )返回的 disstree 对象当前未明确包含该信息 . 也许在另一个版本中 .

相关问题