R-Blogger블로그·해설한국어2023-12-17
tidygraph에 대한 새로운 초점
tidygraph의 새로운 focus 기능tidygraph의 새 버전이 출시되었습니다. 패키지에 큰 변화가 드물었지만 이번에는 단순히 상위 의존성 변경을 반영하는 수준을 넘어 몇 가지 새로운 기능을 추가했습니다. 대규모 릴리스는 아니지만, 블로그 포스트를 쓸 정도의 새 내용이 포함되어 있습니다. tidygraph 사용자는 반드시 읽어 보시길 권합니다. 처음이라면 프로젝트 웹사이트를 살펴보고 사용자를 먼저 만들어 보세요.새로운 feature: focus() / unfocus()특히 기대되는 기능은 focus()와 unfocus()동사 쌍의 추가입니다. 이 아이디어는 원래 패키지 설계 단계에서 제안했지만 처음 릴리스에서는 제외되었고, 오랫동안 남아 있었습니다. 또한 매우 유용하기 때문에 다시 도입하게 되었습니다.왜 필요할까요? 전통적인 표형 데이터에서는 모든 행이 동일한 중요성을 갖습니다. 행을 필터링하더라도 남은 데이터도 여전히 동일하게 취급됩니다. R(및 dplyr)의 벡터화 접근법이 자연스럽게 적용됩니다. 그러나 그래프 데이터에서는 관심 대상이 되는 노드와 부수적인 노드가 존재할 수 있습니다. 필터링을 하면 그래프 구조 자체가 바뀌어 계산 결과에 영향을 줄 수 있습니다. 대부분의 알고리즘은 성능이 뛰어나 vectorized 방식이 그대로 적용되지만, 엣지 수가 매우 많고 일부 노드·엣지만을 대상으로 계산하고 싶을 때는 상황이 다릅니다.focus()동사는 그래프 구조를 유지하면서 일시적으로 특정 노드 또는 엣지만을 대상으로 필터링할 수 있게 해 줍니다. 즉, tidygraph 알고리즘은 focus된 요소에만 적용되지만 전체 그래프에 접근할 수 있으므로, 포커스 여부와 관계없이 동일한 결과를 반환합니다.library(tidygraph) ## Attaching package: 'tidygraph' ## The following object is masked from 'package:stats': ## filter graph %>% mutate(important = dplyr::row_number()) %>% focus(important) %>% mutate(efficiency = node_efficiency()) %>% unfocus() %>% as_tibble() %>% slice(1:10) ## # A tibble: 10 × 2 ## important efficiency ## <lg> <dbl> ## 1 TRUE 0.0253 ## 2 TRUE 0.0274 ## 3 TRUE 0.0417 ## 4 TRUE 0.0306 ## 5 TRUE 0.0368 ## 6 FALSE NA ## 7 FALSE NA ## 8 FALSE NA ## 9 FALSE NA ##10 FALSE NA위 예시에서는 각 노드의 지역 효율성을 계산하지만, 처음 5개 노드에만 관심이 있으므로 focus()를 사용해 나머지 99,995개 노드에 대한 계산을 생략했습니다. 이에 따라 상당한 속도 향상이 이루어집니다. 다만 이 성능 향상은 알고리즘에 따라 달라집니다. 거리 행렬의 컨볼루션처럼 전체 그래프를 한 번에 계산하는 알고리즘에서는 이점이 없을 수 있습니다.focus는 노드와 엣지 모두에 적용할 수 있습니다. 그래프 상태 중 가장 약한 상태이며, activate, group, morph등을 수행하면 자동으로 unfocus됩니다. 즉, 가장 일시적인 상태라고 생각하시면 됩니다.새로운 iterate_*() 동사또 다른 오래된 아이디어가 구현되었습니다. 바로 iterate_*()동사군입니다. 이들은 기존보다 간단하지만, tidygraph 문법으로 그래프 시뮬레이션을 작성할 때 유용합니다. while()혹은 for()루프와 같은 기능을 파이프라인에 넣을 수 있습니다.예를 들어, 엣지를 제거하되 해당 엣지가 노드를 고립시키는 경우는 유지하는 시뮬레이션을 생각해 보겠습니다.unwire <- function(graph) { graph %>% mutate(well_connected = centrality_degree() > 1) %>% activate(edges) %>% mutate( can_remove = .N()$well_connected[from] & .N()$well_connected[to], will_remove = dplyr::row_number() == sample(dplyr::row_number(), 1L, prob = can_remove) ) %>% pull(will_remove) }위 함수를 iterate_n()와 함께 20번 적용하면 다음과 같습니다.create_notable('meredith') %>% iterate_n(20, unwire) ## # A tbl_graph: 70 nodes and 120 edges ## # Undirected simple graph with 1 component ## # Node Data: 70 × 0 (active) ## # Edge Data: 120 × 2 ## from to ## 1 1 5 ## 2 1 6 ## 3 1 7 ## … … …또는 iterate_while()을 사용해 그래프가 두 개 컴포넌트로 분리될 때까지 반복할 수도 있습니다.
원문 URL
전체 글은 원문 페이지에서 이어서 읽을 수 있습니다.
- 작성자
- R-Blogger
- 출처
- R-Blogger
- 플랫폼
- R-Blogger
- 분류
- 블로그·해설
- 언어
- 한국어
- 발행일
- 2023-12-17