Neo4jのデータをRで分析する
Neo4j Advent Calendar 2016 12日目
今回は、先日別の記事*1で述べた「せっかくグラフデータなのにNeo4jでグラフ分析/ネットワーク分析はできないね」という問題をお手軽に解決する方法をまとめます。
サンプルとなるデータ(今回はエッジリストで1万行)をNeo4jから取得して、集計したり、簡単なネットワーク分析までです。
抽出:RNeo4j
RからNeo4jを利用するために、RNeo4jというパッケージを利用します。
1つ注意すべきポイントは、RNeo4jで問い合わせる場合、CypherクエリーのRETURN節にノードを指定することができません。
属性(プロパティ)まで指定して問い合わせる必要があります。
RコンソールまたはRStudioのコンソールでの実行例を示します。
> install.packages("RNeo4j") > library(RNeo4j) > graph = startGraph("http://localhost:7474/db/data/", username="Neo4jのユーザー名", password="Neo4jのパスワード") > query = 'MATCH (ad:address)<-[:located]-(au:author)-[:produce]->(s:source) RETURN ad.full_address,ad.country,au.full_name,s.uid,s.title LIMIT 10000' > head(cypher(graph, query)) ad.full_address ad.country au.full_name 1 Univ Reading, Environm Syst Sci Ctr, Reading, Berks, England England Wadge, G. 2 Univ Reading, Environm Syst Sci Ctr, Reading, Berks, England England Wadge, G. 3 Univ Reading, Environm Syst Sci Ctr, Reading, Berks, England England Wadge, G. 4 Univ Reading, Environm Syst Sci Ctr, Reading, Berks, England England Wadge, G. 5 Univ Reading, Environm Syst Sci Ctr, Reading, Berks, England England Wadge, G. 6 Univ Reading, Environm Syst Sci Ctr, Reading, Berks, England England Wadge, G. s.uid s.title 1 WOS:000327299800043 NA 2 WOS:000307431800005 NA 3 WOS:000311842700001 NA 4 WOS:000306981600021 NA 5 WOS:000286851100013 NA 6 WOS:000296402400001 NA > write.csv(cypher(graph, query), “sample.csv") # CSVに出力したいとき > sample.org <- cypher(graph, query) # そのまま処理を進めるとき > colnames(sample.org) <- c ("full_address" ,"country" ,"full_name" ,"uid" ,"title" ) # 名前の変更 > View(sample.org) # データを見たいとき
集計:data.table
今回は data.table にしましたが、data.table でも dplyr でもなんでも良いです。
さほど大きなデータではありませんが、処理が早いに越したことはないかと。
> install.packages("data.table") > library(data.table) data.table 1.9.6 For help type ?data.table or https://github.com/Rdatatable/data.table/wiki The fastest way to learn (by data.table authors): https://www.datacamp.com/courses/data-analysis-the-data-table-way > sample.dt <- data.table(sample.org) > sample.countries <- sample.dt[, .N, by="country"] # 国ごとに集計してみたり > head(sample.countries) country N 1: England 1672 2: Taiwan 525 3: USA 7148 4: Australia 655 > sample.countries <- sample.countries[order(-N)] # 並び替えてみたり > head(sample.countries) country N 1: USA 7148 2: England 1672 3: Australia 655 4: Taiwan 525 > sample.authors <- sample.dt[, .N, by="full_name"] # 著者ごとに集計してみたり > head(sample.authors) full_name N 1: Wadge, G. 38 2: Costa, A. 708 3: Costa, Antonio 48 4: Hodges, Kevin I. 60 5: Mugford, R. I. 3 6: Zahn, Matthias 14 > sample.authors <- sample.authors[order(-N)] # 並び替えてみたり > head(sample.authors) full_name N 1: Jiang, Yi 715 2: Costa, A. 708 3: Singh, K. 681 4: Mason, D. 422 5: Chen, C. Y. 381 6: Kumar, Pankaj 373
分析:igraph
Rのネットワーク分析用パッケージである igraph を使おうとすると、こんな感じになります。
今回のサンプルデータだと正しく分析できるグラフ構造でないので、実行結果は割愛します。
> install.packages("igraph") > library(igraph) > sample.ig <- graph.data.frame(sample.org, directed=F) > graph.density(sample.ig) # 密度 > transitivity(sample.ig) # 推移性
最後に
実はまだRすらも使い始めて間もないので、入門程度にこの辺りをまとめてみました。
ちなみにNeo4jのウェブインターフェイスからCSV出力すると、RETURNにノードを指定した場合、ノードの属性がJSON形式でごっそり出力されます。
ad,au,s "{""zip"":""hoge"",""state"":""hoge"",""full_address"":""hoge"",""country"":""hoge"",""city"":""hoge""}","{""display_name"":""hoge"",""first_name"":""hoge"",""wos_standard"":""hoge"",""email_addr"":"""",""last_name"":""hoge"",""full_name"":""hoge""}","{""uid"":""hoge"",""title_abbrev_11"":""hoge"",""pageend"":""6"",""pagebegin"":""7"",""title_item"":""hoge"",""edition"":""hoge"",""sortdate"":""hoge"",""title_source"":""hoge"",""title_source_abbrev"":""hoge"",""wuid"":""WOS"",""title_abbrev_iso"":""hoge"",""title_abbrev_29"":""hoge"",""pubyear"":""hoge"",""pubtype"":""Journal""}" . . .
これをRでread.csvして、パースして、使用することも可能です。めんどくさくてやっていません。
そんなにたくさんの属性を使わなかったので、RNeo4jで逐一指定して取得してきました。
こんな感じのNeo4j、みなさまも是非活用してノウハウを教えてくださいね。