fbpx

CL LAB

HOME > Blog > lee > 婚活支援プロジェクト(2/4): データ処理と問題点 #neo4j

婚活支援プロジェクト(2/4): データ処理と問題点 #neo4j

 ★ 2

前回の「婚活支援プロジェクト:構想からデータモデル設計まで」では、婚活に必要な基礎情報を収集し、理想的な相手を予測する方式の決定、データモデリングまでを行いました。今回は、前回のデータモデルに基づいてグラフデータベースを作成し、実際に候補者を予測してみたいと思います。
第1回目:構想からデータモデル設計まで
第2回目:データ処理と問題点
第3回目:どのように改善したらいいのか
第4回目:改善したデータモデルによるデータ処理

事前準備

Neo4jサーバのインストール

Neo4jが初めてという方は、次のサイトを参照してNeo4jサーバーをインストールしてください。OSは、WindowsやMac、Linuxが対応しています。今回の記事ではWindows版を使用しています。以下のページが参考になると思います。

Cypher Query Language(QL)-初級編
qitta.com/awk256

データストアのフォルダー作成

今回のグラフデータベース(以下、GDB:Graph Data Base)を格納するための空のフォルダーを用意してください。
今回の記事では以下のフォルダーを作成しています。作成後、Neo4jを起動する際にGDB用のフォルダーを選択して実行します。

C:¥Users¥Documents¥Neo4j¥konkatu.db

Mac/Linuxの場合は、次のようにフォルダーを作成してください。その後にNeo4jサーバを起動、又は再起動してください。

data/konkatu.db

ただし、Linux版の場合は起動前にconf/neo4j-server.propertiesを編集する必要があります。

org.neo4j.server.database.location=data/konkatu.db

 

Neo4jへのデータロード

これから、前回調査した婚活関連情報とデータモデル設計に基づいてGDBにデータをロードする過程を説明します。

 GDBにデータをロードする方法

前回の調査で理想的な相手を予測するためのデータのモデリングを行いましたが、それらのデータを GDBに登録しなければなりません。GDBにデータを登録する方法は複数あり、データのサイズや状況に応じて使い分けることができます。今回は CypherクエリーとLOAD CSV文を利用します。また参考のために、Neo4jImportを使う方法、APIを利用する方法を合わせて紹介しています。

  • Cypherクエリーを利用する方法

少量のデータを稼働中のGDBに登録する場合は、ダイレクトにCypherクエリーを書いて実行する方法が簡単です。Cypherクエリーは、Webブラウ ザーやNeo4jShell(neo4j-shell)から実行できます。勿論、プログラムに埋め込んで大量データを扱うことも可能です。

  • LOAD CSV文を利用する方法

比 較的大量のデータを稼働中のGDBに登録する場合は、LOAD CSV文を利用します。LOAD CSV文は、第1行目がカラム名になっているCSVファイルを入力データとして使います。一旦、CSVファイルからデータを読み込んだ後に、Cypher クエリーでデータ操作を行います。

  • Neo4jImport(neo4j-shell)を利用する方法

Neo4jImport(neo4j- import)は、大量のデータを最も高速にGDBに登録できる方法です。入力データは、若干書式は異なりますが、LOAD CSV同様のCSVファイルを利用します。Neo4jImportは、常に新しいデータベースファイルを作成するため、既存のGDBに対して追加や更新な どの用途では使えません。さらに、関係性のリンクなどを事前に定義しておく必要があるなどの手間が掛かります。但し、既存のリレーショナルデータベースな どからNeo4jへの移行の場合は、SQLで関係性を作成できるためとても有効な手段の一つになります。勿論、少量のデータに使っても問題はありません。

  • APIを利用する方法

Neo4j は、JavaのNative APIとREST APIでプログラムを開発し、グラフデータを操作することが可能です。これは、なにかしらのサービスシステムとしてNeo4jを組み込んで利用する場合は 必須の機能になるでしょう。REST APIを使う場合は、Java, .NET, PHP, JavaScript, Ruby, Pythonなど、多様な言語が利用できます。

候補者のオリジナルデータをダウンロード

今回は、男女、それぞれ30人分のデータを用意しています。データをダウンロードし、「C:/temp/data/Man2.csv」、「C:/temp/data/Woman2.csv」のように格納してください。

男性データ:Man2.zip
女性データ:Woman2.zip

このような作業が面倒くさいという方は、完成版のGDBをダウンロードして利用してください。完成版のGDBを利用する方は、「Neo4jへのデータロード」は内容を把握する程度にし、「分析及び予測シナリオの作成と実行」へ進んでください。絶対、完成版のGDB(konkatu.gdb)の上にデータをロードしては行けません。すべてのノードが2重になり、Cypherクエリーから正しい結果を期待できなくなります。

完成版のGDBのダウンロード:konkatu.gdb.zip

プライマリドメインのノード作成

まず候補者のノードを作成します。次のLOAD CSV文をWebインターフェースでそれぞれ実行してください。

男性

LOAD CSV WITH HEADERS FROM "file:///C:/Temp/data/Man2.csv" AS line
CREATE (:Person:Man { name:line.name})

女性

LOAD CSV WITH HEADERS FROM "file:///C:/Temp/data/Woman2.csv" AS line
CREATE (:Person:Woman { name:line.name})

サブドメインのノード作成

次は候補者の属性を表す20種のサブドメインのノードを登録するCypherクエリーをWebインターフェースで実行してください。Neo4jShellを使う場合は、構文の末尾にセミコロン(;)を付けてください。

