別名 Compute Minimum Recommended Retention(最小推奨保持率の計算、CMRR)

定義

間隔反復について話すとき、私たちは次の2つの要素を考慮します:

  1. どれだけのフラッシュカードを覚えているか?(知識の習得)
  2. どれだけの時間がかかるか?(1日にかかる勉強時間の負担)

私たちは、できるだけ多くのことを覚えながら、できるだけ少ない時間を費やしたいと考えています。FSRSでは、望ましい保持率の適切な値を選択することで、負担を最小限に抑えるか、知識の習得を最大化することができます。

毎日新しいカードを追加し、時間通りにレビューを行うと想像してみてください。望ましい保持率を高く設定すれば、知識の習得は高くなります。

総知識は、各カードのリコール確率の合計として考えることができます。

数学的には、$\text{knowledge} = \sum\limits_{i=1}^n R_i$ で表されます。ここで、$n$ は学習したカードの数、$R_i$ はi番目のカードをリコールできる確率です。

以下のグラフは、知識が望ましい保持率にどのように依存するかを示しています。この記事のすべてのグラフでは、Y軸に値がないのは、それらが多くの要素(FSRSパラメータ、カードごとに費やす時間、デッキサイズ、新しいカードの制限など)に依存しており、貴重な洞察を提供しないためです。重要なのは全体的な形状です。

image

望ましい保持率の値が高いと、カードをより頻繁にレビューする必要があり、作業負荷が増加します。望ましい保持率を下げると、作業負荷と知識が減少します。しかし、望ましい保持率が非常に低い場合、多くを忘れてしまい、カードを再学習する必要があり、再び作業負荷が増加します。したがって、ここには2つの「力」が働いています:

  1. 望ましい保持率が増加すると、間隔が短くなり、1日に行うレビューの数が増加します。
  2. 望ましい保持率が減少すると、より多くを忘れてしまい、学習した内容を再学習する必要が増えます。

その結果、望ましい保持率を関数として作業負荷をプロットすると、作業負荷が最小になる点が現れます。

: 以下のグラフはFSRSのデフォルトパラメータから生成されています。実際のグラフは学習者によって異なります。

image

同様のグラフは、作業負荷を習得した知識で割った場合にも得られます(この記事の冒頭の式)。これは、どれだけ覚えているかに対して相対的にどれだけ勉強する必要があるかを示しています。この最小値に対応する望ましい保持率の値は若干異なります。

image

作業負荷/知識を最小化することは、作業負荷を最小化するよりも実用的であるように思われます。例えば、80%の保持率を達成するために1日30分勉強し、90%の保持率を達成するために1日31分勉強する必要がある場合、10%多く覚えるために1分多く勉強することに同意するでしょう。

シミュレーション

FSRSを使用すると、Ankiでの学習プロセスをシミュレートすることができます。

コード: https://github.com/open-spaced-repetition/fsrs-rs/blob/0634cb08b08fecb96b0b8a9caba4a5e6938e85bb/src/optimal_retention.rs#L107-L407

シミュレーションのステップバイステップの概要は次のとおりです:

  1. 初期化と設定の読み込み:

    • SimulatorConfig設定からデッキサイズ、学習期間、1日あたりの最大コストなどのさまざまなパラメータを抽出します。ここで以降「コスト」は勉強にかかる秒数を指します。
    • card_tableをゼロ行列として初期化し、設定に基づいて初期値(学習期間や難易度と安定性の非常に小さい値など)で埋めます。
  2. 日次カウンターとコスト配列の初期化:

    • 日次レビュー数、学習数、記憶数、および総日次コストの配列を初期化します。
  3. シミュレーションループ:

    • 各日(学習期間内、「シミュレートする日数」)に対して、次のステップを実行します:
      • 最後のレビューから経過した日数(delta_t)と、カードの安定性および最後のレビュー日付に基づいて学習済みカードの再現性を計算します。
      • どのカードをレビューする必要があるかを決定し、これらのカードに対してランダムな値を生成して、後でそれらが忘れられているかどうかを判断します。ユーザーが「Good」「Hard」「Easy」を押す確率は、ユーザーのレビュー履歴から推定されます。
      • 再現性とランダムな値に基づいて、どのカードが忘れられているかを判断し、レビューが必要なカードに評価を割り当てます。
      • カードが忘れられているかどうか、そのレビュー評価、および設定で定義されたコストパラメータに基づいてカードのコストを更新します。コストパラメータ(ユーザーが「Good」または「Again」と答えたときにカードごとに費やす時間など)は、ユーザーのレビュー履歴から推定されます。
      • コストの累積和を計算して、どのカードがレビューされるかを決定します。1日の最大コストとレビュー制限のため、すべてのカードを常にレビューできるわけではありません。
      • 初めてレビューする必要がある新しいカードを決定します。
      • 新しく学習したカードに対してランダムに評価を生成し、それらの安定性と難易度を更新します。
      • カードのlast_datestabilitydifficultyinterval、およびdueフィールドを更新します。
      • 日次レビュー数、学習数、記憶数、および総コストを更新します。
  4. 結果の返却:

    • 記憶数、レビュー数、学習数、および日次総コストの配列を返します。

記憶数は、シミュレーションの最初の日から現在の日までに習得した総知識です。レビュー数は、現在の日にレビューされたカードの数です。学習数は、現在の日に新しく学習されたカードの数です。日次総コストは、現在の日にカードをレビューし、新しいカードを学習するのに費やした時間です。

最適化

シミュレーターを使用すると、各望ましい保持率レベルに対する作業負荷を予測することができます。オプティマイザーはブレント法を使用して最適な保持率を見つけます。

コード: https://github.com/open-spaced-repetition/fsrs-rs/blob/0634cb08b08fecb96b0b8a9caba4a5e6938e85bb/src/optimal_retention.rs#L478-L589

注: Anki 24.04以前では、目標は知識の習得(すべてのリコール確率の合計)を最大化することでしたが、Anki 24.04以降では、目標は作業負荷/知識(勉強にかかる分数を前述の合計で割ったもの)を最小化することです。