ルーズリーフ

公私におよぶ経験値獲得履歴的ななにか。

Neo4jのデータをRで分析する

Neo4j Advent Calendar 2016 12日目

qiita.com

今回は、先日別の記事*1で述べた「せっかくグラフデータなのにNeo4jでグラフ分析/ネットワーク分析はできないね」という問題をお手軽に解決する方法をまとめます。
サンプルとなるデータ(今回はエッジリストで1万行)をNeo4jから取得して、集計したり、簡単なネットワーク分析までです。

抽出:RNeo4j


CRAN - Package 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、みなさまも是非活用してノウハウを教えてくださいね。

いまのNeo4jの使いどころ

GeekWomenJapan Advent Calendar 2016 5日目

qiita.com

最近触り始めたグラフデータベースのNeo4j。
実際に利用している中で得た、いまのNeo4jの使いどころについてです。
主には、気になっていたけどさてどんな目的で提案しよう...なんて思っていた方向け。
いちおう簡単な紹介も書きますが、なにこれ知らなかったけど面白い!という方は、ググって他の方の記事をお読みいただく方がきっと適切です。
数年前にも一度流行っていたので、日本語の記事も結構ありますし分かりやすいと思います。

1.グラフデータベース?Neo4j?


www.creationline.com

qiita.com

要するに、データをグラフ(ネットワーク)の形でCRUDできるデータベースです。
現状、グラフ"データベース"といえば使うならOSSだしNeo4jかなー、となりがちな印象。
Oracle にも Oracle Labs PGX がありますが、日本では本当にこれから、といった感じです。

Oracle Labs PGX: Parallel Graph Analytics Overview

ちなみにグラフ"分析"ならSparkのGraphXなどなどあります。

Neo4jはいわゆるデータ(ex.会社や社員) をノード、ノードとノードの関係(ex.所属している、上司、部下)をリレーションシップとして保持します。
ノードが"頂点"、リレーションシップが"エッジ"や"枝"と言われるものに相当します。
ノードやリレーションシップにはラベルがありいろいろなタイプの情報をまとめられますし、それぞれプロパティを持つことも可能です。
リレーションシップ自体がRDBで言うところの内部キーのような扱いなので、ノードのプロパティに特別なキーを持たせる必要はありません。

2.活用事例


先日の私のLT資料。
今、こんなことをしていますよー程度の内容ですので、パラ読みで大丈夫です。
あと簡単な最新の自己紹介があるくらい。もう少し真面目な自己紹介はこっち。

cerulean.hatenablog.com

3.Neo4jの使いどころ


私がNeo4j(2系)を触っていたり最新版(3.1系)の内容を見て感じた、Neo4jを使おうとした際に是非満たして欲しいポイントがこの3点。

1) ネットワーク構造を持つデータをいずれ分析したい
2) WebIFを使わないのは勿体無い
3) Neo4jはあくまでグラフデータベースでありデータの切り出しまでが担当

以下、それぞれについて解説します。

1) ネットワーク構造を持つデータをいずれ分析したい

ネットワーク構造(あるいはグラフ構造)を持っている情報は、ごく普通に存在しています。
例えば社員や会員情報だって、会社や部署や人との関係性を持つ、ネットワーク構造として表現することができます。
なので、ある意味かなり広く使うことができるのですが、ただ情報をCRUDするだけならRDBでも十分です。

とはいえスキーマが複雑で、内部でキーを持たせてごちゃごちゃとJOINしなきゃいけないようなデータなら、JOINするよりはrelationshipでデータ自体を繋いでしまった方がきっと速いし簡単だし柔軟であるかもしれません。
内部キー持たせなかったけど、あーAとDってhogeで繋がってるわーどうしよーなんて時にも後でクエリー叩けばOK。
あれ?そう考えると内部でキーをぐるんぐるん持ち回りしたりたくさんマッピングテーブル持ってるようなスキーマなら、載せ替えてもいい気がしてきた。

aggregation系のCypherもあり、集計や平均、偏差あたりは十分に可能です。
グラフ構造なので、誰が/何がたくさんのノードから紐付けされてるのかなーなんて分析も一目瞭然だったりします。

なのですが、せっかくグラフ構造なのでこのままグラフ分析をしたいなーと思った場合には少々力不足。
さすがに最短経路くらいはあるので、レコメンド的なものはできそう。
あとは 3) で書きます。

2) WebIFを使わないのは勿体無い

Neo4jはウェブインターフェイスがカッコいい。素敵。最初こればっかり触っていたくらい大好き。
f:id:hrk0619:20161205120527p:plain 私たちの場合にはReadOnlyなので検索中心ですが、検索して、パッとデータの繋がりが見えるのは非常に嬉しいです。
この論文、なんだかこの人から引用されまくってるなーとか、この人どんだけ仕事してんだよーとか、一目瞭然。

1) にも通ずるところはありますが、グラフデータとしてデータが見えることで、分析の手がかりになります。
このウェブインターフェイスを使うことがイメージできないのであれば、別にRDBでいいのかなーという指標になるかな、と思いました。

3) Neo4jはあくまでグラフデータベースでありデータの切り出しまでが担当

3.1での追加機能などを見ても、スケーリングや耐障害性といったデータベースとしての機能の充実がメインになっているので、現状の使いどころとしてはデータベースとしての使い方に集約すべきだと感じています。
1) にも書きましたが、グラフデータなので、グラフ分析ネットワーク分析の、密度がーとか中心性がーとかやりたくても、Neo4jには術がない。
私たちは、今の所そんなに大きなネットワークの分析をしていないので、サブグラフを切り出してCSVなりに落とし、分析にはRなどを使っています。
Boltを使えばNeo4jから直接データを吸い出せそうなので、今後研究で大規模なグラフを扱うならSparkとか、そもそもPGXを使おうかーなどと話しています。

