PubMedからダウンロードしたXMLファイルの操作方法 (巨大な場合)

検索結果のダウンロード

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

データ(PMID、アブストラクト)を取得

using System;
using System.Text;
using System.Xml.Linq;
using System.IO;
using System.Diagnostics;
using System.Xml;
using System.Collections.Generic;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("ファイル名を入力してください");
            string s;
            s = Console.ReadLine();

            Stopwatch watch = new Stopwatch();
            watch.Start();

            using (StreamWriter sw = new StreamWriter("PMID.txt", false, Encoding.GetEncoding("shift_jis")))
            {
                foreach (XElement el in mystream(s))
                {
                    sw.WriteLine(el.Element("MedlineCitation").Element("PMID").Value);
                }
            }

            using (StreamWriter sw2 = new StreamWriter("Absts.txt", false, Encoding.GetEncoding("shift_jis")))
            {
                foreach (XElement el2 in mystream(s))
                {
                    string Absts = "";
                    foreach(XElement x2 in el2.Descendants("AbstractText"))
                    {
                        Absts = Absts + x2.Value;
                    }
                    sw2.WriteLine(Absts);
                }
            }
            watch.Stop();

            Console.WriteLine("経過時間の合計 = {0}", watch.Elapsed);
            Console.ReadLine();
        }

        static IEnumerable<XElement> mystream(string file_name)
        {
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.DtdProcessing = DtdProcessing.Parse;

            using (XmlReader reader = XmlReader.Create(file_name, settings))
            {
                while (reader.Read())
                {
                    if (reader.Name == "PubmedArticle")
                    {
                        yield return XElement.ReadFrom(reader) as XElement;
                    }
                }
            }
        }
    }
}

以下は参考までに過去記事のコピー(1)

using System;
using System.Linq;
using System.Windows.Forms;
using System.Xml.Linq;

結合

XDocument xdoc1 = XDocument.Load("http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&mode=XML&id=14993493");
XDocument xdoc2 = XDocument.Load("http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&mode=XML&id=15919696");
xdoc1.Element("PubmedArticleSet").Add(xdoc2.Element("PubmedArticleSet").Element("PubmedArticle"));
xdoc1.Save("merge_file.xml");

消去

XDocument doc = XDocument.Load("http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&mode=XML&id=14993493+15919696+21974702+21303965");
var n = doc.Element("PubmedArticleSet").Elements("PubmedArticle").ToArray();
foreach(XElement d in n){ 
if (d.Element("MedlineCitation").Element("PMID").Value == "21974702") 
{ 
d.Remove(); 
} 
}
doc.Save("removo_file.xml");


新規作成

XDocument doc = new XDocument(); XElement rootElem = new XElement("PubmedArticleSet");
doc.Add(rootElem);
doc.Save("newfile.xml");


XSLファイルと関連付ける

XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("myxslt.xsl");
xslt.Transform("sample.xml", "sample.html");

以下は参考までに過去記事のコピー(2)

文献数を確認する

using System.Xml.Linq; 
XDocument xdoc = XDocument.Load("pubmed_result.xml"); 
MessageBox.Show(xdoc.Descendants("PMID").Count().ToString()); 

IDを表示する

using System.Xml.Linq; 
XDocument xdoc = XDocument.Load("pubmed_result.xml");
foreach (var xid in xdoc.Descendants("PMID")) { MessageBox.Show(xid.Value); }

C#でXML操作、その後にtext2vecでTF-IDFを作成

PubMed検索

検索式

"kidney diseases"[MeSH Terms] AND "english"[Language] AND ("2015/1/1"[PDAT] : "2017/12/31"[PDAT])

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

データ(PMID、アブストラクト)を取得

ここの部分は速度重視でC#を使用

using System;
using System.Text;
using System.Xml.Linq;
using System.IO;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("ファイル名を入力してください");
            string s;
            s = Console.ReadLine();

            Stopwatch watch = new Stopwatch();
            watch.Start();

            XDocument doc = XDocument.Load(s);
            var n = doc.Element("PubmedArticleSet").Elements("PubmedArticle");

            StreamWriter sw = new StreamWriter("PMID.txt", false, Encoding.GetEncoding("shift_jis"));
            foreach (XElement x in n)
            {
                sw.WriteLine(x.Element("MedlineCitation").Element("PMID").Value);
            }
            sw.Close();

            StreamWriter sw2 = new StreamWriter("Absts.txt", false, Encoding.GetEncoding("shift_jis"));
            foreach (XElement x in n)
            {
                string Abst = "";
                foreach (XElement x2 in x.Descendants("AbstractText"))
                {
                    Abst = Abst + x2.Value;
                }
                sw2.WriteLine(Abst);
            }
            sw2.Close();

            watch.Stop();
            Console.WriteLine("経過時間の合計 = {0}", watch.Elapsed);
            Console.ReadLine();
        }
    }
}

