직사각형(소셜) 네트워크 데이터, 고급 옵션

본 연습은 my previous post about rectangling network data의 후속 내용이다.총괄적으로 말하자면 우리는 정점의 특징을 사용하여 그림의 노드 간의 링크를 예측하기를 바란다.이전 글에서 나는 평면 파일을 도형 구조에 불러오는 방법{tidygraph}을 어떻게 사용하고 정면과 부정적인 예시를 선택하며 노드 특징을 추출하는지 보여 주었다.
우리는 두 노드 사이에 링크가 존재할 수 있는지 예측하고 싶기 때문에 노드 특징을 사용할 수 있지만 그림의 가장자리에 대한 다른 정보도 있기 때문에 노드 특징만 사용하는 과정을 통해 얻을 수 없다.이 작은 훈련에서, 나는 당신에게 어떻게 두 노드 사이에서 공공 이웃을 얻을 수 있는지 보여 드리겠습니다.나는 {igraph}, 목록, 인덱스, 정규 표현식을 사용할 것이다.
library(dplyr)
library(tidygraph)

각 모서리에 대한 피쳐 생성하기


나의 직감은 바레스와 첸델라가 서로를 알지 못하지만, 공통된 친구가 몇 명 있다면, 그들은 시간적으로 관계를 맺을 가능성이 더 높은 것 같다는 것이다.만약 바레스와 제임스가 공통된 친구가 없다면, 그들 사이의 관계는 아무런 변화가 없을 것이다.몇몇 정보는 우리가 얼마나 공통된 사람이 있는지, 우리가 얼마나 공통된 친구가 있는지에 관한 것이다.

이전 기사에서 데이터를 검색하려면 다음과 같이 하십시오.
enriched_trainingset <- readr::read_rds(file = "data/enriched_trainingset.Rds")
emptier_graph <- readr::read_rds("data/emptier_graph.Rds")

현재 데이터 집합은 두 정점의 도, 개수, 페이지rank, 특징 중심도, 밀착도, 다리 분수와 핵심도를 포함한다.
names(enriched_trainingset)
 [1] "from" "to" "target" "degree"
[5] "betweenness" "pg_rank" "eigen" "closeness"
[9] "br_score" "coreness" "degree_to" "betweenness_to"
[13] "pg_rank_to" "eigen_to" "closeness_to" "br_score_to"
[17] "coreness_to"

igraph와tidygraph 사이의 차이를 처리합니다


나는tidygraph도 이런 조치를 취할 수 있다고 믿지만, 나는 아직 구체적인 방법을 발견하지 못했다.만약 네가 예가 있다면, 나는 정말 즐겨 본다.아마도 나는 다른 방식으로 데이터를 구성해야 할 것이다. 그러나 igraph에서 노드의 인덱스는tidygraph의 ID가 아니다.그래서 나는 반드시 이 이름들로 이 문제를 해결해야 한다.

정규 표현식


만약 당신이 정규 표현식=»skip to the code에 익숙하다면, 어떤 사람들은 정규 표현식을 두려워할 것이다. 나는 그것들이 모든 사람들이 좋아하는 것이 아니라는 것을 안다.심지어 명언도 있다.

Some people, when confronted with a problem, think “I know, I’ll use regular expressions.” Now they have two problems. – by Jamie Zawinski, see notes for more info


