サーバー側(izu-ir)引き継ぎ資料 — ノーツレーダー全特徴量の伝送仕様¶
本体(beatoraja)側で #314/#315/#316 を通じて実装した特徴量を、スコア送信時に IRChartData.values(Map<String,String>)として feature_* キー81個で IR へ送出する。サーバーは集計・保持・正規化・#293接続が責務。以下はサーバー実装に必要な全情報。
0. 最重要の注意(命名の非対称)¶
-
6主軸は歴史的経緯で
_radar 接尾辞なしだが 0–200 正規化済み:feature_notes_density / feature_peak_density / feature_scratch_density / feature_charge / feature_chord / feature_soflan。
-
サブ軸は raw=接尾辞なし、正規化=
_radar 接尾辞。例:feature_pattern_jack=raw、feature_pattern_jack_radar=0–200 正規化。
- したがって「
_radar が付くもの+6主軸」が 0–200 値、それ以外(6主軸を除く接尾辞なし feature_*)は raw。
1. 81キーの分類¶
(A) 0–200 正規化値=33個(サーバーは原則これを再正規化しない)
- 6主軸(接尾辞なし):
feature_notes_density / _peak_density / _scratch_density / _charge / _chord / _soflan
- 新規親軸2個:
feature_pattern_radar / feature_rhythm_radar(子サブ軸 _radar の単純平均)
- A分類サブ軸
_radar 10個 / B分類サブ軸 _radar 15個
(B) raw 値=48個(サーバーが独自正規化したい場合に利用可)
- 6主軸の生入力・中間量23個(
feature_notes_total / _duration_seconds / _peak_window_notes / _scratch_total / _scratch_peak_window_notes / _ln_total / _ln_seconds_total / _charge_notes_during_ln / _charge_notes_during_ln_peak_window / _max_simultaneous_ln / _chord_timeline_count / _max_chord_size / _chord_peak_window_score / _chord_peak_window_notes / _speed_change_count / _stop_count / _scroll_change_count / _soflan_weighted_notes / _soflan_cluster_count / _soflan_affected_notes / _soflan_cluster_score / _soflan_max_change_rate / _soflan_stop_time_total)
- A分類 raw 10個・B分類 raw 15個(下表)
2. ドリルダウン木構造(#293 親→サブ)¶
| 親軸(0–200キー) |
子サブ軸(raw / 正規化=_radar) |
NOTES feature_notes_density
|
notes_density_peak_1s, notes_local_hardness, notes_density_peak_10s, notes_endgame |
PEAK feature_peak_density
|
peak_burst_1s, peak_sustained_3s |
SCRATCH feature_scratch_density
|
scratch_bss, scratch_single, scratch_ren, scratch_complex |
CHARGE feature_charge
|
(サブ軸なし) |
CHORD feature_chord
|
chord_max_size, chord_gachioshi, chord_denim, chord_jika |
SOF-LAN feature_soflan
|
soflan_accel, soflan_decel, soflan_stop, soflan_visual |
PATTERN(新規)feature_pattern_radar |
pattern_jack, pattern_trill, pattern_kaidan, pattern_randa |
RHYTHM(新規)feature_rhythm_radar |
rhythm_24th, rhythm_henpyoshi, rhythm_irregular |
親軸値:feature_pattern_radar = (jack+trill+kaidan+randa の各 _radar)/4、feature_rhythm_radar = (24th+henpyoshi+irregular の各 _radar)/3。NOTES/PEAK/SCRATCH/CHORD/SOF-LAN は既存6主軸値がそのまま親。
3. 正規化方式(0–200)¶
-
既存6主軸と完全に同一方式:raw を分位点アンカー(
*_SCORE_ANCHORS)→ 固定14点 radar カーブ {0, 14.29, 35.71, 71.43, 100, 116.95, 133.90, 150.85, 167.80, 184.75, 191.53, 194.92, 198.31, 200} へ線形補間。実装は NotesRadarCalculator.radarFromAnchors。
-
パーセンタイル方式:アンカーは実譜面 52,449件の raw 分布の分位点。採用分位点列 ≈
[0, 12.3, 34.2, 64.7, 82.5, 85.9, 88.9, 91.8, 94.4, 96.8, 97.9, 98.3, 99.0, 99.3]%(既存 NOTES 軸アンカーから逆算し全軸で共有)。
-
意味:radar 値は「母集団内の難度順位」を表し、全軸で radar≈100 が同じパーセンタイル帯に対応=軸横断比較が可能(#293 の弱点抽出前提)。
-
外れ値耐性:最上位アンカー(≈99.3%ile)超は 200 にクランプ。min-max ではないので極端譜面でスケールが歪まない。導出は本体リポジトリ
scripts/analyze_notes_radar.py(B分類)/ scripts/analyze_notes_radar_aclass.py(A分類)で再現可能。
4. raw の count / density 区分(正規化入力)¶
正規化は軸ごとに「累積イベント数=秒速 density(/duration)」「rate/ratio/size=raw のまま(intensive)」を使い分け(duration 相関分析に基づく)。サーバーが raw から独自に再正規化する場合は同じ区分を踏襲すること。
-
DENSITY(/秒):notes_endgame, pattern_jack/trill/kaidan/randa, chord_gachioshi/denim/jika, scratch_single/ren/complex, rhythm_24th, soflan_stop, soflan_visual, scratch_bss
-
INTENSIVE(raw):notes_density_peak_10s, rhythm_henpyoshi, rhythm_irregular, notes_density_peak_1s, notes_local_hardness, peak_burst_1s, peak_sustained_3s, chord_max_size, soflan_accel, soflan_decel
5. 特例・留意点¶
-
soflan_visual は非ゼロが全体の約0.1%。母集団分位点だと全アンカー0=任意正値が200飽和(退化)するため、この軸だけ非ゼロ部分集合で較正(アンカー約47譜面ベース)。サーバーが集計する際もこの軸はサンプル数が極小である点に留意。
-
疎な軸(例 chord_denim 非ゼロ21%、soflan_accel/decel 約20%):母集団パーセンタイル正規化の性質上、「そのパターンを少しでも持つ=少数派」なので radar が高めに出る。仕様どおりだが #293 の閾値設定時に考慮を。
-
アンカーは母集団(採取譜面群)依存:将来 anchor を更新する場合は
gradle updateAllSongs(--all)で全件再計算→songdata.db の song テーブルから feature_* を CSV エクスポート→上記 scripts 実行→定数差し替え、で完結する設計(本体側作業)。
-
ms 閾値(T_JACK_MS=110 等)は設計§5の暫定値を据え置き。raw 算出ロジックは固定。
6. 集計責務(サーバー側)¶
- 本体は 0–200 正規化+raw 併送まで。サーバーは既存6軸と同じ集計(達成率重み
min(exscore/(notes*2), 1.0)・軸ごと上位N平均・EAV保持)をサブ軸へ拡張する想定。
-
既に 0–200 のキー(6主軸+
_radar+親軸)を二重正規化しないこと。 独自正規化したい場合のみ raw キー(§1-B)を使用。
- 各サブ軸の集計上位N(設計§8-7)、soflan accel/decel/visual の二重計上回避重み(§8-8)はサーバー側で後決めの未確定事項。
7. 値の性質¶
- 全
feature_* は 譜面ごとに決定的(プレイ内容に依存しない譜面特徴)。文字列化は Double.toString。
- 旧スキーマ/旧クライアント互換:未知キーは EAV なので無痛。本体DBも auto-ALTER で列追加のみ(既存値不変)。
8. 参照¶
- 設計:本体リポジトリ
docs/notes-radar-subdivision-design.md(§8' に #316 確定状況)
- 実装:
NotesRadarCalculator / NotesRadarFeature(81 component) / IRChartData
- 関連チケット:#313(設計)/ #314(A分類raw)/ #315(B分類raw)/ #316(本チケット=全サブ軸 0–200 正規化)/ #293(弱点分析パネル)