【Neo4j】グラフネットワークの構築


私の好きなドラマである「あなたの番です」を題材にグラフネットワークを作成。

※ネタバレ含みます。

もっときれいな方法があるような気もしますが、初心者のためご容赦ください。
良い方法あれば教えてください。csvで登録する方法も勉強したい。

計算環境

macOS Monterey 12.2
neo4j desktop v4.4.3

コード

  • 住人Nodeの作成(CREATE)
CREATE
(:Person{FirstName:"Nana",LastName:"Tezuka", Age:49,Room:302}),
(:Person{FirstName:"Shota",LastName:"Tezuka", Age:34,Room:302}),
(:Person{FirstName:"Sawa",LastName:"Kuroshima", Age:49,Room:202}),
(:Person{FirstName:"Yuzuru",LastName:"Kuzumi", Age:45,Room:101}),
(:Person{FirstName:"Kayo",LastName:"Kojima", Age:42,Room:102}),
(:Person{FirstName:"Toshiaki",LastName:"Kojima", Age:45,Room:102}),
(:Person{FirstName:"Kimiko",LastName:"Tamiya", Age:55,Room:103}),
(:Person{FirstName:"Junichiro",LastName:"Tamiya", Age:58,Room:103}),
(:Person{FirstName:"Yoko",LastName:"Ishizaki", Age:35,Room:104}),
(:Person{FirstName:"Kenji",LastName:"Ishizaki", Age:39,Room:104}),
(:Person{FirstName:"Fumiyo",LastName:"Ishizaki", Age:9,Room:104}),
(:Person{FirstName:"Kazuo",LastName:"Ishizaki", Age:6,Room:104}),
(:Person{FirstName:"Kesuke",LastName:"Ukita", Age:55,Room:201}),
(:Person{FirstName:"Airi",LastName:"Seno", Age:21,Room:201}),
(:Person{FirstName:"Ryo",LastName:"Kakinuma", Age:21,Room:201}),
(:Person{FirstName:"Lee",LastName:"Xingyi", Age:22,Room:203}),
(:Person{FirstName:"Nguyen",LastName:"Cuong", Age:21,Room:203}),
(:Person{FirstName:"Iqbal",LastName:"Dadd", Age:45,Room:203}),
(:Person{FirstName:"Jun",LastName:"Nishimura", Age:38,Room:204}),
(:Person{FirstName:"Mikiha",LastName:"Ono", Age:25,Room:301}),
(:Person{FirstName:"Sumika",LastName:"Kitagawa", Age:42,Room:304}),
(:Person{FirstName:"Sora",LastName:"Kitagawa", Age:5,Room:304}),
(:Person{FirstName:"Akane",LastName:"Kinoshita", Age:38,Room:401}),
(:Person{FirstName:"Masashi",LastName:"Enomoto", Age:48,Room:402}),
(:Person{FirstName:"Sanae",LastName:"Enomoto", Age:45,Room:402}),
(:Person{FirstName:"Soichi",LastName:"Enomoto", Age:14,Room:402}),
(:Person{FirstName:"Atsushi",LastName:"Fuji", Age:43,Room:403}),
(:Person{FirstName:"Yuki",LastName:"Eto", Age:23,Room:404}),
(:Person{FirstName:"Go",LastName:"Sano", Age:42,Room:501}),
(:Person{FirstName:"Misato",LastName:"Akaike", Age:50,Room:502}),
(:Person{FirstName:"Goro",LastName:"Akaike", Age:52,Room:502}),
(:Person{FirstName:"Sachiko",LastName:"Akaike", Age:78,Room:502});
  • 住人Nodeの作成(MERGE)
    マンション外の人も追加。なんとなくMERGEを使ってみる。
    MERGEはCREATEと異なり、重複している場合はNodeを作成しない。
    MERGE1つにつき、1Nodeしか追加できなかった。
