aukeyR 은 무엇인가?

aukeyR은 Web of Science의 SCI(E) DB에 수록된 저자키워드 데이터로 생성한 임베딩 행렬을 좀 더 쉽게 검색하고자 개발한 초!!! 간단 패키지입니다.

aukeyR 의 기반 데이터

저자키워드 추출 대상은 SCI(E) 에디션에 한정하였으며, 기간은 2000년에서 2020년(24주차으로)이며, 총 31,704,227건의 문헌이 속합니다. 여기에 약간의 정제과정을 거쳐 동 기간 20회 출현빈도를 기준으로 349,785개의 키워드를 선별하였습니다.

  • 저자키워드 수록비율은 주11을 참조하세요.

  • 저자키워드 갯수와 정제과정에 대해서는 주22를 참조하세요.

aukeyR 의 핵심은 위 349,785개 저자키워드 간 co-occurrence 기반 PMI(pointwise mutual information) 행렬에 SVD(Singular Vector Decomposition) 기법을 적용하여 도출한 300차원의 임베딩 행렬입니다. 링크된 행렬의 크기는 약 1기가 정도 됩니다.

Levy & Goldber(2014)에 따르면, SVD 기법을 적용한 임베딩 결과는 word2vec과 매우 유사한 결과를 산출합니다. 특히 저자키워드의 경우에는 word2vec에서와 같은 일정 window 구간에서의 탐색과정이 전혀(!) 필요하지도, 가능하지도 않습니다. 따라서 SVD기법에 기반한 임베딩 행렬을 산출하는 것이 논리적으로도 명쾌합니다.

  • PMI 값에 대한 SVD 기반의 단어 임베딩에 대해서는 주33을 참조하세요.

aukeyR 패키지 설치

aukeyR 패키지파일을 다운로드합니다.

이어서 아래와 같이 설치하고, 패키지를 불러옵니다.

install.packages("aukeyR_0.1.0.zip", repos=NULL, type="binary")
library(aukeyR)

활용1 : 유사 키워드 탐색

먼저 앞에서 받은 임베딩 행렬을 불러옵니다. 용량이 크므로 약간 시간이 걸립니다.

embedding_matrix <- readRDS("embedding_matrix_scaled_202024.rds")

deep_search 함수를 이용하여 자신이 찾고자 하는 단어와 유사한 단어를 탐색합니다.

result <-
  deep_search(plus_word = "DEEP LEARNING", 
              scaled_matrix = embedding_matrix)

“DEEP LEARNING” 과 유사한 키워드들이 유사도(cosine) 순서대로 출력이 됨을 알 수 있습니다.

출력되는 범위를 지정하고 싶으면 deep_search 함수에서 nthreshold 인자를 조정하면 됩니다. n100이 기본값으로 지정되어 있습니다. threshold를 지정하면 n 값은 무시됩니다. 아래는 유사도 값의 최소 기준을 0.5로 지정한 사례입니다.

result <-
  deep_search(plus_word = "DEEP LEARNING",
              threshold = 0.5,
              scaled_matrix = embedding_matrix)

단어 임베딩의 꽃은 아무래도 단어 벡터 간의 연산이 가능하다는 점일 겁니다. 프랑스 벡터에 독일 벡터를 더하고 파리 벡터를 빼면, 유사한 단어로 베를린을 출력한다는 사례는 많이 접하셨을 겁니다.

저자 키워드에서 위와 같은 ‘국가-수도’ 같은 사례가 나오기는 어려워 보이지만, 어쨌든 deep_search함수는 단어 벡터 연산을 지원합니다. plus에 해당하는 단어들을 plus_word 인자에 문자 벡터로, 마이너스에 해당하는 단어들을 minus_word 인자에 문자 벡터로 입력하면 됩니다.

딥러닝은 이미지 처리와 관련된 영역이 가장 주류이므로, 텍스트 처리와 관련된 단어는 상대적으로 상위에 잘 안보이는 듯하니, 단어 벡터 연산을 한번 해봅니다. “DEEP LEARNING”에 “NATURAL LANGUAGE PROCESSING”을 더해봅니다.

res <- deep_search(plus_word = 
                     c("DEEP LEARNING", "NATURAL LANGUAGE PROCESSING"),
                   n = 100, 
                   scaled_matrix = embedding_matrix)

결과가 어떤가요? 제법 그럴듯해 보입니다.

또 다른 사례로 검색해보겠습니다.

res <- deep_search(plus_word = 
                     c("BUTANOL", "FERMENTATION"),
                   n = 100, 
                   scaled_matrix = embedding_matrix)

“BUTANOL”과 “FERMENTATION”을 조합한 벡터와 유사한 단어들을 탐색할 수 있습니다. 결과가 나쁘지는 않아 보입니다.