ファイルが大きい場合にはこちらも参照
touch-sp.hatenablog.com

前処置

#ストップワードを決める
library(tm)
new_stopwords <- c(stopwords("en"), "also", "however")
saveRDS(new_stopwords, "new_stopwords")

TF-IDFの作成

library(text2vec)

#データの読み込み
new_stopwords <- readRDS("new_stopwords")
Absts <- readLines("Absts.txt")
pmid <-  readLines("PMID.txt")

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

it <- itoken(Absts, tolower, word_tokenizer, ids = pmid)
voc <- create_vocabulary(it, stopwords = new_stopwords)
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)

文献アブストラクトから作成した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次スクリーニングは精度の問題はあるにせよこれで良いような気がする。
きっちりとクラス分け(クラスター分類?)する必要はまったくない。

GloVe Word Embeddingsを試してみる(2)日本語に挑戦

パソコンで楽しむ自分で動かす人工知能

パソコンで楽しむ自分で動かす人工知能

上記に書かれていることをMeCabとRとtext2vecパッケージを使って実行。


<環境>

> 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’

【0】使用するライブラリの読み込み

library(text2vec)

【1】データの取得と前処置

download.file("http://www.aozora.gr.jp/cards/000148/files/752_ruby_2438.zip", "752.zip")
file_name <- unzip("752.zip")
text <- readLines(file_name, warn = FALSE)
> text[527:538]
 [1] "底本:「ちくま日本文学全集 夏目漱石」筑摩書房"                                                                                                                                            
 [2] "   1992(平成4)年1月20日第1刷発行"                                                                                                                                                     
 [3] "底本の親本:「夏目漱石全集2」ちくま文庫、筑摩書房"                                                                                                                                         
 [4] "   1987(昭和62)年10月27日第1刷発行"                                                                                                                                                   
 [5] "※底本の注にれば、本作品の原稿には、「そのうち学校もいやになった。」の後に、漱石自身による2字あけの指定があるという。このファイルでは、その情報にもとづいて、当該の箇所を2字あけとした。"
 [6] "※底本は、物を数える際や地名などに用いる「ヶ」(区点番号5-86)を、大振りにつくっています。"                                                                                                
 [7] "入力:真先芳秋"                                                                                                                                                                            
 [8] "校正:柳沢成雄"                                                                                                                                                                            
 [9] "1999年9月13日公開"                                                                                                                                                                         
[10] "2011年5月20日修正"                                                                                                                                                                         
[11] "青空文庫作成ファイル:"                                                                                                                                                                    
[12] "このファイルは、インターネットの図書館、青空文庫(http://www.aozora.gr.jp/)で作られました。入力、校正、制作にあたったのは、ボランティアの皆さんです。" 
#末尾の削除
text <- text[-c(527:538)]
> text[1:15]
 [1] "坊っちゃん"                                             
 [2] "夏目漱石"                                               
 [3] ""                                                       
 [4] "-------------------------------------------------------"
 [5] "【テキスト中に現れる記号について】"                     
 [6] ""                                                       
 [7] "《》:ルビ"                                             
 [8] "(例)坊《ぼ》っちゃん"                                 
 [9] ""                                                       
[10] "|:ルビの付く文字列の始まりを特定する記号"             
[11] "(例)夕方|折戸《おりど》の"                           
[12] ""                                                       
[13] "[#]:入力者注 主に外字の説明や、傍点の位置の指定"   
[14] "(例)おくれんかな[#「おくれんかな」に傍点]"         
[15] "-------------------------------------------------------"
#冒頭の削除
text <- text[-c(1:15)]
> subset(text, grepl("^[#", text))
 [1] "[#]:入力者注 主に外字の説明や、傍点の位置の指定"
 [2] "[#5字下げ]一[#「一」は中見出し]"              
 [3] "[#5字下げ]二[#「二」は中見出し]"              
 [4] "[#5字下げ]三[#「三」は中見出し]"              
 [5] "[#5字下げ]四[#「四」は中見出し]"              
 [6] "[#5字下げ]五[#「五」は中見出し]"              
 [7] "[#5字下げ]六[#「六」は中見出し]"              
 [8] "[#5字下げ]七[#「七」は中見出し]"              
 [9] "[#5字下げ]八[#「八」は中見出し]"              