とはいえCypherクエリーはシンプルですし、SQLを触ったことがあるならば半日ほどでCRUDは簡単に達成できるでしょう。
今後どのような方向に機能を拡充していくのかも期待大、いずれにせよ、楽しくていいですよ。

4. 参考文献


www.amazon.co.jp

今の所こちらが一番オススメです。

5. <Prev GeekWomenJapan Advent Calendar 2016 4日目


REST必要条件を簡単にさっくりと 超入門編 // Speaker Deck

非常にシンプルかつ分かりやすいREST必要条件! なんとなーくで使っていていざ説明しろと言われてもうまく説明する自信がなかったので、とても助かります。

6. Next> GeekWomenJapan Advent Calendar 2016 6日目


初めてのLチカ | BIJIN PROFILE

そういえばハードが絡むプログラミングはやったことがなかったので、私も手を出してみようかな。
すぐウェブアプリにしてしまう視野の狭さを反省。。。

最後に

結局時間がなくてNeo4jのことを書いてしまいましたが、ゆとりがあれば私が触れる言語9つ書いて比較ーとかやろうとしていました。
これでも初めてのお仕事言語が Scala という割とレアめな人間なので、ちょっと面白いかなと。
せっかく GeekWomenJapan の Advent Calendar だったのにこんな記事で恐縮ですが、このブログには一人の女性エンジニアとして、また、一人の働く母として得た知見などもまとめています、興味があればお時間のあるときにでも眺めていただければ幸いです。

と、時間が足りなくて急いで書いたので、後でちょいちょい文章修正しているかも。すみません。

Neo4jのWebインターフェイス(HTTP)をNginx(HTTPS)でリバースプロキシした

Neo4j Advent Calendar 2016 2日目

qiita.com

ちょっとNeo4j色は薄めですが、導入方法とかNeo4jのよさなどはみなさんが書いてくださりそうなので、実際に使おうとしたときにちょっとハマったし一発で情報が出てこなかったネタを選びました。
環境構築経験少なくて苦手なのが露呈するからこんな機会じゃなきゃ絶対書かない。

発端

Neo4jのとっても素敵なWebインターフェイスを複数チームで使いたいが、Neo4jのいるサーバーは表に出したくない。
どうもXWindow/XQuartzを使うと設定頑張ってもレスポンスが遅すぎてつらいし、仕方ないので外向けのサーバーからリバースプロキシする。
ついでにユーザー認証もしたい。

構成

[Server1] 外部向けサーバーとして稼働中
CentOS 6.8
Nginx 1.10.1

[Server2] ネットワーク内部のみSSHアクセスを許可して稼働中
CentOS 6.8
Neo4j 2.3.2

手順

Neo4j, Nginx, httpd-tools(Basic認証のため)はインストール済みとして、設定の話に集約します。
もし必要でしたらコメントいただければ作業ログのレベルですが↑も書きます。

1) proxy.conf を作成してリバースプロキシ、HTTPSBasic認証の設定を書く。

$ cd /etc/nginx/conf.d/ # 例
$ vi proxy.conf # お好きなeditorでどうぞ、同じ構成なら[]部分を編集する感じ

## Head
server {
    # HTTPS
    listen 443 default ssl;

    ssl on;
    ssl_certificate [SSL証明書までのpath];
    ssl_certificate_key [SSL秘密鍵までのpath];

    location / {
        # Basic認証
        deny all;
        auth_basic "[Administrator only]";# お好きな名称でどうぞ
        auth_basic_user_file [.htpasswdまでのpath];
        satisfy any;

        # リバースプロキシ
        proxy_pass [Neo4jのアドレス];# http://servername:7474/ とかが多いのかな

        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Authorization "Basic [エンコードしたNeo4jのパスワード]";# ここちょっとハマったし直したい

        proxy_redirect http:// https://;# これ忘れてて一瞬ハマった
        proxy_buffering off;

    }
}
## EOF

2) ユーザーとパスワードを設定する

$ mkpasswd # 硬めのパスワードが欲しかったら使用
$ htpasswd -c [.htpasswdまでのpath] [ユーザー名] # 初回
$ htpasswd [.htpasswdまでのpath] [ユーザー名] # 追加時

3) Nginxの設定をテストする(もし問題があればエラーを見ながら修正)

$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

4) Nginx再起動

$ nginx -s reload

以上。

一度ハマった点

Neo4jのWebインターフェイスを使用するためには、例えば"neo4j"というユーザーとそのパスワードを入力する必要があります。
リバースプロキシをしてしまうので、せっかく認証をしてもその情報をきちんと受け渡さないと、Neo4jの認証エラーで弾かれました。
とりあえずすぐ使えるようにしなければならなかったので、Neo4jのログを見ながらエンコードされたパスワードを拾って入れてしまいました。
時間あるときにちゃんとクッキーなりセッションなりの必要な項目を受け渡すように直します。直せたらここも更新します。
認証情報どこにいるやら...パッと情報が見つからなかった。私の場合経験しながら学ばないと吸収されないので頑張る。

参考文献

gihyo.jp

www.oreilly.co.jp

<Prev Neo4j Advent Calendar 2016 1日目

qiita.com

私が説明書くより断然分かりやすいと思う。

Next> Neo4j Advent Calendar 2016 3日目

qiita.com

早速使ってみたいなーという方必読ですね!
Windowsで構築したことがなかったので、個人的にも重宝します。