ニュース知識グラフで価格予測 — モデルの部品の基礎知識¶
作成日: 2026-11-01
位置づけ: 「ニュース記事を知識グラフにして、BERT と LSTM で価格を予測する」構成の各部品が、何を入れて何を出すかの整理。特定の実験結果は含めない。
関連: 時系列予測の評価と統計_過大評価を避ける_整理
0. 概要¶
一言で: 「記事 → 五つ組 → 文 → BERT のベクトル → 日ごとに平均 → LSTM」。各部品の入出力を押さえれば、構成の全体が読める。
flowchart LR
Article[記事本文]
Quint["五つ組<br>LLM で抽出"]
Text["日本語の文"]
Bert["記事ベクトル<br>768 次元"]
Daily["日ごとのベクトル<br>重み付き平均"]
Price["価格系列"]
Lstm[LSTM]
Out[翌日の終値]
Article --> Quint
Quint --> Text
Text --> Bert
Bert --> Daily
Daily -->|ラグ分だけ前の日| Lstm
Price --> Lstm
Lstm --> Out
| 部品 | 入れるもの | 出すもの | 一言で |
|---|---|---|---|
| 五つ組抽出(LLM) | 記事本文 | 記事ごとに数件の五つ組 | 記事を「誰が何をした」の箇条書きにする |
| 文章化 | 五つ組 | 1 文 | 構造を BERT が読める形に戻す |
| BERT | 文 | 768 次元のベクトル | 文の意味を数字の並びにする |
| 重み付き平均 | 記事ベクトル + 重み | 日ごとのベクトル | その日のニュースを 1 本にまとめる |
| LSTM | 価格系列 + ニュースベクトル | 翌日の終値 | 時系列を順に読んで次を当てる |
1. 知識グラフと五つ組¶
- 三つ組:
(主語, 関係, 目的語)。例:(ある法案, 正の影響, ステーブルコイン) - 五つ組(クインタプル): 三つ組に型と時刻を足したもの。
(head, head_type, relation, tail, tail_type, timestamp) - 型は有限個に絞る。エンティティの型(資産・組織・規制当局・人物・出来事など)と関係の型(発表する・正の影響・負の影響・増加・減少など)を先に決め、LLM の出力をスキーマで検証する
- 記事 1 本が小さなグラフになり、日付ごとに積むと動的知識グラフになる
flowchart LR
H["組織<br>ORG"]
G["法案<br>EVENT"]
S["概念<br>CONCEPT"]
H -->|ANNOUNCE| G
G -->|POSITIVE_IMPACT| S
抽出後の前処理で効くこと¶
| 処理 | なぜ要るか |
|---|---|
| 名寄せ | 同じ実体が表記揺れで別ノードに割れる(大文字小文字、空白)。小文字化と空白除去で一致する表記を最頻のものに統合する。記号は消さない(6.5% と 65% が同じになってしまう) |
| タイムスタンプの統一 | LLM は本文中の別の日付(過去の出来事、将来の予定日)を時刻として入れることがある。公開日より後の日付は未来の情報の漏れになるので、記事の公開日時に置き換える |
| 抽出品質の確認 | 記事ごとの件数が上限ぴったりに偏るなら、件数を埋めるための質の低い関係が混ざっている疑いがある。本文に支持されているかを標本で確かめる |
運用の落とし穴: 推論トークンを使うモデルは、出力上限が小さいと推論だけで上限に達し、空の応答を返すことがある。大量実行の前に少数件で単価と打ち切りを実測する。
2. 知識グラフ埋め込みを使わない理由¶
- TransE: 三つ組が成り立つとき \(\mathbf{h} + \mathbf{r} \approx \mathbf{t}\) になるようベクトルを学習する。一言で「主語に関係を足すと目的語に着く」
- ただしこれはグラフ専用の埋め込みを一から学ぶ方式。予測対象の日数が少ない(千数百日)と、過学習しやすい
- 代わりに、五つ組を文に直して事前学習済みの言語モデルに読ませる。学習するパラメータが増えない
3. 文章化¶
関係タイプを日本語の述語に対応させ、テンプレートで 1 文にする。
\[
\text{文}(q) = \text{「}h_q(\text{型})\text{は}t_q(\text{型})\text{に対して}\text{述語}(r_q)\text{。」}
\]
例: 「Brale(ORG)はUSDPRIME(ASSET)に対して事業活動を行った。」
| 関係 | 述語の例 |
|---|---|
| POSITIVE_IMPACT | ポジティブな影響を与えた |
| NEGATIVE_IMPACT | ネガティブな影響を与えた |
| INCREASE / DECREASE | 増加させた / 減少させた |
| ANNOUNCE | 発表した |
4. BERT と記事ベクトル¶
- BERT: 文を読み、各トークンに文脈込みのベクトルを返す事前学習済みモデル。日本語なら東北大の
bert-base-japanese系が定番 - 記事ベクトル: 先頭の特別なトークン
[CLS]の出力(768 次元)を使う方法と、全トークンの平均を使う方法がある - 重みは固定し、微調整しない(データが少ないため)
- 入力上限は 512 トークン。五つ組を数件連結する程度ならほぼ収まる
| 取り出し方 | 中身 | 注意 |
|---|---|---|
[CLS] |
先頭トークンのベクトル 1 本 | 微調整しない BERT では、文の意味を表すよう訓練されていない |
| 平均 | 全トークンのベクトルの平均 | 文埋め込み用に訓練したモデル(SimCSE、E5 など)なら、そちらの推奨に従う |
5. 日ごとの重み付き平均¶
\[
v_d = \frac{\sum_{i \in I_d} w_i\, e_i}{\sum_{i \in I_d} w_i}
\]
- \(I_d\): d 日に公開された記事の集合、\(e_i\): 記事ベクトル、\(w_i\): 重み
- 全記事 \(w_i = 1\) なら単純平均。重要度スコア \(s_i\) から \(w_i = s_i / 5\) のように決めると、重要な記事を重く扱う
- 相対関係で掴む: 重みが効くのは「記事同士の比」だけ。1 日に数十本あると、重い記事が 1 本あっても平均は大きくは動かない
6. LSTM¶
- LSTM: 時系列を 1 ステップずつ読み、内部の記憶に何を残し何を忘れるかを学ぶ RNN
- 入力: 過去の価格系列(終値・始値・高値・安値・出来高・変化率)。ニュースは、LSTM の最終出力に全結合層で変換したニュースベクトルを結合して、全結合層で予測する
- 検証損失が最小のエポックの重みを採用する(最終エポックを使うと、検証損失の振れで結果が決まる)
7. 用語¶
| 用語 | 意味 |
|---|---|
| RMSE | 予測誤差の二乗平均の平方根。価格と同じ単位。外れた予測に厳しい |
| 方向性一致率 | 上がる / 下がるの向きを当てた割合。ランダムは 50% |
| ラグ | 予測日の何日前のニュースを使うか |
| ウィンドウ | そのラグ日から遡って何日分の記事を平均するか |
| seed / run | 乱数の種 / 1 回の学習と評価。1 seed = 1 run |
| Baseline | 価格だけの LSTM。ニュースの効果を測る対照 |
データ分割(時系列)¶
- 時系列順に、訓練・検証・テストへ分ける。ランダムに混ぜると、未来を見て学習する漏れになる
- 正規化(MinMaxScaler など)は訓練区間だけで fit する。全データで fit すると、テスト期間の値のレンジが訓練に漏れる
- RMSE は水準の誤差なので、前日の終値に近い値を出すだけでも小さくなる。方向性一致率や単純な対照とあわせて見る
8. 参考¶
- Bordes et al. (2013) "Translating Embeddings for Modeling Multi-relational Data" (TransE), NeurIPS 2013
- Li & Passino (2024) "FinDKG: Dynamic Knowledge Graphs with Large Language Models for Detecting Global Trends in Financial Markets", ICAIF 2024, arXiv:2407.10909
- Devlin et al. (2019) "BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding", NAACL 2019
作成: 2026-11-01 / 最終更新: 2026-11-01