MERGE (:Person{FirstName:"Asao",LastName:"Hosokawa", Age:45,Room:000});
MERGE (:Person{FirstName:"Ruri",LastName:"Sakuragi", Age:25,Room:000});
MERGE (:Person{FirstName:"Tatsuo",LastName:"Uchiyama", Age:21,Room:000});
MERGE (:Person{FirstName:"Masato",LastName:"Kamiya", Age:26,Room:000});
MERGE (:Person{FirstName:"Hiroshi",LastName:"Tokoshima", Age:60,Room:000});
MERGE (:Person{FirstName:"Haruki",LastName:"Namitome", Age:21,Room:000});
MERGE (:Person{FirstName:"Yutaro",LastName:"Yamagiwa", Age:43,Room:000});
MERGE (:Person{FirstName:"Masao",LastName:"Tanaka", Age:48,Room:000});
MERGE (:Person{FirstName:"Yoshihiko",LastName:"Hakamada", Age:45,Room:000});
MERGE (:Person{FirstName:"Takafumi",LastName:"Kono", Age:26,Room:000});

↓こんな感じでNodeが作成された

  • 部屋Nodeの作成
MERGE (:Room{No:101});
MERGE (:Room{No:102});
MERGE (:Room{No:103});
MERGE (:Room{No:104});
MERGE (:Room{No:105});
MERGE (:Room{No:201});
MERGE (:Room{No:202});
MERGE (:Room{No:203});
MERGE (:Room{No:204});
MERGE (:Room{No:205});
MERGE (:Room{No:301});
MERGE (:Room{No:302});
MERGE (:Room{No:303});
MERGE (:Room{No:304});
MERGE (:Room{No:305});
MERGE (:Room{No:401});
MERGE (:Room{No:402});
MERGE (:Room{No:403});
MERGE (:Room{No:404});
MERGE (:Room{No:405});
MERGE (:Room{No:501});
MERGE (:Room{No:502});
MERGE (:Room{No:503});
MERGE (:Room{No:504});
MERGE (:Room{No:505});
  • 居住情報の追加(MATCH & CREATE)
MATCH (p1:Person{Room:101}), (r1:Room{No:101}) CREATE (p1)-[:Live]->(r1);
MATCH (p2:Person{Room:102}), (r2:Room{No:102}) CREATE (p2)-[:Live]->(r2);
MATCH (p3:Person{Room:103}), (r3:Room{No:103}) CREATE (p3)-[:Live]->(r3);
MATCH (p4:Person{Room:104}), (r4:Room{No:104}) CREATE (p4)-[:Live]->(r4);
MATCH (p5:Person{Room:105}), (r5:Room{No:105}) CREATE (p5)-[:Live]->(r5);

MATCH (p1:Person{Room:201}), (r1:Room{No:201}) CREATE (p1)-[:Live]->(r1);
MATCH (p2:Person{Room:202}), (r2:Room{No:202}) CREATE (p2)-[:Live]->(r2);
MATCH (p3:Person{Room:203}), (r3:Room{No:203}) CREATE (p3)-[:Live]->(r3);
MATCH (p4:Person{Room:204}), (r4:Room{No:204}) CREATE (p4)-[:Live]->(r4);
MATCH (p5:Person{Room:205}), (r5:Room{No:205}) CREATE (p5)-[:Live]->(r5);

MATCH (p1:Person{Room:301}), (r1:Room{No:301}) CREATE (p1)-[:Live]->(r1);
MATCH (p2:Person{Room:302}), (r2:Room{No:302}) CREATE (p2)-[:Live]->(r2);
MATCH (p3:Person{Room:303}), (r3:Room{No:303}) CREATE (p3)-[:Live]->(r3);
MATCH (p4:Person{Room:304}), (r4:Room{No:304}) CREATE (p4)-[:Live]->(r4);
MATCH (p5:Person{Room:305}), (r5:Room{No:305}) CREATE (p5)-[:Live]->(r5);