WITH ["野球","サッカー","バレーボール","バスケットボール","テーブルテニス","ヨガ","散歩","ダンス","その他"] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (a1:Sport {title: list[i]}))

WITH ["土日祝日","平日","不定期"] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (b1:Holiday {title: list[i]}))

WITH ["聞くタイプ","話すタイプ","とちらでも良い"] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (c1:Talk {title: list[i]}))

WITH ["積極的","消極的","とちらでもない"] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (d1:Meeting {title: list[i]}))

WITH [140,150,160,170,180,190,200] as list
FOREACH(i IN range(0, length(list)-1) |
CREATE (e1:Height {title: list[i]}))

WITH ["外向的","内向的"] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (f1:Personality {title: list[i]}))

WITH ["読書","映画感想","音楽感想","TV感想","ゲーム","寝る","友たちとお喋り","料理を作る","その他"] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (g1:Indoor {title: list[i]}))

WITH ["吸う","吸わない"] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (h1:Smoking {title: list[i]}))

WITH ["飲む","飲まない"] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (j1:Alcohol {title: list[i]}))

WITH ["好き","嫌い"] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (k1:Karaoke {title: list[i]}))

WITH ["信じる","信じない"] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (m1:Fortunetelling {title: list[i]}))

WITH ["意識して運動する","特に意識していない"] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (n1:Healthcare {title: list[i]}))

WITH ["海","山","川","公園","遊園地","どちらでもいい"] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (o1:Outdoor {title: list[i]}))

WITH [100,200,300,400,500,600,700,800,900] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (p1:Income {title: list[i]}))

WITH ["北海道","青森県","岩手県","宮城県","秋田県","山形県","福島県","茨城県","栃木県","群馬県","","埼玉県","千葉県","東京都","神奈川県","新潟県","富山県","石川県","福井県","山梨県","長野県","岐阜県","静岡県","愛知県","三重県","滋賀県","京都府","大阪府","兵庫県","奈良県","和歌山県","鳥取県","島根県","岡山県","広島県","山口県","徳島県","香川県","愛媛県","高知県","福岡県","佐賀県","長崎県","熊本県","大分県","宮崎県","鹿児島県","沖縄県"] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (q1:Location {title: list[i]}))

WITH ["有り","無し"] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (r1:Maritalhistory {title: list[i]}))

WITH ["犬派","猫派"] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (s1:Pet {title: list[i]}))

WITH ["義務教育","高等学校","各種専門学校","短大・高専","大学","大学院"] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (t1:Education {title: list[i]}))

WITH ["公務員","会社員","自営業","企業経営・役員","教師","医師","医療関係","保育士","農林・漁業","パート・アルバイト","学生","家事手伝","その他"] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (u1:Job {title: list[i]}))

WITH [1995,1994,1993,1992,1991,1990,1989,1988,1987,1986,1985,1984,1983,1982,1981,1980,1979,1978,1977,1976,1975,1974,1973,1972,1971,1970] AS list
FOREACH(i IN range(0, length(list)-1) |
CREATE (v1:Born {title: list[i]}))

実行が終了したら、左のメニューバーを開いて「Node Labels」のラベル名をクリックし、それぞれのノードを確認してください。

node-labels

以下は、「Education」をクリックした時の例です。

education-nodes

候補者とサブドメインのノードとの関係性作成

今回のデータは、それぞれの男女に対して20種類のサブドメインの要素をランダムに割り振っています。このようなデータの関係性の作成は、とても難しいように思われるかも知れませんが、Cypherではとても簡単に記述できます。
LOAD CSV文のテストをしてみたい場合は、「RETURN * LIMIT 25」文までを実行してみてください。名称の不一致やデータの不在などは、ここで検知できます。Webインターフェースで以下のクエリーをそれぞれ実行してください。

男性

LOAD CSV WITH HEADERS FROM "file:///C:/Temp/data/Man2.csv" AS line
MATCH
(man:Person:Man { name: line.name }),
(sport:Sport { title: line.sport}),
(holiday:Holiday { title: line.holiday}),
(talk:Talk { title: line.talk}),
(meeting:Meeting { title: line.meeting}),
(height:Height { title:toInt(line.height)}),
(personality:Personality { title: line.personality}),
(indoor:Indoor { title: line.indoor}),
(smoking:Smoking { title: line.smoking}),
(alcohol:Alcohol { title: line.alcohol}),
(karaoke:Karaoke { title: line.karaoke}),
(fortunetelling:Fortunetelling { title: line.fortunetelling}),
(healthcare:Healthcare { title: line.healthcare}),
(outdoor:Outdoor { title: line.outdoor}),
(income:Income { title:toInt(line.income)}),
(born:Born { title:toInt(line.born)}),
(location:Location { title: line.location}),
(maritalhistory:Maritalhistory { title: line.married}),
(pet:Pet { title: line.pet}),
(education:Education { title: line.education}),
(job:Job { title: line.job})
//RETURN * LIMIT 25
CREATE
man-

Author

データベースが大好きなサーバサイドのエンジニア。現代的なデータ基盤のソリューションアーキテクトとして活動しています。

[著書]
グラフデータベースNeo4jの他
https://www.amazon.co.jp/李昌桓/e/B004LWEKOU

leeの記事一覧

CL LAB Mail Magazine

CL LABの情報を逃さずチェックしよう!

メールアドレスを登録すると記事が投稿されるとメールで通知します。

メールアドレス: 登録

※登録後メールに記載しているリンクをクリックして認証してください。

Related post

[無料ウェビナー] GitLab_CI/CDハンズオン_2023111