道場「おまかせ」の仕組み
おまかせ(開始モード auto)は、道場プールから初見・練習不足・苦手の3枠を混ぜて出題します。端末に保存された解答履歴を使い、ログインは不要です。このページは実装と同じ数式・手順で説明しています。
設計の意図
冷たい道場プール(まだあまり解いていない)では初見多め。温まると練習不足と苦手の比率を上げ、定着と弱点補強のバランスを取ります。
習熟度 coverage は「その道場プールのうち、道場モードで1回以上解いた問題の割合」です。 レッスンや模試で同じ論点を解いていても、coverage には直接効きません(ただし leaf の統計には効きます。後述)。
3枠の比率は coverage に対して線形に変化します(UCB や Thompson サンプリングなどは使いません)。
学習経験者と初学者の違い
論点(leaf)の集め方
おまかせは「問題に付いた論点タグ」を、論点ツリー上の末端(leaf)に正規化してから扱います。
- 各問題には topicIds(論点 ID の配列)が付きます。親論点だけ・子だけ・混在があり得ます。
- まず「最も具体的なタグ」だけを残します(子と親が両方付いている場合、親は子に飲み込まれます)。
- 残った各 ID が leaf ならそのまま採用。親論点なら子孫の leaf すべてに展開します。
- leaf が1つも得られない問題は、初学者ゲートでは候補外になります。
例(イメージ)
タグ [商業簿記] → 子孫 leaf {仕訳, 減価償却, …}
タグ [仕訳](すでに leaf)→ {仕訳}
タグ [仕訳, 減価償却] → {仕訳, 減価償却}(問題は両方の leaf を持つ)
- 端末のレッスン進捗から、完了したレッスンの ID を集めます。
- 各レッスンに TopicLesson で紐づく「ホーム論点」の public ID を集め、許可プール(Set)を作ります。
- 道場の各問題について、上の手順で得た leaf の集合が、すべて許可プールに含まれるときだけ残します(any-overlap ではありません)。
- 許可プールが空、または該当問題が0件のときは「はじめる」が押せず、案内文が表示されます。
解答履歴の ID と leaf への集約
レッスン・道場・模試の試行は、ソース付き ID で保存され、leaf 統計はソース横断でまとめます。
| ソース | 履歴キーの形 | おまかせでの使われ方 |
|---|---|---|
| lesson | lesson:<問題ID> | leaf の n_eff / 苦手度に寄与。道場の「未挑戦」枠には直接は載らない。 |
| dojo | dojo:<問題ID> | その道場問題を「見た」と coverage にカウント。問題ごとの attemptCount も道場キー基準。 |
| contest | contest:<問題ID> | leaf の n_eff / 苦手度に寄与。道場の「未挑戦」枠には直接は載らない。 |
- n_eff — 各試行の減衰重み w の合計(試行回数そのものではない)
- c_eff — 正解(タイムアウト除く)の w の合計
- p_hat — ベイズ平均 (c_eff + 1) / (n_eff + 2)
- weak — 1 − p_hat(高いほど苦手寄り)
重み w = 0.5(経過日数 / 14) (半減期 14 日)
| 解答の古さ | 重み w(例) |
|---|---|
| 今日 | 1.000 |
| 14日前 | 0.500 |
| 28日前 | 0.250 |
他の開始モードとの違い
| モード | 候補の決め方 | 並び |
|---|---|---|
| おまかせ | 苦手や練習量の少ない問題を分析して出題 | 3枠割当 + フォールバック + leaf 連続抑制 |
| 論点選択 | 選んだ論点から出題(未選択は全範囲) | 論点フィルタ後の通常キュー |
| 間違えた問題 | 各問題の直近の解答が不正解のものだけを出題します。 | 直近不正解のみ(該当なしならモード非表示) |
アルゴリズム本体(ステップバイステップ)
planDojoRecommendQueue と同じ順序です。
| 枠 | 入る問題 / leaf | 並び順(優先が左) |
|---|---|---|
| 初見 | attemptCount = 0 | 重要度重み付きシャッフル(rank が高いほど先頭に来やすい。乱数キー = U1/(rank+1)) |
| 練習不足 | 0 < n_eff < K(K=3)の leaf を持つ問題 | leaf は 1/(1+n_eff) の降順(n_eff が小さい=練習が薄い leaf を先)→ 各 leaf 内は未挑戦優先 → attempt 少ない → 重要度 |
| 苦手 | n_eff ≥ K の leaf を持つ問題(weak の閾値フィルタはなし) | leaf は weak 降順 → 問題は weak 降順 → 未挑戦優先 → 最終解答が古い → 重要度 |
| フォールバック余り | まだ取られていない問題 | 初見シャッフル + 既解は lastAt 昇順。枠ラベルは leftoverSlot で再判定 |
各枠の生の値 = N × 比率。まず floor を取り、残り問数は小数部が大きい枠から1問ずつ配分(同率なら枠名の辞書順)。
| coverage | 10問の割当(初見 / 練習不足 / 苦手) |
|---|---|
| 0%(道場プールで未着手が多い) | 8 / 1 / 1 |
| 20% | 7 / 1 / 2 |
| 100%(プールの問題は一通り解いた) | 1 / 3 / 6 |
習熟度と3枠の比率
初見 = max(10%, 85% − 75% × coverage)
練習不足 = 7.5% + 22.5% × coverage
苦手 = 7.5% + 52.5% × coverage
0%(道場プールで未着手が多い)
比率: 初見 85% / 練習不足 7.5% / 苦手 7.5%
20%
比率: 初見 70% / 練習不足 12% / 苦手 18%
100%(プールの問題は一通り解いた)
比率: 初見 10% / 練習不足 30% / 苦手 60%
3枠の意味(要約)
leaf 連続抑制
fill 後のリストを、先頭から走査して直前の問題と leaf が重ならない要素を選ぶ貪欲法で並べ替えます。 枠の大まかな順序(初見が先に来る傾向)は保ちつつ、隣接同 leaf を減らします。候補が1 leaf しかないプールでは連続は避けられません。 2問先までの leaf は見ません(隣接のみ)。
おまかせが使っていないもの
- UCB / Thompson サンプリング / FSRS などの最適探索・記憶モデル
- 苦手枠での weak 閾値によるハードフィルタ(並び順のみで優先)
- 初学者ゲート後の「全道場フォールバック」
- レッスン履歴を coverage の seen に含める処理(意図的に道場プールの冷温で見る)
既知の限界・今後の余地
苦手枠の定義 — n_eff ≥ K の leaf はすべて苦手プールの候補になります。得意な leaf は weak ソートで後方に回るだけで、枠が空くと選ばれることがあります。
coverage とレッスン — レッスンで繰り返していても、道場で未挑戦なら初見枠・高 coverage 扱いにはなりません(leaf 統計にはレッスン試行が効きます)。
初学者と道場のミスマッチ — レッスン完了論点と道場問題の leaf が一致しないと0問になります(全問題フォールバックはしません)。該当0件時は画面に案内を出します。
連続抑制 — 隣接1手先のみ。同一 leaf が3問連続するケースは理論上あり得ます。
将来: スコア一本化・sweet spot 帯・探索アルゴリズムの導入は別フェーズの検討項目です。