MATCH (p1:Person{Room:401}), (r1:Room{No:401}) CREATE (p1)-[:Live]->(r1);
MATCH (p2:Person{Room:402}), (r2:Room{No:402}) CREATE (p2)-[:Live]->(r2);
MATCH (p3:Person{Room:403}), (r3:Room{No:403}) CREATE (p3)-[:Live]->(r3);
MATCH (p4:Person{Room:404}), (r4:Room{No:404}) CREATE (p4)-[:Live]->(r4);
MATCH (p5:Person{Room:405}), (r5:Room{No:405}) CREATE (p5)-[:Live]->(r5);

MATCH (p1:Person{Room:501}), (r1:Room{No:501}) CREATE (p1)-[:Live]->(r1);
MATCH (p2:Person{Room:502}), (r2:Room{No:502}) CREATE (p2)-[:Live]->(r2);
MATCH (p3:Person{Room:503}), (r3:Room{No:503}) CREATE (p3)-[:Live]->(r3);
MATCH (p4:Person{Room:504}), (r4:Room{No:504}) CREATE (p4)-[:Live]->(r4);
MATCH (p5:Person{Room:505}), (r5:Room{No:505}) CREATE (p5)-[:Live]->(r5);

↓登場人物(紫)がどの部屋(オレンジ)に住んでいるのか見えるようになった。

  • 実際の殺害関係の追加(MATCH & MERGE)
MATCH (p1:Person{FirstName:'Hiroshi'}), (p2:Person{FirstName:'Hiroshi'}) MERGE (p1)-[:Kill] ->(p2);
MATCH (p1:Person{FirstName:'Sanae'}), (p2:Person{FirstName:'Yutaro'}) MERGE (p1)-[:Kill] ->(p2);
MATCH (p1:Person{FirstName:'Atsushi'}), (p2:Person{FirstName:'Masao'}) MERGE (p1)-[:Kill] ->(p2);
MATCH (p1:Person{FirstName:'Sawa'}), (p2:Person{FirstName:'Misato'}) MERGE (p1)-[:Kill] ->(p2);
MATCH (p1:Person{FirstName:'Sawa'}), (p2:Person{FirstName:'Goro'}) MERGE (p1)-[:Kill] ->(p2);
MATCH (p1:Person{FirstName:'Ruri'}), (p2:Person{FirstName:'Yoshihiko'}) MERGE (p1)-[:Kill] ->(p2);
MATCH (p1:Person{FirstName:'Sawa'}), (p2:Person{FirstName:'Kayo'}) MERGE (p1)-[:Kill] ->(p2);
MATCH (p1:Person{FirstName:'Sawa'}), (p2:Person{FirstName:'Kesuke'}) MERGE (p1)-[:Kill] ->(p2);
MATCH (p1:Person{FirstName:'Yuzuru'}), (p2:Person{FirstName:'Asao'}) MERGE (p1)-[:Kill] ->(p2);
MATCH (p1:Person{FirstName:'Tatsuo'}), (p2:Person{FirstName:'Takafumi'}) MERGE (p1)-[:Kill] ->(p2);
MATCH (p1:Person{FirstName:'Tatsuo'}), (p2:Person{FirstName:'Nana'}) MERGE (p1)-[:Kill] ->(p2);
MATCH (p1:Person{FirstName:'Tatsuo'}), (p2:Person{FirstName:'Tatsuo'}) MERGE (p1)-[:Kill] ->(p2);
MATCH (p1:Person{FirstName:'Tatsuo'}), (p2:Person{FirstName:'Masato'}) MERGE (p1)-[:Kill] ->(p2);
MATCH (p1:Person{FirstName:'Junichiro'}), (p2:Person{FirstName:'Haruki'}) MERGE (p1)-[:Kill] ->(p2);

↓このように誰が誰を殺害したのか、赤線でわかった。

  • 紙に書いた名前(MATCH & MERGE)
