graphDB graphRAG の他の用途として
経済・金融データ分析
例: 経済指標・株価・商品価格・為替などの相関関係をグラフ構造に保存し、RAGで「現状と過去の類似パターン」を取得。
メリット:
価格・イベント・ニュースの因果関係を把握できる
RAGで時系列説明やリスク分析を生成可能
シナリオ:
質問:「過去10年間でWTIが急落したときの共通要因は?」
処理: GraphDBで急落イベントと関連経済指標を探索 → RAGが文章化
これを作成したい
GPTの答えを自分なりにまとめる
急落イベントの自動生成
閾値は2通り用意(どちらか一致でイベント化):
* 絶対閾値: return1d <= -0.05
* 統計的閾値: zscore <= -2.0
// 急落イベント生成
MATCH (a:Asset {symbol:"WTI"})-[:HAS_PRICE]->(p:Price)
WHERE p.return1d <= -0.05 OR p.zscore <= -2.0
MERGE (e:Event:PriceDrop {date:p.date, asset:"WTI"})
ON CREATE SET e.threshold = CASE WHEN p.return1d <= -0.05 THEN "ret<=-5%" ELSE "z<=-2" END
MERGE (e)-[:ON_ASSET]->(a)
MERGE (e)-[:NEARBY_PRICE {lag:0}]->(p);
共起(要因候補)のひも付け
イベント±3営業日程度の窓で、関連しそうなファクトを CO_OCCURS_WITH で結ぶ。
// 経済指標サプライズと共起
MATCH (e:Event:PriceDrop {asset:"WTI"})
MATCH (ip:IndicatorPrint)
WHERE date(ip.date) >= date(e.date)-duration('P3D') AND date(ip.date) <= date(e.date)+duration('P3D')
MERGE (e)-[:CO_OCCURS_WITH {window:"±3d"}]->(ip);
// ドル指数(DXY)急騰など他資産の大変動
MATCH (e:Event:PriceDrop {asset:"WTI"})
MATCH (p:Price {asset:"DXY"})
WHERE date(p.date)=date(e.date) AND (p.return1d >= 0.01 OR p.zscore >= 2.0)
MERGE (e)-[:CO_OCCURS_WITH {window:"0d"}]->(p);
// ニュース(トピック抽出済み)も結ぶ
MATCH (e:Event:PriceDrop {asset:"WTI"}), (n:News)
WHERE date(n.date) >= date(e.date)-duration('P1D') AND date(n.date) <= date(e.date)+duration('P1D')
AND n.topic IN ["OPEC","在庫","中東地政学","需要見通し","景気後退懸念"]
MERGE (e)-[:CO_OCCURS_WITH {window:"±1d"}]->(n);
自動タグ付け(要因ノード化)
共起オブジェクトから 要因タグを抽出・集計して :Factor を作り、イベントと結ぶ。
// 例:DXY急騰なら「ドル高」を付与
MATCH (e:Event:PriceDrop)-[:CO_OCCURS_WITH]->(p:Price {asset:"DXY"})
WHERE p.zscore >= 2.0 OR p.return1d >= 0.01
MERGE (f:Factor {name:"ドル高急伸"})
MERGE (e)-[:HAS_FACTOR {type:"market"}]->(f);
// 例:在庫サプライズ(EIA原油在庫が予想比+)
MATCH (e:Event:PriceDrop)-[:CO_OCCURS_WITH]->(ip:IndicatorPrint)<-[:PUBLISHED_AS]-(:Indicator {code:"EIA_CRUDE_INV"})
WHERE ip.surprise > 0
MERGE (f:Factor {name:"EIA在庫予想超過(増)"})
MERGE (e)-[:HAS_FACTOR {type:"supply"}]->(f);
// 例:ニューストピックから
MATCH (e:Event:PriceDrop)-[:CO_OCCURS_WITH]->(n:News)
WHERE n.topic IN ["OPEC","増産","協調減産不履行"]
MERGE (f:Factor {name:"OPEC供給ニュース"})
MERGE (e)-[:HAS_FACTOR {type:"policy"}]->(f);
回答から見ると
急落イベントの定義が必要
そして要員候補を定義し
Cyperで紐付け定義している
この要員候補が共起となるので
この共起をもとに
要因タグを抽出・集計して :Factor を作り、イベントと結ぶ
過去10年の共通要因」を求めるCypherを作成
ここまでできたら
GraphRAG(LlamaIndex例)
を作成
ゼロからやっていくとして やることの順番
0. 目的と範囲の固定(30分で決め切る)
目的:WTI急落の共通要因を、数値+ニュース根拠つきで説明・検知できる。
やること
* 期間:直近10年(例:2015-01-01〜)
* 対象:WTI, DXY, EIA原油在庫, 主要マクロ(CPI/NFP/ISM), ニュース見出し
* 急落定義:ret1d ≤ -5% または zscore ≤ -2
* 共起窓:±3日
完了条件:上記をREADMEに明文化。
1. 環境・リポジトリ準備
やること
* Gitリポジトリ作成:/graph-wti-poc
* Python 3.11系、仮想環境
* 依存:neo4j, pandas, numpy, python-dateutil, llama-index-graph-stores-neo4j, llama-index
* Neo4j(Docker可)起動、パスワード設定
完了条件:make setup && make testでimportなしのスモークテストが通る。
2. データの最小セットを落とす(まずはCSVでOK)
やること
* data/price_wti.csv(日次 Date, Close)
* data/price_dxy.csv
* data/eia_crude_inv.csv(週次 Date, actual, consensus)
* data/macro_{cpi,nfp,ism}.csv(Date, actual, consensus)
* data/news_titles.csv(Date, title, source, topic?)
完了条件:CSVが所定フォーマットで保存され、scripts/validate_csv.pyで列チェックOK。
3. グラフ・スキーマ定義
やること
* ノード:Asset, Price, Indicator, IndicatorPrint, News, Event:PriceDrop, Factor
* リレーション:HAS_PRICE, PUBLISHED_AS, ON_ASSET, NEARBY_PRICE, CO_OCCURS_WITH, HAS_FACTOR, MENTIONS
* インデックス/制約:Asset(symbol), Price(date,asset), Indicator(code), IndicatorPrint(date,code)
完了条件:scripts/init_schema.cypherを一発実行で作成される。
4. ETL(投入)——最小データ→Neo4j
やること
* scripts/load_assets.py(WTI/DXYなど)
* scripts/load_prices.py(ret1d/zscore計算込み)
* scripts/load_indicators.py(surprise = actual−consensus)
* scripts/load_news.py(topicは暫定でも可)
完了条件:Neo4j上でノード・関係の件数が期待範囲にある(簡易Cypherで確認)。
5. 急落イベント生成
やること
* jobs/mk_price_drop.cypher
* ルール① ret1d ≤ -0.05
* ルール② zscore ≤ -2.0
* イベント→資産・当日価格ノードへリンク
完了条件:MATCH (:Event:PriceDrop)で複数件が生成される。
6. 共起リンク付け(±3日)
やること
* jobs/link_cooccurrence.cypher
* Event ↔ IndicatorPrint(±3日)
* Event ↔ Price(DXY)(同日/±1日、急騰条件付き)
* Event ↔ News(±1日、topicフィルタ)
完了条件:各EventにCO_OCCURS_WITHが最低1件以上付く。
7. 要因タグ自動付与(Factor化)
やること
* ルールベースで開始(後でMLに発展)
* DXY急騰→「ドル高急伸」
* EIA在庫サプライズ>0→「在庫増サプライズ」
* News.topic in {OPEC, 需要減速, 地政学}→対応Factor
* jobs/mk_factors.cypher
完了条件:MATCH (e:Event)-[:HAS_FACTOR]->(f)がヒット、因子名の重複がない。
8. 集計クエリ(分析の芯)
やること
* TOP要因:頻度ランキング
* 事例リスト:各イベントと要因・信号の要約
* 反証:急落“でない”日との比較(同じ要因の出現率差)
完了条件:Cypher 3本がqueries/に保存され、結果がCSV/JSONで出力できる。
9. GraphRAG 接続(LlamaIndex最小構成)
やること
* Neo4j GraphStore接続
* ニュース本文(任意)をVector Index化
* 「イベント周辺サブグラフ抽出→要約」QueryEngine
完了条件:python rag_answer.py “過去10年のWTI急落の共通要因は?”が自然文で答えを返す。
10. 評価(人間の目で妥当性チェック)
やること
* ランダムに5〜10イベントを抽出し、当日の実ニュースと比較
* 誤検知/過検知の原因をメモ(topic付与・閾値調整など)
完了条件:改善ポイントのTODOが/docs/findings.mdにまとまる。
11. ルールのチューニング(再実行可能に)
やること
* 閾値・窓幅(±2/±3/±5日)、surpriseの標準化(z化)を切替可能に
* パラメタは.envやconfig.yamlへ
完了条件:make rebuild-with CONFIG=config.yamlで全処理が再実行できる。
12. アラート原型(将来の運用)
やること
* シンプルな条件2〜3本(例:WTI -3%以上&DXY +0.8%以上)
* 該当日の証跡(どの要因に引っかかったか)をテキスト生成
完了条件:CLIで日次スキャン→標準出力に最新ヒットを表示。
13. 可視化ミニUI(任意:後付け)
やること
* Streamlit or Dash
* タイムライン(急落イベント)
* ヒートマップ(要因×年)
* クリックで当日の共起ニュース・指標を展開
完了条件:ローカルで1ページ表示、スクリーンショット保存。
14. データ運用・再現性
やること
* Makefile:make all, make clean
* 週次/日次ジョブ(将来)向けに/jobs/を分離
* バックアップ手順(Neo4j dump, data/ バージョン付け)
完了条件:READMEに再現手順とバックアップ復元手順が記載。
まず動かす最短ルート(PoC 版)
1. 0→1→2(最小CSV)
2. 3(スキーマ)
3. 4(ETL投入)
4. 5(急落生成)
5. 6(共起リンク)
6. 8(要因TOP集計)
7. 9(RAG回答の骨格)
ここまでで**「数値+ニューストピックに基づく共通要因の説明」**が出ます。
その後、7(Factor強化)→11(チューニング)→12(アラート)→13(UI)で育てればOK。