文献アブストラクトから作成したTF-IDFを使って似たような文献を探してみる

<環境>

> sessionInfo()
R version 3.4.2 (2017-09-28)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 16299)

Matrix products: default

locale:
[1] LC_COLLATE=Japanese_Japan.932  LC_CTYPE=Japanese_Japan.932   
[3] LC_MONETARY=Japanese_Japan.932 LC_NUMERIC=C                  
[5] LC_TIME=Japanese_Japan.932    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods  
[7] base     

other attached packages:
[1] RevoUtils_10.0.6     RevoUtilsMath_10.0.1

loaded via a namespace (and not attached):
[1] compiler_3.4.2 tools_3.4.
> packageVersion("text2vec")
[1] ‘0.5.0’
> packageVersion("xml2")
[1] ‘1.1.1’
> packageVersion("dplyr")
[1] ‘0.7.4’
> packageVersion("tm")
[1] ‘0.7.1’

使用するライブラリ

library(text2vec)
library(xml2)
library(dplyr)
library(tm)

PubMed検索

検索式

(renal insufficiency chronic) AND ("2015/1/1"[Date - Publication] : "2017/12/31"[Date - Publication]) 

PubMedから検索結果をXMLフォーマットでダウンロード。
検索結果をダウンロードするには、検索結果ページの右上にある「Send to」をクリック、「File」を選択し、Formatを「XML」にして「Create File」をクリック。
pubmed_result.xml」という名前のファイルがダウンロードされる。

Rのスクリプト

myXML <- read_xml("pubmed_result.xml")

pmid <- myXML %>% xml_find_all("//PubmedArticle/MedlineCitation/PMID") %>% xml_text()

pubmedarticle <- myXML %>% xml_find_all("//PubmedArticle")

Absts <- NULL

for (i in 1:length(pubmedarticle)) {
    Absts <- c(Absts, pubmedarticle[i] %>% xml_find_all(".//AbstractText") %>% xml_text() %>% paste(collapse = ""))
}

#アブストラクトがない文献を除く
no_Absts <- Absts == ""
Absts <- Absts[!no_Absts]
pmid <- pmid[!no_Absts]

Ab <- gsub("end stage renal disease", "ESRD", Absts)
Ab <- gsub("chronic kidney disease", "CKD", Ab)

it <- itoken(Ab, tolower, word_tokenizer, ids = pmid)
voc <- create_vocabulary(it, stopwords = stopwords("en"))
voc <- prune_vocabulary(voc, doc_count_min = 2)
voc <- voc[!grepl("^[0-9]*$", voc$term),]

dtm <- create_dtm(it, vocab_vectorizer(voc))

model_tfidf = TfIdf$new(smooth_idf = FALSE, sublinear_tf = TRUE, norm = "l1")
dtm_tfidf = model_tfidf$fit_transform(dtm)

answer <- dtm_tfidf["26200944",, drop = FALSE]
cos_sim <- sim2(x = dtm_tfidf, y = answer, method = "cosine", norm = "l2")
head(sort(cos_sim[, 1], decreasing = TRUE), 6)

実行結果(上位5つのみ)

 26200944  27118687  28339863  27456350  27225196  25407760 
1.0000000 0.3702279 0.3561138 0.3188950 0.2966631 0.2569545 

結果の確認

title <- function(pmid) {
    address <- "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&mode=XML&id="
    myXML <- read_xml(paste(address, pmid, sep = ""))
    return(myXML %>% xml_find_first(xpath = "//ArticleTitle") %>% xml_text())
}
result <- head(sort(cos_sim[, 1], decreasing = TRUE), 6)
titles <- sapply(names(result), title)
sprintf(titles)

TogoWSを使うと次のようにも書ける。

library(RCurl)
title <- function(pmid) {
    myURL <- paste0("http://togows.org/entry/pubmed/", pmid, "/title")
    return(getURL(myURL))
}
result <- head(sort(cos_sim[, 1], decreasing = TRUE), 6)
titles <- sapply(names(result), title)
titles <- gsub("\n", "", titles)
sprintf(titles)
[1] "Smoking increases the risk of all-cause and cardiovascular mortality in patients with chronic kidney disease."                                
[2] "Smoking and Adverse Outcomes in Patients With CKD: The Study of Heart and Renal Protection (SHARP)."                                          
[3] "Cigarette smoking and chronic kidney disease in the general population: a systematic review and meta-analysis of prospective cohort studies." 
[4] "Differential impact of smoking on mortality and kidney transplantation among adult Men and Women undergoing dialysis."                        
[5] "Cigarette Smoking and Chronic Kidney Disease in African Americans in the Jackson Heart Study."                                                
[6] "Different association of cigarette smoking with GFR estimated from serum creatinine and that from serum cystatin C in the general population."

CKDとタバコと予後に関する文献が抽出されているので結果はまずまず。と言うか上出来、少し感動。
Deep Learning使ってません!!使いたいけど使いどころがよくわからない・・・。


ガイドライン作成時の1次スクリーニングは精度の問題はあるにせよこれで良いような気がする。
きっちりとクラス分け(クラスター分類?)する必要はまったくない。