MATCH (p1:Person{FirstName:'Misato'}), (p2:Person{FirstName:'Sachiko'}) MERGE (p1)-[:Write] ->(p2);
MATCH (p1:Person{FirstName:'Sanae'}), (p2:Person{FirstName:'Hiroshi'}) MERGE (p1)-[:Write] ->(p2);
MATCH (p1:Person{FirstName:'Atsushi'}), (p2:Person{FirstName:'Yutaro'}) MERGE (p1)-[:Write] ->(p2);
MATCH (p1:Person{FirstName:'Nana'}), (p2:Person{FirstName:'Asao'}) MERGE (p1)-[:Write] ->(p2);
MATCH (p1:Person{FirstName:'Sumika'}), (p2:Person{FirstName:'Kayo'}) MERGE (p1)-[:Write] ->(p2);
MATCH (p1:Person{FirstName:'Kesuke'}), (p2:Person{FirstName:'Misato'}) MERGE (p1)-[:Write] ->(p2);
MATCH (p1:Person{FirstName:'Sawa'}), (p2:Person{FirstName:'Haruki'}) MERGE (p1)-[:Write] ->(p2);
MATCH (p1:Person{FirstName:'Xingyi'}), (p2:Person{FirstName:'Masao'}) MERGE (p1)-[:Write] ->(p2);
MATCH (p1:Person{FirstName:'Yuzuru'}), (p2:Person{FirstName:'Yoshihiko'}) MERGE (p1)-[:Write] ->(p2);
MATCH (p1:Person{FirstName:'Junichiro'}), (p2:Person{FirstName:'Takafumi'}) MERGE (p1)-[:Write] ->(p2);
MATCH (p1:Person{FirstName:'Yoko'}), (p2:Person{FirstName:'Yoko'}) MERGE (p1)-[:Write] ->(p2);
  • 手にした紙に書いてあった名前(MATCH & MERGE)
MATCH (p1:Person{FirstName:'Misato'}), (p2:Person{FirstName:'Kayo'}) MERGE (p1)-[:Get] ->(p2);
MATCH (p1:Person{FirstName:'Sanae'}), (p2:Person{FirstName:'Yutaro'}) MERGE (p1)-[:Get] ->(p2);
MATCH (p1:Person{FirstName:'Atsushi'}), (p2:Person{FirstName:'Masao'}) MERGE (p1)-[:Get] ->(p2);
MATCH (p1:Person{FirstName:'Nana'}), (p2:Person{FirstName:'Takafumi'}) MERGE (p1)-[:Get] ->(p2);
MATCH (p1:Person{FirstName:'Kotoha'}), (p2:Person{FirstName:'Yoko'}) MERGE (p1)-[:Get] ->(p2);
MATCH (p1:Person{FirstName:'Kesuke'}), (p2:Person{FirstName:'Sachiko'}) MERGE (p1)-[:Get] ->(p2);
MATCH (p1:Person{FirstName:'Sawa'}), (p2:Person{FirstName:'Misato'}) MERGE (p1)-[:Get] ->(p2);
MATCH (p1:Person{FirstName:'Xingyi'}), (p2:Person{FirstName:'Yoshihiko'}) MERGE (p1)-[:Get] ->(p2);
MATCH (p1:Person{FirstName:'Yuzuru'}), (p2:Person{FirstName:'Asao'}) MERGE (p1)-[:Get] ->(p2);
MATCH (p1:Person{FirstName:'Junichiro'}), (p2:Person{FirstName:'Haruki'}) MERGE (p1)-[:Get] ->(p2);

↓なんとなく事件の全貌が見えてきた。

内山と黒島のまわりは複雑。エッジがたくさんでている。
赤矢印(殺害関係)と緑矢印(手に入れた名前)が一致しているところはルール通りに実行している。さらに青矢印(手紙に書いた名前)が繋がっているところはルールに従って連鎖していることがわかる。
大きく2つのグループに分かれる。ただし、切れているところは田中(ドルジ)と桜木のところで、厳密にいうと繋がっているかも。

ということでグラフネットワークを作ってみました。好きなテーマでやると面白いですね。今度はもっと大きいデータでやってみたいです。