[10] "[#5字下げ]九[#「九」は中見出し]"              
[11] "[#5字下げ]十[#「十」は中見出し]"              
[12] "[#5字下げ]十一[#「十一」は中見出し]"          
[13] "[#地から1字上げ](明治三十九年四月)"
#不要な行の削
text <- subset(text, !grepl("^[#", text))
#ルビの削除
text <- gsub("《[^》]*》", "", text)

【2】単語を抽出する

コマンドプロンプトで以下を実行

mecab -Owakati -b 200000 text.txt > out.txt

bコマンドで適当に大きめの数字を割り当てないと以下のエラーがでる

input-buffer overflow. The line is split. use -b #SIZE option.

いよいよ単語の抽出

text <- readLines("out.txt", warn = FALSE)
it <- itoken(text)
voc <- create_vocabulary(it)
voc <- prune_vocabulary(voc, term_count_min = 5)

【3】TCM(term-co-occurence matrix)を作成する

tcm <- create_tcm(it, vocab_vectorizer(voc), skip_grams_window = 5)

【4】ワードベクトルを作成する

glove <- GlobalVectors$new(word_vectors_size = 50, vocabulary = voc, x_max = 10)
main <- glove$fit_transform(tcm, n_iter = 20)
context <- glove$components
word_vectors <- main + t(context)
#文字コードの変換
rownames(word_vectors) <- iconv(rownames(word_vectors), "cp932")

GloVe Word Embeddingsを試してみる

ほとんどマニュアル通りに行っただけ。
GloVe Word Embeddings

<環境>

> 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’

【0】使用するライブラリの読み込み

library(text2vec)

【1】データの取得と読み込み

download.file("http://mattmahoney.net/dc/text8.zip", "text8.zip")
unzip("text8.zip", "text8")
text8 <- readLines("text8", warn = FALSE)

【2】単語を抽出する

it <- itoken(text8)
voc <- create_vocabulary(it)
voc <- prune_vocabulary(voc, term_count_min = 5)
> voc
Number of docs: 1 
0 stopwords:  ... 
ngram_min = 1; ngram_max = 1 
Vocabulary: 
              term term_count doc_count
    1:   kentauros          5         1
    2:   tornatore          5         1
    3: phantastica          5         1
    4:   steinhoff          5         1
    5:      minthe          5         1
   ---                                 
71286:          in     372201         1
71287:         one     411764         1
71288:         and     416629         1
71289:          of     593677         1
71290:         the    1061396         1

【3】TCM(term-co-occurence matrix)を作成する

tcm <- create_tcm(it, vocab_vectorizer(voc), skip_grams_window = 5)

【4】ワードベクトルを作成する

glove <- GlobalVectors$new(word_vectors_size = 50, vocabulary = voc, x_max = 10)
main <- glove$fit_transform(tcm, n_iter = 20)
context <- glove$components
word_vectors <- main + t(context)

【5】うまくいっているか試してみる(paris - france + germany)

paris <- word_vectors["paris",, drop = FALSE]
france <- word_vectors["france",, drop = FALSE]
germany <- word_vectors["germany",, drop = FALSE]

answer <- paris - france + germany

cos_sim <- sim2(x = word_vectors, y = answer, method = "cosine", norm = "l2")
head(sort(cos_sim[,1], decreasing = TRUE), 5)
   berlin     paris    munich   germany    vienna 
0.7652117 0.7228930 0.6976820 0.6499416 0.6340590 

文献のアブストラクトを取得してTF-IDFを作成する(2)

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


<環境>

> 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’

【0】使用するライブラリの読み込み

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

【1】データ(文献のアブストラクト)を取得する

myXML <- read_xml("pubmed_result.xml")

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

pmid <- sapply(pubmedarticle, function(a){a %>% xml_find_first(".//MedlineCitation/PMID") %>% xml_text})

getAbst <- function(mynode) {
    
    return(mynode %>% xml_find_all(".//AbstractText") %>% xml_text() %>% paste(collapse = " "))
}

Absts <- sapply(pubmedarticle, getAbst)
Absts <- removeNumbers(Absts)

【2】単語を抽出する

it <- itoken(Absts, tolower, word_tokenizer, ids = pmid)

voc <- create_vocabulary(it, stopwords = stopwords("en"), ngram = c(1L, 3L))
voc <- prune_vocabulary(voc, doc_count_min = 2L)
> head(voc[order(voc$term_count, decreasing = T),], n = 20)
Number of docs: 454 
174 stopwords: i, me, my, myself, we, our ... 
ngram_min = 1; ngram_max = 3 
Vocabulary: 
              term term_count doc_count
 1:       patients       1458       301
 2:            ckd       1409       228
 3:        disease       1076       403
 4:           risk        993       321
 5:              p        845       237
 6:          renal        722       294
 7:            age        664       357
 8:     associated        657       309
 9:        smoking        652       451