활용2: 유사도 행렬 생성

앞서 활용1에서 설명한 deep_search 함수는 검색 단어를 중심으로 검색 단어와 유사도가 높은 단어들의 목록과 유사도 값을 제공합니다. 이 결과를 갖고 검색 단어를 중심으로 한 ego network는 생성할 수 있지만, 단어 간 유사도에 기반한 매핑은 할 수 없겠죠.

이를 위해 create_sim_matrix가 있습니다. 이 함수는 활용1에서 저장한 단어 목록을 집어 넣으면 그 목록에 있는 단어들 간의 유사도를 결과로 산출합니다. 결과 제공 형태는 type인자에서 dataframe (기본), matrix, pair 세 가지 중 하나를 고를 수 있습니다. dataframematrix는 사실상 둘 다 행렬 형태이나, 오브젝트의 class가 이름과 같이 다릅니다. dataframe은 사실 data.table 패키지의 클래스입니다. pair 는 행렬형태를 단어 쌍별로 값을 부여한 형태이고, class는 data.table입니다.

dt_list <- deep_search(plus_word = 
                     c("DEEP LEARNING", "NATURAL LANGUAGE PROCESSING"),
                   n = 100, 
                   scaled_matrix = embedding_matrix)
res_sim <- create_sim_matrix(word_set = dt_list$word,
                             scaled_matrix = embedding_matrix,
                             type = "pair")

이 결과는 그대로 VOSviewer 같은 곳에 집어 넣어 활용할 수 있을 것입니다.

활용3: 키워드 추세 탐색

aukeyR 패키지의 핵심 데이터인 임베딩 행렬과 함께 제공되는 데이터는 349,785개 키워드 각각에 대한 추세 관련 정보입니다. 임베딩 행렬 생성에는 2020년에서 24주차까지의 데이터가 포함되었지만, 추세 데이터에는 2000-2019년, 총 20년만 고려하였습니다. 키워드 빈도가 발생하지 않은 년도는 0값을 채워 넣었습니다. 정리한 데이터는 아래 3개 입니다.

년도별 빈도 데이터 는 표현 그대로, 년도별 단순 빈도수만 집어 넣은 것이라서, 나중에 특정 키워드의 추세 그래프를 그릴 때 활용될 수 있을 것입니다.

다음으로 총괄 추세 지표 데이터에는 각 단어별로 30개 변수가 들어 있습니다. 꽤 많아 보이지만 실제로는 퍼센타일(백분위수)을 계산하기 위한 중간 과정을 남겨 둔 것입니다. 아래 변수 설명을 보면 전체 유형이 파악되실 겁니다.

순위 계산은 “average” 방식을 적용하였고, 퍼센타일의 값 1은 순위 상위 1%를 의미합니다.

추세 지표 변수 설명

    1. slope_20yrs : 년도별 빈도 기준, 20년(2000-2019) 회귀모형 기울기
    1. slope_10yrs : 년도별 빈도 기준, 10년(2010-2019) 회귀모형 기울기
    1. ratio_p1p2 : 2기(2015-2019) 빈도합과 1기(2010-2014) 빈도합의 비율 (total_p2/total_p1)
    1. slope_share_20yrs : 년도별 점유율 기준, 20년(2000-2019) 회귀모형 기울기
    1. slope_share_10yrs : 년도별 점유율 기준, 10년(2010-2019) 회귀모형 기울기
    1. ratio_share_p1p2 : 2기(2015-2019) 점유율과 1기(2010-2014) 점유율의 비율 (share_p2/share_p1)
    1. total_p1 : 1기(2010-2014) 빈도의 합계
    1. total_p2 : 2기(2015-2019) 빈도의 합계
    1. share_p1 : 1기(2010-2014) 점유율 (해당 단어 빈도 합계 / 전체 빈도 합계)
    1. share_p2 : 2기(2015-2019) 점유율 (해당 단어 빈도 합계 / 전체 빈도 합계)
    1. slope_20yrs_rank : 1)번 순위
    1. slope_10yrs_rank : 2)번 순위
    1. ratio_p1p2_rank : 3)번 순위
    1. slope_share_20yrs_rank : 4)번 순위
    1. slope_share_10yrs_rank : 5)번 순위
    1. ratio_share_p1p2_rank : 6)번 순위
    1. total_p1_rank : 7)번 순위
    1. total_p2_rank : 8)번 순위
    1. share_p1_rank : 9)번 순위
    1. share_p2_rank : 10)번 순위
    1. slope_20yrs_rank_pr : 11)번 순위의 퍼센타일 (1은 상위 1% 의미)
    1. slope_10yrs_rank_pr : 12)번 순위의 퍼센타일
    1. ratio_p1p2_rank_pr : 13)번 순위의 퍼센타일
    1. slope_share_20yrs_rank_pr : 14)번 순위의 퍼센타일
    1. slope_share_10yrs_rank_pr : 15)번 순위의 퍼센타일
    1. ratio_share_p1p2_rank_pr : 16)번 순위의 퍼센타일
    1. total_p1_rank_pr : 17)번 순위의 퍼센타일
    1. total_p2_rank_pr : 18)번 순위의 퍼센타일
    1. share_p1_rank_pr : 19)번 순위의 퍼센타일
    1. share_p2_rank_pr : 20)번 순위의 퍼센타일

