本文へ移動

09 · 仕組み

スケジューリング(FSRS)

次にいつ出すかは FSRS が決めます。状態は持たず、学習ログから毎回計算し直します。

このページの中身

次の復習の間隔は FSRS(Free Spaced Repetition Scheduler)が決めます。覚えているものは間隔が伸び、あやふやなものは早く戻ってきます。

状態を持たず、ログから復元します

data/reviews/*.jsonl が唯一の真実です。あるカードのスケジュールは、そのカードのログを毎回リプレイして求めます。

状態を別に持つと二重の真実ができて必ずずれます(実際、この仕組みの前身では、学習した23日ぶんに対して記録が5回しか残らず、18日ぶんの履歴が消えていました)。

この設計から出てくる帰結が2つあります。

  • 間隔に乱数(fuzz)を入れません。 入れるとリプレイのたびに結果が変わってしまいます
  • 未学習のカードは「今すぐ出せる」扱いです

ログの1行は card_idreview_time(Unix ミリ秒)・review_rating(1〜4)を必ず含みます。日付で分かれた追記専用のファイルです。

data/ の中を手で編集・整列・削除しないでください。 消したカードのログ行もそのまま残します(履歴の唯一の写しだからです)。

既定の設定

アルゴリズムFSRS-6(21要素のパラメータ)
目標保持率0.9
短期の刻み1分 / 10分(再学習は 10分)
1日の新規カード20枚(Anchor Proで解除)

既定のままなら、3つのプラットフォームで同じログから同じ間隔が出ます。新しいカードの初回は「もう一度 1分 / むずかしい 6分 / できた 10分 / かんたん 8日」です。

パラメータを変える(data/fsrs.json

設定画面に入力欄は置いていません。リポジトリが正本と言っている以上、端末ごとの設定を作ると二重の真実になるためです。リポジトリに data/fsrs.json を置くと、同期のたびに読み込みます。

{
  "w": [ 21個の数値 ],
  "desired_retention": 0.9,
  "learning_steps": ["1m", "25m"],
  "relearning_steps": ["10m"],
  "maximum_interval": 36500
}
  • キーは snake_case です(一般的な最適化ツールや Anki の出力をそのまま貼れます。camelCase も受け付けます)
  • 全項目が任意です。壊れていてもアプリは止まりません。 既定で動き、採らなかった理由を設定画面に出します
  • w の長さは 17 / 19 / 21 のみ受け付けます。それ以外は既定に戻し、その旨を出します
  • 同期のたびに差分を見て、リモートから消えたら端末からも消します

19要素の w を明示すると iOS だけ FSRS-5 に落ち、learning_steps を見なくなります(短期が 1分/5分/10分 の決め打ちになる)。Mac と Android は19要素でも刻みを見ます。この食い違いは設定画面に出ます。何も書かなければ3つとも FSRS-6 です。

設定画面の「アルゴリズム」に FSRS-5 と出ているときは、19要素の w を渡していることを正しく表しています。

実ログから最適化する(Mac 版)

Mac 版の設定 →「実ログから最適化」で、あなた自身の学習ログからパラメータを学習できます。

  • 間隔がどう変わるかを見せてから採否を決められます(パラメータを変えると全カードの期日が一斉に計算し直されるため)
  • 採用すると data/fsrs.json を書き換え、次の同期でリポジトリへ送ります。iPhone にも同じ設定が降ります
  • 入力に使うのは、最後の採点が前の採点と別の日のものだけです。同じ日のうちの再出題は経過が0日で、忘却曲線に情報が無いためです
  • 目安は 400件から試せて 1,000件で安定します。それ未満でも回せますが、結果を見て捨てられます
  • 最適化はアプリ版でだけ動きます(月1回程度で十分です)

iOS と Android は読むだけです。

このページは Anchor Cards の公開版の仕様書です。アプリの挙動と食い違いを見つけたらお問い合わせからお知らせください。