10:         kidney        615       297
11:          study        563       325
12:       diabetes        549       290
13:          years        534       282
14:        factors        497       238
15:             ci        487       143
16:        chronic        464       306
17:           egfr        429       116
18: kidney_disease        427       275
19: cardiovascular        411       191
20:           esrd        391        82

【3】DTM(Document-Term-Matrix)を作成する

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

【4】TF-IDF(Term Frequency-Inverse Document Frequency)を作成する

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

TF-IDFの補足

パターン1

model_tfidf = TfIdf$new()
dtm_tfidf = model_tfidf$fit_transform(dtm)
> dtm[15, 12947, drop = F]
1 x 1 sparse Matrix of class "dgCMatrix"
         disease
27559974       3
> dtm_tfidf[15, 12947, drop = F]
1 x 1 sparse Matrix of class "dgCMatrix"
             disease
27559974 0.001320932

0.0013209319がどのような式で計算されているかを探ってみた。

> (3 * log(454 / (403 + 1))) / sum(dtm["27559974",])
[1] 0.001320932


パターン2

model_tfidf = TfIdf$new(norm = "none")
dtm_tfidf = model_tfidf$fit_transform(dtm)
> dtm[15, 12947, drop = F]
1 x 1 sparse Matrix of class "dgCMatrix"
         disease
27559974       3
> dtm_tfidf[15, 12947, drop = F]
1 x 1 sparse Matrix of class "dgCMatrix"
          disease
27559974 0.350047
> (3 * log(454 / (403 + 1)))
[1] 0.350047


パターン3

model_tfidf = TfIdf$new(smooth_idf = FALSE)
dtm_tfidf = model_tfidf$fit_transform(dtm)
> dtm[15, 12947, drop = F]
1 x 1 sparse Matrix of class "dgCMatrix"
         disease
27559974       3
> dtm_tfidf[15, 12947, drop = F]
1 x 1 sparse Matrix of class "dgCMatrix"
             disease
27559974 0.001348988
> (3 * log(454 / 403)) / sum(dtm["27559974",])
[1] 0.001348988


パターン4

model_tfidf = TfIdf$new(sublinear_tf = TRUE, norm = "none")
dtm_tfidf = model_tfidf$fit_transform(dtm)
> dtm[15, 12947, drop = F]
1 x 1 sparse Matrix of class "dgCMatrix"
         disease
27559974       3
> dtm_tfidf[15, 12947, drop = F]
1 x 1 sparse Matrix of class "dgCMatrix"
          disease
27559974 0.244871
> ((log(3) + 1) * log(454 / (403 + 1)))
[1] 0.244871


うまくいっているような、いっていないような・・・。
さてさてここからどうしよう?

文献のアブストラクトを取得して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’

【0】使用するライブラリの読み込み

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

【1】データ(文献のアブストラクト)を取得する

address <- "http://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&mode=XML&id="

pubmedID <- c("25458663", "26200944", "27118687")

getAbst <- function(pmid) {
    myXML <- read_xml(paste(address, pmid, sep = ""))
    return(myXML %>% xml_find_all(xpath = "//AbstractText") %>% xml_text() %>% paste(collapse = " "))
}

Absts <- sapply(pubmedID, getAbst)
Absts <- stemDocument(Absts, "en")
Absts <- removeNumbers(Absts)

【2】単語を抽出する

it <- itoken(Absts, tolower, word_tokenizer)
voc <- create_vocabulary(it, stopwords = stopwords("en"))
> head(voc[order(voc$term_count, decreasing = T),], n = 20)
Number of docs: 3 
174 stopwords: i, me, my, myself, we, our ... 
ngram_min = 1; ngram_max = 1 
Vocabulary: 
              term term_count doc_count
 1:             ci         22         2
 2:            ckd         17         3
 3:        current         13         3
 4:             rr         12         1
 5:              m         12         3
 6:           risk         11         3
 7:         smoker         11         3
 8:             kg         10         1
 9:           caus          9         3
10: cardiovascular          8         2
11:         diseas          8         3
12:         associ          8         2
13:         events          8         2
14:           rate          7         3
15:          smoke          7         2
16:          never          7         2
17:             hr          6         1
18:            bmi          6         1
19:             vs          6         1
20:       lifestyl          6         1

【3】DTM(Document-Term-Matrix)を作成する

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

【4】TF-IDF(Term Frequency-Inverse Document Frequency)を作成する

model_tfidf = TfIdf$new()
dtm_tfidf = model_tfidf$fit_transform(dtm)


うまくいっているような、いっていないような・・・。
さてさてここからどうしよう?