View
3.809
Download
0
Embed Size (px)
Citation preview
Copyright © 2016 Oracle and/or its affiliates. All rights reserved.
Oracle Labs 発!Parallel Graph Analytics ( PGX )
2017 年 3 月 1 日 更新
日本オラクル株式会社山中遼太( [email protected] )
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 2
以下の事項は、弊社の一般的な製品の方向性に関する概要を説明するものです。また、情報提供を唯一の目的とするものであり、いかなる契約にも組み込むことはできません。以下の事項は、マテリアルやコード、機能を提供することをコミットメント(確約)するものではないため、購買決定を行う際の判断材料になさらないで下さい。オラクル製品に関して記載されている機能の開発、リリースおよび時期については、弊社の裁量により決定されます。
Oracle と Java は、 Oracle Corporation 及びその子会社、関連会社の米国及びその他の国における登録商標です。文中の社名、商品名等は各社の商標または登録商標である場合があります。
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 3
グラフ・データベース?
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 4
ネットワーク分析とグラフ
• さまざまな関係構造をネットワークとして扱うことができる
• このネットワークを点と線の集合として抽象化したものがグラフ• グラフ理論は数学の一つとして古くから発展してきた
1736 年 ケーニヒスベルグの問題(オイラー) 無向/有向グラフ、多重グラフ、重み、…
※ 出典 ( ライセンス: CC BY-SA 3.0) https://ja.wikipedia.org/wiki/ 一筆書き /media/File:7_bridges.svg
Copyright © 2016 Oracle and/or its affiliates. All rights reserved.
グラフ・データベース
5
DB-Engines に掲載のカテゴリ別人気変化率(http://db-engines.com/en/ranking_categories)
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 6
データを表に格納する
deptno dname loc1 営業第一 東京2 研究開発 大阪3 マーケティング 東京
empno ename job deptno1 アルバート 課長 1
2 バクスター 主任研究員 2
3 チェン 係長 3
4 デイヴィス エンジニア 2
社員表
部門表主キー
主キー
外部キー
SELECT e.enameFROM emp e, dept dWHERE e.deptno = d.deptnoAND d.loc = 'Tokyo'
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 7
データをグラフに格納する
プロパティ・グラフなら、簡単かつ柔軟に表現することができ、さらに、グラフ用の直感的なクエリ言語で検索することができる
SELECT e.enameWHERE (e)-[belong_to]->(d) , d.loc = 'Tokyo'
11
2
3
4
2
3
dname: 営業第一loc: 東京
ename: アルバートjob: 営業
belong_to
from: 2013
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 8
誰が最重要人物か? ― つながりの定量化
• 集計を用いた手法• 誰が多く支払ったか?• 誰が高いマージンの商品を買ったか?• 誰が継続的に購入しているか?
• つながりを用いた手法• 誰が強い影響力を周りに対して持っているか?• 誰が特定人物と同じ商品を購入しているか?• 誰が若い世代のコミュニティに属しているか?
表に対する問い
SQL のような計算方法が適している
グラフに対する問い
なにか別の計算方法が必要とされている!
Copyright © 2016 Oracle and/or its affiliates. All rights reserved.
グラフが利用されるビッグデータ課題
9
購買記録
顧客と商品
リコメンデーション 影響力のある人物の特定
パターン・マッチング
コミュニティの検出
私と買い物が似ている人物によって購入された商品と、その商品と一緒に購入されている商品を教えてください
ソーシャル・ネットワーク上で中心的な役割を担っている人物を教えてください(マーケティング分析など)
似通った人達やつながりのある人達のグループを教えてください(ターゲット・マーケティングなど)
ある不正取引と同様の取引パターンがみられる全ての預金口座を探してください(不正検出や行動分析など)
Twitter など
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 10
グラフ分析エンジン「 PGX」
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 11
Spatial and Graph オプション
Oracle Database Enterprise Edition 12c R2
Graph 機能
ネットワーク・データ・モデル
RDF セマンティック・グラフ
Spatial 機能
プロパティ・グラフ
Spatial and Graph オプション
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 12
グラフ・データベースが最適?
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 13
インメモリ解析 + 永続化ストレージ
RDBMS, Hadoop, NoSQL (KVS)
Request分析処理
RequestReques
tRequestReques
t更新処理
PGXPGX
メモリ上
データを並列処理で読み込みノードとエッジとしてメモリ上に展開
Oracle Labs で開発された高速なインメモリのグラフ分析エンジン
トランザクションはデータベースや Hadoop で処理
グラフ用クエリ言語 PGQL や、定義済みグラフ分析アルゴリズムを API から使用可能(ただし PGQL は DB 12.2.0.1 では未サポート)
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 14
Oracle Labs PGXOracle Labs (旧 Sun Labs )から OTN ライセンスで配布• 商用利用はできませんが、無償で検証や開発ができます。
Copyright © 2016 Oracle and/or its affiliates. All rights reserved.
グラフ分析における2種類の処理
•参照系処理• あるノードの周辺ノードの参照• プロパティ・パスによる探索• パターン・マッチング• サブグラフの抽出
15
•演算系処理• コンポーネントやコミュニティの検
出• コミュニティ構造の評価• ランキングとウォーキング• 経路探索
315 2
542
3
23
2
2
1
221
11
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 16
PGX のコンセプト
•参照系処理と演算系処理の双方、これらを組み合わせた処理に対応• グラフのクエリによる参照( PGQL )• グラフへのアルゴリズムの適用• グラフの変換( Mutation )
「あるノードから3ステップ 以内にあるページランクの 高いノード」を探す、など
315 2
542
3
23
2
2
1
221
11
315 2
542
3
23
2
2
1
221
11
演算!
参照!
Copyright © 2016 Oracle and/or its affiliates. All rights reserved.
参照系処理 ― クエリ言語によるグラフの参照
17
SELECT person.name, person.ageWHERE (m WITH name='Mario') -[WITH type='likes']-> (person), (l WITH name='Luigi') -[WITH type='likes']-> (person), person.age < m.age - 2ORDER BY person.name
• Neo4j Cypher に似たクエリ言語「 PGQL」によってグラフを参照可能
• グラフのパターンを直感的に記述できる:
「年齢がマリオより2歳下より若く、マリオとルイージが共に好いている 全ての人物の名前と年齢を、名前順に教えてください」
• バージョン 0.9 の仕様書はこちら
Copyright © 2016 Oracle and/or its affiliates. All rights reserved.
演算系処理 ― 定義済みの 35 のアルゴリズム
18
コンポーネントやコミュニティの検出
強連結成分分解( Tarjan 法、 Kosaraju法)弱連結コンポーネントラベル伝搬法
ランキングとウォーキング
ページランク、パーソナライズドページランク中心媒介性、次数分布、次数中心性近接中心性、固有ベクトル中心性HITS 、ランダムウォークサンプリング
コミュニティ構造の評価
∑ ∑
コンダクタンスモジュール性クラスタ係数トライアングル数え上げ
経路探索幅優先探索、ダイクストラ法双方向ダイクストラ法 ベルマン・フォード法
その他 リンク予測( SALSA )
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 19
使ってみる
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 20
PGX のセットアップ( Linux )
$ cd $HOME/pgx # ここにファイルを置くとします$ unzip pgx-2.3.1-server.zip$ tar xvzf jdk-8u111-linux-x64.tar.gz
$ export JAVA_HOME=$HOME/pgx/jdk1.8.0_111$ export PATH=$JAVA_HOME/bin:$PATH$ export PGX_HOME=$HOME/pgx/pgx-2.3.1$ alias pgx='$PGX_HOME/bin/pgx'
環境変数とエイリアスを設定します
ファイルを展開します
最新版の PGX 2.3.1 Server をこちらからダウンロードします
JDK8 (下記では 8u111 )もこちらからダウンロードします
参考 Oracle Labs PGX 2.2.1 Documentation – Installation
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 21
PGX のセットアップ( Mac )
$ cd $HOME/pgx # ここにファイルを置くとします$ unzip pgx-2.3.1-server.zip
$ export \ JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_111.jdk/Contents/Home/ $ export PATH=$JAVA_HOME/bin:$PATH$ export PGX_HOME=$HOME/pgx/pgx-2.3.1$ alias pgx='$PGX_HOME/bin/pgx'
環境変数とエイリアスを設定します
ファイルを展開します
最新版の PGX 2.3.1 Server をこちらからダウンロードします
JDK8 (下記では 8u111 )もこちらからダウンロードしてインストールします
参考 Oracle Labs PGX 2.3.1 Documentation – Installation
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 22
PGX シェルの起動
$ pgx..pgx>
PGXシェルを起動します
pgx> :exit
PGXシェルを閉じるとき
pgx> :clear
PGXシェルの誤入力でエラーが発生した際はヒストリーをクリアしてください
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 23
グラフの読み込み
$ cd $PGX_HOME$ pgx
PGXシェルを起動します
G = session.readGraphWithProperties("examples/graphs/sample.adj.json")
G.queryPgql(" SELECT x.id(), y.id() WHERE (x)-->(y) ").print()
x.id() y.id()============================================ 333 128 128 1908 128 99 99 333
サンプルのデータをロードした後、全てのエッジを参照します
333128
1908
99
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 24
Marvel ヒーローのグラフ• Marvel のコミックには
多くのキャラクターが登場
• さらに、ヒーロー達が集まって敵と戦ったり、他のコミックに友情出演することが多々ある
• そこでキャラクターの共演をグラフにして解析する
※ 出典 http://www.oracle.com/us/theavengers /avengers-main-body-1571184.html (壁紙もダウンロードできます)
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 25
データの入手
$ more hero-network.csv
"IRON MAN/TONY STARK ","CHAIN""IRON MAN/TONY STARK ","SPIDER-WOMAN II/JULI""IRON MAN/TONY STARK ","CARPENTER, RACHEL""CARPENTER, RACHEL","CHAIN""CARPENTER, RACHEL","SPIDER-WOMAN II/JULI"..
Exposedata.com (http://exposedata.com/marvel/) のウェブ・アーカイブの「 Hero Social Network Data」から CSV データを入手します
このデータは、キャラクターをノードとして、コミックの同じ号に登場しているキャラクター同士をカンマ区切りで対にしただけのものです
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 26
グラフのロード
G = session.readGraphWithProperties("hero/hero-network.csv.json").undirect()
$ vi hero-network.csv.json{ "uri": "hero-network.csv", "format": "edge_list", "node_id_type": "string", "separator": ","}
$ pgx
グラフのロードのための情報を JSON で記述します
PGXシェルから上のファイルを指定してグラフをロードします(無向グラフとして読み込んでいます)
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 27
グラフのロード
キャラクター(ノード)を表示しますG.queryPgql(" SELECT x.id() WHERE (x) ").print()
G.queryPgql(" SELECT x.id() WHERE (x) ").getNumResults()
==> 6426
キャラクター(ノード)の数を表示します
G.queryPgql(" SELECT x.id(), y.id() WHERE (x)-->(y) ").getNumResults()
==> 1146702
一緒に登場するキャラクターの組(エッジ)の数を表示します
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 28
グラフのロード
G = G.simplify( \ MultiEdges.REMOVE_MULTI_EDGES \ , SelfEdges.REMOVE_SELF_EDGES \ , TrivialVertices.REMOVE_TRIVIAL_VERTICES \ , Mode.CREATE_COPY \ , null \ )
ロードしたグラフに前処理を施します
G.queryPgql(" SELECT x.id(), y.id() WHERE (x)-->(y) ").getNumResults()
==> 334414
一緒に登場するキャラクターの組(エッジ)の数を表示します
# 同じ2つのノードを結ぶ複数のエッジを除去# 始点と終点が同じノードのエッジを除去 # エッジを持たないノードを除去 # 内部的にグラフのコピーを作成 # グラフ名(任意)
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 29
参照型処理の実行
PGQL は参照型処理(パターン・マッチング)に便利です
「アイアンマンとスパイダーマンとウルヴァリンの全てと 一緒に登場したことのあるキャラクターは?」
G.queryPgql(" \ SELECT x.id() \ WHERE \ (x)-->(a WITH id()='IRON MAN/TONY STARK ') \ , (x)-->(b WITH id()='SPIDER-MAN/PETER PAR') \ , (x)-->(c WITH id()='WOLVERINE/LOGAN ') \").print()
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 30
参照型処理の実行
結果の件数が多いので、一度、結果データを変数に渡して件数を数えますResult = G.queryPgql(" \ SELECT x.id() \ WHERE \ (x)-->(a WITH id()='IRON MAN/TONY STARK ') \ , (x)-->(b WITH id()='SPIDER-MAN/PETER PAR') \ , (x)-->(c WITH id()='WOLVERINE/LOGAN ') \")
Result.getNumResults()
==> 504
10件だけ見てみますResult.print(5)
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 31
ヒーローの重要度の評価
• 次数中心性• より多くのエッジを持つノードがより重
要• 友だちが多い人は重要人物?
• ページランク• 重要性はグラフ上で伝播するとすれば…• 重要なノードに繋がるノードは重要• 重要人物の友だちは重要人物?
• 媒介中心性• 多くのノード同士の最短経路にいると重要• その人がいないとみんなが困る?
Ironman
CapAmer
Ironman Hulk
Nick
CapAmer
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 32
演算型処理の実行
まず、各ノードの次数中心性を求めますanalyst.inDegreeCentrality(G)
計算されたスコアは各ノードのプロパティ in_degree に格納されます
引数として、グラフ( G )が渡されています。計算量はノードの数 N 、エッジ数を E としたとき、計算量は N に依存して増加するため O (N) になります。詳細はリファレンスに記載されています。
==> Vertex Property named 'in_degree' of type integer belonging to graph ..
Ironman in_degree: 3
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 33
演算型処理の実行
5人の重要なキャラクターが得られました!| n.id() | n.in_degree |======================================| CAPTAIN AMERICA | 1906 || SPIDER-MAN/PETER PAR | 1737 || IRON MAN/TONY STARK | 1522 || THING/BENJAMIN J. GR | 1416 || MR. FANTASTIC/REED R | 1379 |
G.queryPgql(" \ SELECT n.id(), n.in_degree WHERE (n) \ ORDER BY n.in_degree DESC \").print(5)
計算結果を参照するためには、 PGQL を使います
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 34
演算型処理の実行
次に、各ノードのページランクを求めますanalyst.pagerank(G, 0.0001, 0.85, 100)
計算されたスコアは各ノードのプロパティ pagerank に格納されます
引数として、グラフ( G )および 3 つのパラメータ(許容される最大エラー値、ダンピング・ファクター、計算の反復回数)が渡されています。計算量は反復回数を k として O (k*E) になります。詳細はリファレンスに記載されています。
==> Vertex Property named 'pagerank' of type double belonging to graph ..
Ironman pagerank: 0.0041204
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 35
演算型処理の実行
スパイダーマンが1位になりました!| n.id() | n.pagerank |================================================| SPIDER-MAN/PETER PAR | 0.005295697226042497 || CAPTAIN AMERICA | 0.005125996140362315 || IRON MAN/TONY STARK | 0.0041204415753377755 || WOLVERINE/LOGAN | 0.0038669573843525297 || THING/BENJAMIN J. GR | 0.00368240604720028 |
G.queryPgql(" \ SELECT n.id(), n.pagerank WHERE (n) \ ORDER BY n.pagerank DESC \").print(5)
計算結果を参照するためには、 PGQL を使います
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 36
演算型処理の実行
同様に、各ノードの媒介中心性も求めてみます
analyst.vertexBetweennessCentrality(G)
媒介中心性は、全ての頂点間の最短経路の中でその頂点が経路上にいる割合をスコアとしています。媒介中心性の計算量は O (N*E) であり、ページランクの計算量 O (k*E) と比較して計算コストが高く、やや実行時間が長くかかります。
詳細はリファレンスに記載されています。
==> Vertex Property named 'betweenness' of type double belonging to graph ..
計算されたスコアは各ノードのプロパティ betweenness に格納されます Ironman pagerank: 0.0072942
betweenness: 1536742
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 37
演算型処理の実行
トップ4まではページランクとも順位が一致しています| n.id() | n.betweenness |=============================================| SPIDER-MAN/PETER PAR | 3035278.742514685 || CAPTAIN AMERICA | 2351348.199987786 || IRON MAN/TONY STARK | 1536742.6554027207 || WOLVERINE/LOGAN | 1473595.2238889316 || HAVOK/ALEX SUMMERS | 1471842.538198293 |
G.queryPgql(" \ SELECT n.id(), n.betweenness WHERE (n) \ ORDER BY n.betweenness DESC \").print(5)
計算結果を参照するためには、 PGQL を使います
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 38
参照と演算の併用
演算型処理の結果(ここではページランクのスコア)を参照型処理(パターン・マッチング)の対象としてそのまま使えてしまうのが PGQL の便利なところ!
前出の検索をこのように変更してみます。
「アイアンマンとスパイダーマンとウルヴァリンの全てと一緒に登場したこと のあるキャラクターのうちマイナーなキャラクターは?」Result = G.queryPgql(" \ SELECT x.id(), x.pagerank \ WHERE \ (x)-->(a WITH id()='IRON MAN/TONY STARK ') \ , (x)-->(b WITH id()='SPIDER-MAN/PETER PAR') \ , (x)-->(c WITH id()='WOLVERINE/LOGAN ') \ ORDER BY x.pagerank ASC \")
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 39
参照と演算の併用
こちらがマイナーなキャラクター 10 名です
Result.print(10)
| x.id() | x.pagerank |================================================| TYCHO | 5.611553899059807E-5 || ISBISA/DR. SANDERSON | 7.622033978468877E-5 || MASON, WANDA | 9.52103640547917E-5 || STORM, CHILI | 1.087940205195763E-4 || MAGNUM, MOSES | 1.0989429673080101E-4 || BIRD MAN/HENRY HAWK | 1.206812449804567E-4 || CAT MAN/HORGAN | 1.206812449804567E-4 || TERRAXIA | 1.2137478460591338E-4 || RAZORFIST III | 1.23495696066652E-4 || SVAROG | 1.2727748790164624E-4 |
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 40
タンパク質のネットワークであれば…
「タンパク質 A 、 B 、 C の全てと相互作用があるタンパク質のうちネットワーク 上の重要性が低いタンパク質(ロングテールの標的の可能性がある)は?」Res = G.queryPgql(" \ SELECT x, x.pagerank \ WHERE \ (x)-->(a WITH id()='Protein A') \ , (x)-->(b WITH id()='Protein B') \ , (x)-->(c WITH id()='Protein C') \ ORDER BY x.betweenness ASC \")
AX
CB
中心媒介性: 0.00129 (低)
STRING Database http://string-db.org/
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 41
乗換案内
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 42
データの入手
駅データ.jp から、駅データ、接続駅データ、路線データを入手します。
line_cd,company_cd,line_name,line_name_k, ..1001,3,中央新幹線 ,チュウオウシンカンセン , ..1002,3,東海道新幹線 ,トウカイドウシンカンセン , ..1003,4,山陽新幹線 ,サンヨウシンカンセン , ..
line_cd,station_cd1,station_cd21002,100201,1002021002,100202,1002031002,100203,100204
接続駅データはエッジです。
station_cd,station_g_cd,station_name, ..1110101,1110101,函館 , ..1110102,1110102,五稜郭 , ..1110103,1110103,桔梗 , ..
駅データはノードとそのプロパティです。
路線データはエッジのプロパティです。
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 43
データの加工
$ sort -t ',' -k 1 station20161107free.csv > station.csv$ sort -t ',' -k 1 line20161107free.csv > line.csv$ sort -t ',' -k 2 join20161107.csv > join01.csv$ join -t ',' join01.csv station.csv -1 2 -2 1 -o 1.1,2.2,1.3 > join02.csv$ sort -t ',' -k 3 join02.csv > join03.csv$ join -t ',' join03.csv station.csv -1 3 -2 1 -o 1.1,1.2,2.2 > join04.csv$ sort -t ',' -k 1 join04.csv > join05.csv$ join -t ',' join05.csv line.csv -1 1 -2 1 -o 2.3,1.2,1.3 > join06.csv$ cat station.csv | awk -v FS=',' -v OFS=',' '{if (NR != 1) print $2, "*"}' | \ sort | uniq > station_uniq.csv$ join -t ',' station_uniq.csv station.csv -1 1 -2 1 -o 1.1,1.2,2.3 > rail.csv$ cat join06.csv | \ awk -v FS=',' -v OFS=',' '{print $2, $3, $1, "1"}' >> rail.csv
データを Edge List 形式に加工します。
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 44
グラフのロード
$ vi rail.csv.json{ "uri": "rail.csv", "format": "edge_list", "node_id_type": "integer", "vertex_props":[ {"name":"name", "type":"string"} ], "edge_props":[ {"name":"name", "type":"string"} , {"name":"score", "type":"double"} ], "separator": ","}
グラフのロードのための情報を JSON で記述します
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 45
グラフのロード
PGXシェルを開き、グラフを(有向グラフのまま)ロードしますG = session.readGraphWithProperties("rail/rail.csv.json")
同じ駅間は複数の路線で接続されていることがあるため、このグラフは同じノード間に複数のエッジが含まれ得るグラフですG.queryPgql(" \ SELECT x.name, r.name, y.name WHERE (x)-[r]->(y), \ x.name='恵比寿 ', y.name='渋谷 ' \").print()
| x.name | r.name | y.name |============================| 恵比寿 | JR埼京線 | 渋谷 || 恵比寿 | JR山手線 | 渋谷 |
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 46
有向グラフと無効グラフ
G.queryPgql(" \ SELECT x.name, r.name, y.name WHERE (x)-[r]->(y), x.name='外苑前 ' \").print()
外苑前のとなりの駅と路線
| x.name | r.name | y.name |==============================| 外苑前 | 東京メトロ銀座線 | 表参道 |
G.queryPgql(" \ SELECT x.name, r.name, y.name WHERE (x)<-[r]-(y), x.name='外苑前 ' \").print()
| x.name | r.name | y.name |==============================| 外苑前 | 東京メトロ銀座線 | 青山一丁目 |
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 47
有向グラフと無効グラフ
G.queryPgql(" \ SELECT x.name, r.name, y.name WHERE (x)-[r]->(y), x.name='外苑前 ' \").print()
| x.name | r.name | y.name |==============================| 外苑前 | 東京メトロ銀座線 | 青山一丁目 || 外苑前 | 東京メトロ銀座線 | 表参道 |
無効グラフにすることにより、同じ路線の逆方向の駅が出力されます
実際には多くの路線は両方向なので、無効グラフに変換しますG = G.undirect()
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 48
経路の検索
G.queryPgql(" \ SELECT y.name, COUNT(*) AS cnt WHERE (x)-->()-->()-->(y), \ x.name='外苑前 ' GROUP BY y.name ORDER BY cnt DESC \").print()
外苑前から3ホップの駅とその経路の数を求めます
| y.name | cnt |================| 表参道 | 9 || 青山一丁目 | 9 || 恵比寿 | 6 || 新宿 | 6 || 原宿 | 5 |...
同じ駅を行き来することができるため隣の駅への経路が多く出力されます
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 49
経路の検索
G.queryPgql(" \ SELECT y.name, COUNT(*) AS cnt WHERE (x)-->(s1)-->(s2)-->(y), \ x.name='外苑前 ', x!=s1, x!=s2, x!=y, s1!=s2, s1!=y, s2!=y \ GROUP BY y.name ORDER BY cnt DESC \").print()
同じ駅を2度通らないように条件を追加します
| y.name | cnt |================| 新宿 | 6 || 恵比寿 | 6 || 原宿 | 5 || 渋谷 | 4 || 四ツ谷 | 4 || 溜池山王 | 4 |...
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 50
経路の検索
G.queryPgql(" \ SELECT x.name, r1.name, s1.name, r2.name, s2.name, r3.name, y.name \ WHERE (x)-[r1]->(s1)-[r2]->(s2)-[r3]->(y), \ x.name='外苑前 ', y.name='新宿 ', x!=s1, x!=s2, x!=y, s1!=s2, s1!=y, s2!=y \").print()
経路を確認します
| x.name | r1.name | s1.name | r2.name | s2.name | r3.name | y.name |==========================================================================| 外苑前 | 東京メトロ銀座線 | 表参道 | 東京メトロ半蔵門線 | 渋谷 | JR埼京線 | 新宿 || 外苑前 | 東京メトロ銀座線 | 表参道 | 東京メトロ半蔵門線 | 渋谷 | JR湘南新宿ライン | 新宿 || 外苑前 | 東京メトロ銀座線 | 表参道 | 東京メトロ半蔵門線 | 渋谷 | JR成田エクスプレス | 新宿 || 外苑前 | 東京メトロ銀座線 | 表参道 | 東京メトロ銀座線 | 渋谷 | JR埼京線 | 新宿 || 外苑前 | 東京メトロ銀座線 | 表参道 | 東京メトロ銀座線 | 渋谷 | JR湘南新宿ライン | 新宿 || 外苑前 | 東京メトロ銀座線 | 表参道 | 東京メトロ銀座線 | 渋谷 | JR成田エクスプレス | 新宿 |
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 51
重要度の高い駅は?
各駅の次数中心性、ページランク、媒介中心性も求めてみます。
同じ駅間に複数の路線があった場合にもひとつのエッジとして計算できるようにグラフを変換します。複数の路線のうちひとつのみを残して他は削除されます。
analyst.inDegreeCentrality(G)analyst.pagerank(G, 0.0001, 0.85, 100)analyst.vertexBetweennessCentrality(G)
G = G.simplify( \ MultiEdges.REMOVE_MULTI_EDGES \ , SelfEdges.REMOVE_SELF_EDGES \ , TrivialVertices.REMOVE_TRIVIAL_VERTICES \ , Mode.CREATE_COPY \ , null \ )
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 52
重要度の高い駅は?
G.queryPgql(" \ SELECT n.name, n.in_degree \ WHERE (n) ORDER BY n.in_degree DESC \").print(10)
次数中心性の高い駅を参照します
| n.name | n.in_degree |========================| 新宿 | 18 || 横浜 | 15 || 池袋 | 14 || 大阪 | 14 || 渋谷 | 12 || 名古屋 | 12 || 東京 | 12 |
※ 出典 ( ライセンス: CC BY-SA 4.0) https://ja.wikipedia.org/wiki/ 新宿駅#/media/File:JR_Shinjuku_Miraina_TowerB.JPG
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 53
重要度の高い駅は?
G.queryPgql(" \ SELECT n.name, n.pagerank \ WHERE (n) ORDER BY n.pagerank DESC \").print(10)
ページランクの高い駅を参照します
| n.name | n.pagerank |==================================| 横浜 | 4.998270086927543E-4 || 池袋 | 4.524281258534644E-4 || 新宿 | 4.2276282745781573E-4 || 名古屋 | 4.0831778989897983E-4 || 千葉 | 4.020797074464819E-4 || 大阪 | 3.805626711067609E-4 || 三ノ宮 | 3.6190334872793586E-4 |
※ 出典 ( ライセンス: CC BY 3.0) https://ja.wikipedia.org/wiki/横浜駅#/media/File:横浜駅西口方駅舎 .jpg
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 54
重要度の高い駅は?
G.queryPgql(" \ SELECT n.name, n.betweenness \ WHERE (n) ORDER BY n.betweenness DESC \").print(10)
媒介中心性の高い駅を参照します
| n.name | n.betweenness |=================================| 塩尻 | 3.5063735792578205E7 || 恵那 | 3.442572652854239E7 || 多治見 | 3.442035688060632E7 || 土岐市 | 3.4356404528542325E7 || 瑞浪 | 3.435411752854232E7 || 釜戸 | 3.435190252854232E7 || 武並 | 3.434972852854232E7 |
※ 出典 ( ライセンス: GFDL) https://ja.wikipedia.org/wiki/塩尻駅#/media/File:ShiojiriStnishi.jpg
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 55
重要度の高い駅は?
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 56
連結している?
G.queryPgql(" \ SELECT x.wcc, COUNT(*) AS num_station WHERE (x) \ GROUP BY x.wcc ORDER BY num_station DESC \").print()
出発と到着の駅のノード ID を確認しておきます
連結成分を計算します( WCC: Weakly Connected Compornent )analyst.wcc(G)
| subgraph | num_station |==========================| 1 | 8915 || 0 | 15 |
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 57
連結している?
分割された小さいほうのグラフに含まれる駅を表示しますG.queryPgql(" \ SELECT x.name, r.name, y.name WHERE (x)-[r]->(y), x.wcc=0, y.wcc=0 \").print()
| x.name | r.name | y.name |============================| 那覇空港 | ゆいレール | 赤嶺 || 赤嶺 | ゆいレール | 那覇空港 || 赤嶺 | ゆいレール | 小禄 || 小禄 | ゆいレール | 赤嶺 || 小禄 | ゆいレール | 奥武山公園 || 奥武山公園 | ゆいレール | 小禄 || 奥武山公園 | ゆいレール | 壺川 || 壺川 | ゆいレール | 奥武山公園 |...
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 58
最短経路は?
G.queryPgql(" SELECT x.id() WHERE (x), x.name='外苑前 ' ").print()G.queryPgql(" SELECT x.id() WHERE (x), x.name='鹿児島 ' ").print()
出発と到着の駅のノード ID を確認しておきます
x.id()====================== 2800117
x.id()====================== 1190412
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 59
最短経路は?
Path.getPathLengthWithHop()
最短で何ホップで到達できるかがわかります。
==> 360
エッジのスコア(今回は距離や時間のデータがないため全て 1 としています)を指定してダイクストラ法で最短経路を計算します。計算量は O (N log(N)) です。 node1 = G.getVertex(2800117)node2 = G.getVertex(1190412)score = G.getEdgeProperty("score")Path = analyst.shortestPathDijkstra(G, node1, node2, score)
Path.exists()
==> true
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 60
最短経路は?
最短経路上の駅を確認します。ただし、このデータには新幹線など一部のデータが含まれていないことにご留意ください。vList = Path.getVertices()eList = Path.getEdges()hops = Path.getPathLengthWithHop()for (i=0; i<hops+1; i++) { print vList[i].getProperty("name") if (i==hops) { print "\n" } else { print " > " }}
外苑前 > 表参道 > 渋谷 > 新宿 > 吉祥寺 > 三鷹 > 国分寺 > 立川 > 八王子 > 高尾 > 相模湖 > 藤野 > 上野原 > 四方津 > (略) > 加治木 >錦江 > 帖佐 > 姶良 > 重富 > 竜ケ水 > 鹿児島
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 61
PGX.D
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 62
PGX.D ― 分散処理版 PGX
Copyright © 2016 Oracle and/or its affiliates. All rights reserved.
PGX.D ― HPC の SC15 で Best Paper のひとつに
63
http://sc15.supercomputing.org/conference-program/technical-program/papers/best-student-paper-and-paper-finalists
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 64
参考資料
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 65
参考資料
• Oracle Labs PGX(再掲)
• 関連する Oracle 製品• Oracle Database Spatial and Graph• Oracle Big Data Spatial and Graph
• 関連する SlideShare 資料• Hadoop Conference Japan 2016 LT資料 グラフデータベース事始め• オラクルのHadoopソリューションご紹介
Copyright © 2016 Oracle and/or its affiliates. All rights reserved. 66