이제 위 변수들 중에 의미있다고 생각되는 것들을 탐색결과로 얻은 단어들에 붙이면 되겠습니다. VOSviewerOverlay Mapping에 활용하여도 좋겠고, 탐색결과의 심화분석, 단어들의 선별 등에 활용할 수도 있을 것입니다.

여기서는 위 변수들 중에 몇 가지를 조합하여 최근 5년에 급속히 떠오른 키워드를 추려보겠습니다.

먼저 데이터를 불러옵니다.

dt_dynamics <- fread("aukey_dynamics_indicator_202024.txt", encoding = "UTF-8")

1기(2010-2014년)와 2기(2015-2019)의 비율이 상위 2% 이내이며, 2기에서의 점유율도 상위 2%인 것을 추려봅니다. 기준으로는 퍼센타일 값을 적용합니다. 아무래도 해당 키워드들은 극도의 비대칭 분포를 갖게 되므로, 별다른 이유가 아니라면 퍼센타일 값을 기준으로 선별하는 것이 적절하다고 보입니다.

res <- dt_dynamics[ratio_share_p1p2_rank_pr <= 2 &
                 share_p2_rank_pr <= 2 , 
                 .(word, ratio_share_p1p2, share_p2_rank_pr)]

결과가 어떤가요? 이 두가지 기준으로만 추출해도 지난 10년 동안 뜨겁게 달구던 키워드들이 수두룩 하게 나오네요. ratio_share_p1p2 변수가 0인 것은 1기에 아예 값이 0이었다는 것을 의미합니다.

앞으로 할 일

aukeyR의 핵심 데이터인 임베딩 행렬추세 지표는 주기적으로 생성하겠다고 장담할 수는 없지만, 적절한 시기에 업데이트를 진행해 나가겠습니다. 그리고 시간이 되면, VOSviewer에 바로 넣을 수 있는 파일을 생성해 주는 함수도 추가할 예정입니다.

주석


  1. 저자키워드가 모든 문헌에 수록된 것은 아니며, 16,942,511건 약 53.4% 만 달려있습니다. 동 기간 SCI(E)의 문헌유형이 Article에 해당하는 문헌은 총 22,330,938건이며 이중 저자키워드가 수록된 것은 15,470,243건으로 약 69.3%에 달합니다. 저자키워드 수록비율은 Web of Science Category별로도 크게 차이가 납니다. 범주별 수록비율을 보면, SCI(E), SSCI, AHCI 3대 에디션 2000-2020년 36,548,485건에서 저자키워드 수록비율은 최대 98.3%에서 최소 0.006%로 극단적으로 차이가 나며, 분야별 수록비율의 평균은 80.3%, 중앙값은 86.8%, Q1은 77.1%, Q3는 92.3%입니다. 앞서 전체를 단순 평균한 수치와 비교하여 대폭 올라간 것을 알 수 있습니다.↩︎

  2. 저자키워드의 정제 과정은 1) 앞뒤 공백 + 연속공백 제거 2) 대문자 변환 3) 문자+숫자 이외는 공백으로 변환 4) 앞뒤 공백 + 연속공백 제거 5) 숫자로만 구성된 키워드 제거와 같습니다. 단수와 복수를 통일하는 것은 정확도도 낮을 뿐만 아니라, 단수와 복수의 시계열 변동도 매우 의미있는 정보인 경우가 많으므로 그대로 두었습니다. 2000-2020년(24주차) 기간 3개 에디션에서 수록된 고유한 저자키워드 갯수는 13,965,990개이며, 정제 과정을 거치면 11,118,752개로 약 284만 건이 정제과정을 거치며 동일하게 처리됩니다. 정제된 기준으로 하면, 최종 분석대상 349,785개는 전체 저자키워드의 약 3.15%에 해당합니다.↩︎

  3. 긴 문서에서 단어 간의 PMI 측정은 일정 길이의 window를 하나의 단위로 놓고 측정한 co-occurrence 정보를 이용하게 되는데, 저자키워드의 경우에는 문헌 단위가 곧 window에 해당됩니다. Levy & Goldberg(2014)에 대한 간략한 설명은 Chris Moody(2017)의 글이 좋습니다.↩︎