나는 그 중 하나coursera courses by the Johns Hopkins University at Coursera에서 정규 표현식을 배웠다.나의 스타크래프트 프로젝트에서, 나는 자주 그것을 사용하여 텔레비전 스크립트에서 짧은 단어를 추출한다.
비록 정규 표현식은 허튼소리처럼 보이지만, 그것들은 매우 강해서, 너는 그것으로 많은 일을 완성할 수 있다.나는 이것이 너를 놀라게 하지 않기를 바란다.테스트 예시를 항상 만들고 스크립트가 해야 할 일을 완성했는지 확인하고 여러 개의 작은 정규 표현식을 연결해서 필요한 내용을 얻는 것도 비교적 쉽다. '비교적 큰 텍스트 세션 captain crunch and his 4 friends 을 선택하고 그 중에서 새로운 선택 4 friends = > 4.
내가 너에게 사용한 모든 부품을 설명할 것이다.
나는 정규 표현식을 사용하여 텍스트 () 사이의 숫자를 추출할 것이다.그래서 저는 "タコベル ジャパン Taco Bell Japan (116)"부터 숫자116까지 하고 싶어요.
이것은 명령이다. gsub(pattern=".+\\(([0-9]+)\\)$",replacement="\\1",x=.) 나는 이 정규 표현식으로 내가 원하는 것을 검색했다. ".+\\(([0-9]+)\\)$" 나는 "\\1"로 결과를'포획조1'로 바꾸었고 마지막 부분x=.은 내가 파이프로 물건을 연결한 결과이다. 너는 names(nodes_igraph)로 읽어야 한다.따라서 모든 정점의 이름을 취하여 a()로 도안을 검색하고 찾은 숫자로 전체 텍스트를 대체합니다.
다음 내용을 살펴보겠습니다.
  • 우선 포획팀: 정규 표현식을 ()로 표시한 다음 \\number로 호출할 수 있습니다.
  • .+.표시: 모든 문자, +표시: 1회 또는 여러 번(모든 문자와 일치)
  • \\(의 뜻은 문자 괄호나 원괄호'()이지만 괄호에 특수한 의미가 있기 때문에 우리는 정규 표현식에 괄호가 필요하다는 것을 알리기 위해 두 개의 반사봉'전의'문자를 사용해야 한다
  • .
  • ([0-9]+)는 포획조 1에서 한 숫자(0-9사이, 다시 말하면 모든 숫자)가 한 번 또는 여러 번 나타난다고 밝혔다.
  • \\)의 뜻은 글자괄호나 원괄호)이지만 특수한 의미가 있기 때문에 우리는 반드시 두 개의 반사봉'전의'문자를 사용해야 한다.
  • $는 선로 말단
  • 을 가리킨다.
    그래서 나는 네가 정규 표현식을 다음과 같이 해석할 수 있다고 생각한다. 우리가 문자의 시작 부분의 괄호 ('뒤에는 숫자가 바짝 붙어 있고, 뒤에는 오른쪽 괄호가 바짝 붙어 있다') 와 줄 끝을 찾을 때까지 임의의 문자를 계속 가져라.그래서 이게'셰프 그레이스 라미레스(412)'같은 거랑 어울려요.도미노피자(Dominostory)(125)"()"사이의 숫자만 반환합니다.일치하지 않음blabla (23), 일치하지 않음blabla ()
    nodes_igraph <- igraph::V(emptier_graph)
    ids <- names(nodes_igraph) %>%
    gsub(".+\\(([0-9]+)\\)$","\\1",x=.) %>%
    as.numeric()
    
    

    각 노드의 이웃 찾기


    각 노드에 대해 연결된 노드를 찾으면 이웃 함수는 각 노드가 직접 연결된 노드를 포함하는 목록을 되돌려줍니다.
    # for every node find the nodes at distance 1.
    neighbors <- igraph::neighborhood(emptier_graph,order = 1)
    # for every node find the nodes at distance 2
    neighbors_dist2 <- igraph::neighborhood(emptier_graph,order = 2,mindist = 1)
    # Example of one
    neighbors_dist2[[11]]
    
    
    + 4/620 vertices, named, from 0a11922:
    [1] Spago Las Vegas (136) Domino's Guatemala (264)
    [3] Chope (391) Chef Michelle Bernstein (158)
    
    
    함수 세트를 만듭니다.
  • igraph 대상에서 노드 인덱스 함수를 찾습니다.
  • 두 개의 노드를 포함하고 두 개의 노드의 모든 직접 이웃을 찾아 공통된 이웃을 통계하는 함수.
  • 또 다른 유사하지만 거리는 2
  • 훈련이 집중된 모든 측면(정면과 부정 예시)을 순환하여 이 두 함수를 응용하여 데이터 집중에 추가한다.
  • # convenience function to translate the id in tidygraph into the id in igraph. 
    lookup_node_id <- function(empty_graph_id){
    which(ids == empty_graph_id)
    }
    n_common_neighbors <- function(from, to){
    stopifnot(from != to) # I know myself, and protect against me
    from_id <- lookup_node_id(as.integer(from))
    from_nb <- names(neighbors[[from_id]]) # name of this node
    from_itself <- names(nodes_igraph[[from_id]])
    from_nbs <- setdiff(from_nb, from_itself)
    to_id <- lookup_node_id(as.integer(to))
    to_nb <- names(neighbors[[to_id]])
    to_itself <- names(nodes_igraph[[to_id]])
    to_nbs <- base::setdiff(to_nb, to_itself)
    ### return only the neighbor nodes found in both sides
    result <- base::intersect(from_nbs, to_nbs)
    if(is.null(result)){
    0
    }else{
    length(result)
    }
    }
    n2_common_neighbors <- function(from, to){
    stopifnot(from != to) # I know myself, and protect against me
    from_id <- lookup_node_id(as.integer(from))
    from_nb <- names(neighbors_dist2[[from_id]])
    from_itself <- names(nodes_igraph[[from_id]])
    from_nbs <- setdiff(from_nb, from_itself)
    to_id <- lookup_node_id(as.integer(to))
    to_nb <- names(neighbors_dist2[[to_id]])
    to_itself <- names(nodes_igraph[[to_id]])
    to_nbs <- base::setdiff(to_nb, to_itself)
    result <- base::intersect(from_nbs, to_nbs)
    if(is.null(result)){
    0
    }else{
    length(result)
    }
    }
    # superslow, because it is not vectorized.
    get_common_neighbors <- function(dataframe){
    n1 <- rep(NA_integer_,nrow(dataframe))
    n2 <- rep(NA_integer_,nrow(dataframe))
    for (i in 1:nrow(dataframe)) {
    n1[[i]] <- n_common_neighbors(
    dataframe$from[[i]], dataframe$to[[i]]
    )
    n2[[i]] <- n2_common_neighbors(
    dataframe$from[[i]], dataframe$to[[i]]
    )
    }
    dataframe$commonneighbors_1 = n1
    dataframe$commonneighbors_2 = n2
    dataframe
    }
    
    
    이제 다음 기능을 수행합니다.
    두 노드 사이의 공공 이웃 수를 이용하여 훈련집을 풍부하게 하고 각 가장자리에 몇 개의 노드가 있는지 계산하는 것이 유일하다.
    enriched_trainingset <-
    enriched_trainingset %>%
    get_common_neighbors() %>%
    mutate(unique_neighbors = degree + degree_to - commonneighbors_1)
    #readr::write_rds(enriched_trainingset, file="data/enriched_trainingset2.Rds")
    
    
    우리는 정면과 부정적인 예 사이에서 이웃과 독특한 이웃이 다르다는 것을 알 수 있다.그래서 앞으로 ML에 도움이 될 거예요!
    enriched_trainingset %>%
    group_by(target) %>%
    summarise(
    avg_neighbors = mean(commonneighbors_1),
    avg_unique_nb = mean(unique_neighbors)
    )
    
    
    `summarise()` ungrouping output (override with `.groups` argument)
    
    
    # A tibble: 2 x 3
    target avg_neighbors avg_unique_nb
    <dbl> <dbl> <dbl>
    1 0 0.108 4.89
    2 1 0.0156 4.18
    
    

    재현성


    작성할 때(이 문서를 작성할 때) 시스템의 상태입니다.* 확장하려면 여기를 클릭**


    sessioninfo::session_info()
    
    
     Session info ─────────────────────────────────────────────────────────────
    setting value
    version R version 4.0.2 (2020-06-22)
    os macOS Catalina 10.15.7
    system x86_64, darwin17.0
    ui RStudio
    language (EN)
    collate en_US.UTF-8
    ctype en_US.UTF-8
    tz Europe/Amsterdam
    date 2020-12-04
     Packages ─────────────────────────────────────────────────────────────────
    package * version date lib source
    assertthat 0.2.1 2019-03-21 [1] CRAN (R 4.0.2)
    blogdown 0.21 2020-10-11 [1] CRAN (R 4.0.2)
    bookdown 0.21 2020-10-13 [1] CRAN (R 4.0.2)
    cli 2.2.0 2020-11-20 [1] CRAN (R 4.0.2)
    crayon 1.3.4 2017-09-16 [1] CRAN (R 4.0.2)
    digest 0.6.27 2020-10-24 [1] CRAN (R 4.0.2)
    dplyr * 1.0.2 2020-08-18 [1] CRAN (R 4.0.2)
    ellipsis 0.3.1 2020-05-15 [1] CRAN (R 4.0.2)
    evaluate 0.14 2019-05-28 [1] CRAN (R 4.0.1)
    fansi 0.4.1 2020-01-08 [1] CRAN (R 4.0.2)
    fastmap 1.0.1 2019-10-08 [1] CRAN (R 4.0.2)
    generics 0.1.0 2020-10-31 [1] CRAN (R 4.0.2)
    glue 1.4.2 2020-08-27 [1] CRAN (R 4.0.2)
    hms 0.5.3 2020-01-08 [1] CRAN (R 4.0.2)
    htmltools 0.5.0 2020-06-16 [1] CRAN (R 4.0.2)
    httpuv 1.5.4 2020-06-06 [1] CRAN (R 4.0.2)
    igraph 1.2.6 2020-10-06 [1] CRAN (R 4.0.2)
    jsonlite 1.7.1 2020-09-07 [1] CRAN (R 4.0.2)
    knitr 1.30 2020-09-22 [1] CRAN (R 4.0.2)
    later 1.1.0.1 2020-06-05 [1] CRAN (R 4.0.2)
    lifecycle 0.2.0 2020-03-06 [1] CRAN (R 4.0.2)
    magrittr 2.0.1 2020-11-17 [1] CRAN (R 4.0.2)
    mime 0.9 2020-02-04 [1] CRAN (R 4.0.2)
    miniUI 0.1.1.1 2018-05-18 [1] CRAN (R 4.0.2)
    pillar 1.4.7 2020-11-20 [1] CRAN (R 4.0.2)
    pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.0.2)
    processx 3.4.4 2020-09-03 [1] CRAN (R 4.0.2)
    promises 1.1.1 2020-06-09 [1] CRAN (R 4.0.2)
    ps 1.4.0 2020-10-07 [1] CRAN (R 4.0.2)
    purrr 0.3.4 2020-04-17 [1] CRAN (R 4.0.2)
    R6 2.5.0 2020-10-28 [1] CRAN (R 4.0.2)
    Rcpp 1.0.5 2020-07-06 [1] CRAN (R 4.0.2)
    readr 1.4.0 2020-10-05 [1] CRAN (R 4.0.2)
    rlang 0.4.9 2020-11-26 [1] CRAN (R 4.0.2)
    rmarkdown 2.5 2020-10-21 [1] CRAN (R 4.0.2)
    rstudioapi 0.13 2020-11-12 [1] CRAN (R 4.0.2)
    servr 0.20 2020-10-19 [1] CRAN (R 4.0.2)
    sessioninfo 1.1.1 2018-11-05 [1] CRAN (R 4.0.2)
    shiny * 1.5.0 2020-06-23 [1] CRAN (R 4.0.2)
    stringi 1.5.3 2020-09-09 [1] CRAN (R 4.0.2)
    stringr 1.4.0 2019-02-10 [1] CRAN (R 4.0.2)
    tibble 3.0.4 2020-10-12 [1] CRAN (R 4.0.2)
    tidygraph * 1.2.0 2020-05-12 [1] CRAN (R 4.0.2)
    tidyr 1.1.2 2020-08-27 [1] CRAN (R 4.0.2)
    tidyselect 1.1.0 2020-05-11 [1] CRAN (R 4.0.2)
    utf8 1.1.4 2018-05-24 [1] CRAN (R 4.0.2)
    vctrs 0.3.5 2020-11-17 [1] CRAN (R 4.0.2)
    withr 2.3.0 2020-09-22 [1] CRAN (R 4.0.2)
    xfun 0.19 2020-10-30 [1] CRAN (R 4.0.2)
    xtable 1.8-4 2019-04-21 [1] CRAN (R 4.0.2)
    yaml 2.2.1 2020-02-01 [1] CRAN (R 4.0.2)
    [1] /Library/Frameworks/R.framework/Versions/4.0/Resources/library
    
    

    정규 표현식에 대한 주석

  • 정규 표현식에 대한 인용은 긴 역사를 가진 것 같아서 깊이 연구한 사람이 있다here
  • 여기 좋은 정규 표현식 조언이 있습니다by Jeff Atwood (@codinghorror) in this post
  • 별도?base::regexp
  • 도구책

  • 내 게시물 더 찾기 intermediate level
  • mygithub에서 Rmarkdown에만 적용되는 조금 다른 버전을 찾았습니다.
  • 이 글의 영감은 analyticsvidhya.com here의 인터넷에 관한 좋은python 글에서 비롯되었다. 이 글은 같은 데이터와 정반 양방면의 예를 사용했지만 즉각 깊이 있게 공부하는 방법을 제시했다.
  • 좋은 웹페이지 즐겨찾기