Đây là phiên bản igraph
. Hàm này lấy kết quả từ Parse_annotator
làm đầu vào của nó, do đó, ptext
trong ví dụ của bạn. NLP::Tree_parse
đã tạo ra một cấu trúc cây đẹp, vì vậy ý tưởng ở đây là duyệt qua nó một cách đệ quy và tạo ra một edgelist để cắm vào igraph
. Các edgelist chỉ là một ma trận 2 cột của head-> tail giá trị.
Để cho igraph
để tạo các cạnh giữa các nút thích hợp, chúng cần phải có số nhận dạng duy nhất. Tôi đã làm điều này bằng cách thêm một dãy số nguyên (sử dụng regmatches<-
) vào các từ trong văn bản trước khi sử dụng Tree_parse
.
Chức năng nội bộ edgemaker
đi ngang qua cây, điền edgelist
khi di chuyển. Có các tùy chọn để tô màu các lá riêng biệt với phần còn lại của các nút, nhưng nếu bạn vượt qua tùy chọn vertex.label.color
, nó sẽ tô màu chúng giống nhau.
## Make a graph from Tree_parse result
parse2graph <- function(ptext, leaf.color='chartreuse4', label.color='blue4',
title=NULL, cex.main=.9, ...) {
stopifnot(require(NLP) && require(igraph))
## Replace words with unique versions
ms <- gregexpr("[^() ]+", ptext) # just ignoring spaces and brackets?
words <- regmatches(ptext, ms)[[1]] # just words
regmatches(ptext, ms) <- list(paste0(words, seq.int(length(words)))) # add id to words
## Going to construct an edgelist and pass that to igraph
## allocate here since we know the size (number of nodes - 1) and -1 more to exclude 'TOP'
edgelist <- matrix('', nrow=length(words)-2, ncol=2)
## Function to fill in edgelist in place
edgemaker <- (function() {
i <- 0 # row counter
g <- function(node) { # the recursive function
if (inherits(node, "Tree")) { # only recurse subtrees
if ((val <- node$value) != 'TOP1') { # skip 'TOP' node (added '1' above)
for (child in node$children) {
childval <- if(inherits(child, "Tree")) child$value else child
i <<- i+1
edgelist[i,1:2] <<- c(val, childval)
}
}
invisible(lapply(node$children, g))
}
}
})()
## Create the edgelist from the parse tree
edgemaker(Tree_parse(ptext))
## Make the graph, add options for coloring leaves separately
g <- graph_from_edgelist(edgelist)
vertex_attr(g, 'label.color') <- label.color # non-leaf colors
vertex_attr(g, 'label.color', V(g)[!degree(g, mode='out')]) <- leaf.color
V(g)$label <- sub("\\d+", '', V(g)$name) # remove the numbers for labels
plot(g, layout=layout.reingold.tilford, ...)
if (!missing(title)) title(title, cex.main=cex.main)
}
Vì vậy, sử dụng ví dụ của bạn, chuỗi x
và phiên bản chú thích của nó ptext
, trông giống như
x <- 'Scroll bar does not work the best either.'
ptext
# [1] "(TOP (S (NP (NNP Scroll) (NN bar)) (VP (VBZ does) (RB not) (VP (VB work) (NP (DT the) (JJS best)) (ADVP (RB either))))(. .)))"
Tạo đồ thị bằng cách gọi
library(igraph)
library(NLP)
parse2graph(ptext, # plus optional graphing parameters
title = sprintf("'%s'", x), margin=-0.05,
vertex.color=NA, vertex.frame.color=NA,
vertex.label.font=2, vertex.label.cex=1.5, asp=0.5,
edge.width=1.5, edge.color='black', edge.arrow.size=0)
Được rồi, nhưng sau đó thì sao? – Indi
Có thể qua https://en.wikibooks.org/wiki/LaTeX/Linguistics#tikz-qtree? – Reactormonk