GTFS実ダイヤに基づくETA速度較正の改善と都庁前データ修正をmasterへ反映 - #1599
Merged
Merged
Conversation
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* 公開GTFS時刻表から速度較正テーブルを自動生成するスクリプトを追加 compute_average_distance.py と同じ validate/apply パターンで、公共交通 オープンデータセンター等の GTFS フィードから路線×種別ごとの実効最高速度を 較正する scripts/compute_speed_table.py を追加する。 - GTFS の stop_times から平日日中の列車ごとの所要時間を取り、駅名正規化+ 座標(500m/最近傍200m)で自リポジトリの駅データへ名寄せする - 停車パターンを station_station_types の種別グループと照合して kind を判定 - arrival_estimation.rs の運動学モデル(迂回係数較正・通過ペナルティ・ 運転余裕率込み)を Python で再現し、実ダイヤ所要時間の中央値を再現する 実効最高速度を二分探索でフィッティングする - 一般則(路線種別×種別倍率)から±10%以上乖離した路線だけを speed_table.rs の自動生成ブロック(手動テーブルと重複するキーは除外、 手動テーブル優先で lookup)へ書き込む フィード構成: 函館市電(認証不要)、京都市営地下鉄・横浜市営地下鉄 (要 ODPT_ACCESS_TOKEN、https://developer.odpt.org/ で無料発行)。 初回適用として函館市電の較正結果を収録: 市街地併用軌道の実勢に合わせ 2系統 20km/h・5系統 25km/h(一般則の路面電車 40km/h では所要時間を 40〜50% 過小評価していた)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TsvFBx2rLj486tvj64M9eP * __pycache__を.gitignoreに追加 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TsvFBx2rLj486tvj64M9eP * GTFSキャッシュを原子的に書き込み非ZIP応答の恒久キャッシュを防ぐ 一時ファイルへ書いてZIP検証後に os.replace で確定し、ZipFile は with で クローズする。あわせて手動テーブル優先の lookup を回帰検知するテストを追加。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TsvFBx2rLj486tvj64M9eP * 横浜市営地下鉄ブルーライン快速と京都市営地下鉄東西線の速度較正エントリを追加 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
* 速度較正テーブルのデータソース(公共交通オープンデータセンター・OSM)のライセンス表記を追記 README の Data Sources に、速度較正テーブルの元データである京都市交通局・ 横浜市交通局(公共交通オープンデータ基本ライセンス)と函館市企業局交通部 (GTFS-RUL)、および average_distance の元データである OpenStreetMap(ODbL)を 追記する。scripts/README.md には compute_speed_table.py の使い方と フィードごとのライセンス一覧を追加。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TsvFBx2rLj486tvj64M9eP * 西武バスGTFS(公共交通オープンデータ基本ライセンス)の出典表記をREADMEに追記 import.rs の experimental フィードとして取り込んでいる西武バスGTFSの 出典・ライセンスが Data Sources に記載されていなかったため追加する。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TsvFBx2rLj486tvj64M9eP --------- Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* 西武バスGTFSを常時有効化しENABLE_EXPERIMENTAL_BUS_FEATUREフラグを削除 - GtfsFeedのexperimentalフィールドと関連の環境変数判定を削除し、 設定済みの全GTFSフィード(都営バス・西武バス)を常にインポートするように変更 - .env / AGENTS.md / docs/architecture.md / README.md から ENABLE_EXPERIMENTAL_BUS_FEATUREおよびexperimental表記を削除 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVJjKGTcRodoo6TEeiy6he * enabled_gtfs_feeds()を削除しGTFS_FEEDSを直接参照 フィルタリングを行わない薄いラッパーになっていたため、 呼び出し側で GTFS_FEEDS.to_vec() を直接使用する形に変更 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FVJjKGTcRodoo6TEeiy6he --------- Co-authored-by: Claude <noreply@anthropic.com>
* 大江戸線 都庁前の並び順退行を検知するETA回帰テストとデータ検証を追加 都営大江戸線のETAが「一駅分なくなったかのような時間」になる事象を調査。 原因は #1589 の駅ID書き換えで、都庁前(放射部側)と新宿の e_sort が重複 (9930128)したまま station_cd のタイブレークが反転し、並び順が 「…代々木→都庁前→新宿→西新宿五丁目…」に崩れたこと。この状態では 新宿⇔放射部を跨ぐ区間のスライスから都庁前が丸ごと欠落し、全駅のETAが 約1駅分(2分弱)短くなる(実データで数値再現済み)。#1595 の e_sort 連番化で修正済みのため、現行データでは正しい推定になることを確認した。 再発防止として以下を追加: - data_validator: 大江戸線 都庁前前後の並び順(ORDER BY e_sort, station_cd 相当)を検証し、崩れたら fail-fast で失敗させる (#1589 時点のCSVで失敗・現行CSVで成功することを確認済み) - query.rs: 実データ39駅での回帰テスト2件 (新宿→光が丘: 都庁前を含む12駅・約23分 / 光が丘→都庁前: 11駅・約22分) cargo fmt --all -- --check / cargo clippy --all-targets / make test-unit (401 passed) / cargo run -p data_validator ([VALID]) 確認済み。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014At3GiE2fu3ib32cuR7AMQ * ODPTの本番利用可能な鉄道GTFS全フィードを速度較正の対象に追加 公共交通オープンデータセンター(ODPT)の鉄道GTFSを調査し、本番利用可能な ライセンスのフィードをすべて compute_speed_table.py の較正対象に追加: - 都営地下鉄(CC BY 4.0・トークン不要。浅草/三田/新宿/大江戸+都電荒川線・ 日暮里舎人ライナー同梱) - 東京メトロ・つくばエクスプレス・多摩都市モノレール・りんかい線 (公共交通オープンデータ基本ライセンス・要 ODPT_ACCESS_TOKEN) 京王・相鉄・東武はチャレンジ限定ライセンス(api-challenge配信)のため 従来方針どおり対象外(README に明記)。 スクリプトの改善: - 同名駅が同一路線に複数あるケース(大江戸線 都庁前の2レコード)で駅マッチングが 先頭固定になり列車が全滅する問題を修正。候補列から単調割当(span最小)を選ぶ resolve_monotonic を導入し、6の字直通・環状一周も正しく扱う - --apply をマージ型に変更。トークン未設定でスキップしたフィード由来の既存 エントリ(京都・横浜)が消えないようにし、再較正で閾値未満になったキーだけ削除 較正結果(トークン不要フィードのみで実行): - 都営浅草線 Default 65km/h / エアポート快特 55km/h、都電荒川線 25km/h を自動追加 - 都営大江戸線は自動フィット60km/hを不採用とし、手動テーブルに公表最高速度 70km/h で較正エントリを追加。自動値はサンプルの大半が6の字全区間直通 (実83〜88分)で環状部の急曲線に引きずられ、放射部が+14%と実測から外れるため。 70km/h では全ベンチマーク(放射部実11分・新宿→光が丘実24分・光が丘→都庁前 実22分・清澄白河→赤羽橋実16分・全区間実85分)が±9%以内に収まる cargo fmt --check / cargo clippy / make test-unit (401 passed) / python3 scripts/compute_speed_table.py --validate 確認済み。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014At3GiE2fu3ib32cuR7AMQ * GTFS実ダイヤによる隣接駅間別の速度較正(segment_speed_table)を追加 路線×種別単位の速度較正は路線内で一様な実効速度を仮定するため、都営大江戸線の 環状部南側(月島〜赤羽橋の河川横断・急勾配・急曲線区間)のように路線平均より 2〜3割遅い区間の残差(清澄白河→赤羽橋 実16分 vs 推定14.7分)を原理的に解消 できなかった。公開GTFS時刻表から隣接駅ペア単位で実効速度をフィットする 較正テーブルを新設し、この区間差を反映する。 - domain/segment_speed_table.rs を新設。(line_cd, 駅cd小, 駅cd大, km/h) の 生成テーブルと二分探索ルックアップ、適用種別の判定(各停系=速度倍率1.0のみ。 急行・特急は各停実ダイヤ由来の駅間速度で引き下げない)を提供 - arrival_estimation: 駅間サブセグメントの速度決定で駅間別較正を路線単位より 優先(鉄道・各停系のみ) - get_train_route: クライアント物理シミュレーション用セグメントの max_speed too 同様に駅間別較正で上書き - compute_speed_table.py: 駅間別較正の生成を追加。駅間の純走行時間(次駅到着 時刻があれば出発→到着、無ければ出発→次駅出発−モデル停車時分)を複数本の 平均でデクオンタイズ(GTFSの時刻は分丸めのため)し、路線較正値から±5%以上 乖離したペアだけを出力。到着時刻を優先しないと停車時分を二重計上して駅間 速度を系統的に過小評価する。--apply はマージ型(未較正路線のエントリ保持) 較正結果(都営+函館のトークン不要フィード、71ペア): - 清澄白河→赤羽橋: 14.66分 → 16.05分 (実16分、-8.4% → +0.3%) - 新宿→光が丘 24.75(実24) / 光が丘→都庁前 22.72(実22) / 落合南長崎→光が丘 11.53(実11) / 6の字全区間 83.2(GTFS実85) と全域±5%以内 - 清澄白河→赤羽橋の回帰テストを追加(15.0..17.0) cargo fmt --check / cargo clippy --all-targets / make test-unit (405 passed) / python3 scripts/compute_speed_table.py --validate 確認済み。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014At3GiE2fu3ib32cuR7AMQ * ./scripts/compute_speed_table.py --apply * 直通優等種別が線内各駅停車になる路線で種別速度を適用しない 半蔵門線 押上→神保町のように、直通元では急行でも当該路線内は全駅に停車する ケースで、種別(Express)の速度倍率×1.15が掛かり駅間別較正も外れて、各停の 正しい推定18分が15分に縮む問題を修正。 経路スライス内でその路線に通過駅(pass=1 / StopCondition::Not)が一つも 無ければ、優等種別でも実質各駅停車として走っているとみなし、種別を Default 相当に落として速度を決める(種別倍率なし・Default の路線較正・駅間別較正を 適用)。通過駅がある路線では従来どおり種別の速度を使う。優等列車の実経路 スライスには通過駅が pass=1 行として必ず含まれるため、真の速達区間の挙動は 変わらない。 - arrival_estimation / get_train_route の両方に適用 - 半蔵門線 実データでの回帰テストを追加(押上→神保町: 急行==各停 ≈18分) - 通過駅なしの合成経路で優等倍率を前提にしていた既存テスト2件を、通過駅を 含む構成に修正(実データの優等経路には通過駅行が必ず含まれる) cargo fmt --check / cargo clippy --all-targets / make test-unit (407 passed) 確認済み。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014At3GiE2fu3ib32cuR7AMQ * レビュー指摘対応: 駅間マージのペア単位化と通過駅判定の端点除外 CodeRabbitレビュー(#1597)の指摘3件+リファクタ1件に対応: - compute_speed_table.py: --apply の駅間エントリ置換判定を路線単位から (line_cd, 駅cd小, 駅cd大) のペア単位に変更。路線単位だと、時刻データ欠損等で 今回評価できなかったペアの較正済みエントリが巻き添えで消えるため。 評価済み(サンプル数・フィット・妥当性チェック通過)のペアだけを置換・削除 対象にする。トークンなしで --apply を再実行しても生成テーブルに差分が 出ないこと(メトロ等233エントリ保持)を確認済み - arrival_estimation: line_has_pass の通過駅判定を is_stop と同じ端点補正込みの stops_here ベースに変更(端点の pass=1 だけでは優等扱いにしない)。 端点passに依存していたテスト2件を中間通過駅を持つ構成に修正 - get_train_route: 同様に端点を除外して中間通過駅のみを優等扱いの根拠にする (TrainRouteSegment.stops の意味は従来どおり変更しない) - compute_speed_table.py: calibrate_feed から駅間サンプル収集を collect_segment_samples ヘルパーへ切り出し(挙動変更なし) cargo fmt --check / cargo clippy --all-targets / make test-unit (407 passed) 確認済み。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014At3GiE2fu3ib32cuR7AMQ * 銀座線短区間のGTFS速度較正を改善 * テストの useless vec! による clippy 警告を解消 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014At3GiE2fu3ib32cuR7AMQ * 駅間較正の診断機能(--dump-line)と実験的な繰り越し補正(--rebalance)を追加 メトロ系路線で駅間別較正が過大になる報告(銀座線 渋谷→新橋 14.2分 vs 実13、 千代田線 綾瀬→新御茶ノ水 18.7分 vs 実15〜16)の調査用。 原因の構造: - GTFSの駅時刻は分単位で、タイムポイント以外の駅では時刻割付が隣接ペア間で 偏る(例: 千代田線 西日暮里→千駄木 平均0.7分 / 千駄木→根津 平均2.1分)。 短すぎる側はフィット時に運動学的下限へクランプされ縮められない一方、 長すぎる側はそのまま再現されるため、合計が系統的に過大になる(非対称バイアス) - 一方、到着時刻が別記録されている駅では純走行時間ベースの較正になり、 分丸めされた停車時分を避けられる。都営はこの2つの逆向きバイアスが相殺して 精度が出ており、繰り越し補正を無条件に適用すると逆に過小になる (大江戸線 清澄白河→赤羽橋 15.8→14.4分に悪化することを確認) 追加機能: - --dump-line LINE_CD: ペアごとの本数・到着時刻ベースのサンプル数・生平均・ 補正後・運動学的下限・フィット結果を表示(フィード実データでの切り分け用) - --rebalance(実験的・既定OFF): 下限を下回るペアの不足分を同一走行の 隣接ペアへ繰り越して合計を保存する補正。--dump-line で生平均の偏りを 確認してから使う - サンプルに到着基準/出発間隔基準の出所を記録(平均値・出力は不変) 既定の --apply の生成結果はコミット済みテーブルと完全一致(挙動変更なし)。 make test-unit (408 passed) / py_compile 確認済み。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014At3GiE2fu3ib32cuR7AMQ * 駅間較正の推定器を改善: 到着時刻優先+出発間隔のみのペアはトリム平均 --dump-line 28005 の実データで判明した事実に基づく改善: - 東京メトロのGTFSは全駅で到着時刻=出発時刻(純走行時間が観測できない) - そのため全ペアが「出発間隔−モデル停車時分」で較正され、接続待ちの折込み (北綾瀬〜綾瀬 平均4.67分、綾瀬〜北千住 平均3.40分)や分丸めされた停車時分が そのまま駅間時間に乗り、千代田線 綾瀬→新御茶ノ水が18.7分(実15〜16)に膨張 - 都営は到着時刻ベースのサンプルが豊富で正確だった 推定器の変更: - 到着時刻ベース(純走行時間)のサンプルが5本以上あるペアはそれだけを使う (出発間隔ベースと混ぜると停車時分ぶんの系統誤差になる) - 出発間隔ベースしか無いペアは上位30%を除去したトリム平均を使う (接続待ち・時隔調整の折込みは分布の上側に偏るため) トークン不要フィードでの検証: 大江戸線 清澄白河→赤羽橋 16.04分(実16)・ 新宿→光が丘 24.86(実24)・光が丘→都庁前 22.62(実22)・落合南長崎→光が丘 11.56(実11)と全ベンチマーク±7%以内。make test-unit (408 passed)。 メトロの再較正には ODPT_ACCESS_TOKEN 環境で `python3 scripts/compute_speed_table.py --apply` の再実行が必要。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014At3GiE2fu3ib32cuR7AMQ * 速度セグメントテーブルを更新 * 繰り越し補正を出発間隔ベースのみのペア連続区間に限定して既定有効化 タイムポイント補間の偏り(隣接ペアの一方が運動学的下限未満・他方が過大)への 繰り越し補正を、出発間隔ベースでしか較正できないペアの連続区間に限定して 既定で有効にする。--rebalance フラグは削除。 到着時刻ベース(純走行時間)で較正できたペアには適用せず、鎖もそこで分断する。 純走行時間の「下限未満」は補間アーティファクトではなく、モデルの保守的な 加減速下限より実車が速いだけであり、繰り越すと実測に合っていた区間まで 過小になる(大江戸線 清澄白河→赤羽橋 16.04→14.73 に悪化することを確認済み)。 トークン不要フィードでの検証: 大江戸線ベンチマーク4区間すべて不変 (16.04 / 24.86 / 22.62 / 11.56)。補正が適用されるのは函館市電・都電荒川線の dep-onlyペア列のみ。メトロ(全ペアdep-only)はトークン環境での --apply 再実行で 全鎖に補正が掛かり、千代田線 綾瀬→新御茶ノ水のクランプ由来の過大(約+1分)が 解消される見込み。make test-unit (408 passed)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014At3GiE2fu3ib32cuR7AMQ * 速度セグメントテーブルを再更新 * 半蔵門線回帰テストの許容範囲を較正ポリシー(実所要±10%)に合わせる メトロの駅間別較正(トリム平均+繰り越し補正)の再生成で押上→神保町が 17.2分→16.8分(実18分、-6.7%)となり、旧境界17.0..19.5をわずかに下回った。 テストの主目的は「線内各駅停車の直通急行 == 各停」の検証であり、 所要時間の境界は較正ポリシーの±10%(16.2..19.8)に揃える。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014At3GiE2fu3ib32cuR7AMQ * 駅間サンプルの型注釈を実体(値=(時間, arr|dep)タプル)に合わせる collect_segment_samples が (target, "arr"|"dep") のタプルを積むように 変わった際に、seg_samples / all_seg_samples の型注釈が list[float] の ままだったので list[tuple[float, str]] に修正する(挙動変更なし)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014At3GiE2fu3ib32cuR7AMQ * 駅間較正の出典コメントを駅間ペア単位で全フィード保持に変更 seg_feed_of が line_cd キーで上書きされるため、複数フィードが同一 路線・駅間に寄与した場合に出典コメントが最後のフィード名だけに なっていた。駅間ペアをキーに集合で保持し、出力時は全出典を 「・」区切りで並べる(現状は路線とフィードが 1 対 1 のため生成結果は 不変)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014At3GiE2fu3ib32cuR7AMQ --------- Co-authored-by: Claude <noreply@anthropic.com>
Contributor
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
devに溜まっていた GTFS 実ダイヤに基づく ETA 速度較正の一連の改善・都営大江戸線 都庁前のデータ修正・西武バス GTFS の常時有効化(#1589〜#1598)をmasterへ反映する。変更の種類
変更内容
到着時間推定(ETA)・速度較正
データ修正(都営大江戸線 都庁前)
その他
テスト
cargo fmt --all -- --checkが通ることcargo clippy -- -D warningsが通ることcargo test(SQLX_OFFLINE=true)が通ること関連Issue
スクリーンショット(任意)