For AI agents: the complete documentation index is available at https://open-spaced-repetition.github.io/ts-fsrs/ja-JP/llms.txt, the full documentation bundle is available at https://open-spaced-repetition.github.io/ts-fsrs/ja-JP/llms-full.txt, and this page is available as Markdown at https://open-spaced-repetition.github.io/ts-fsrs/ja-JP/guide/optimizer/train-evaluate.md.

学習と評価

学習は数回の binding 呼び出しで復習履歴を処理します。入力は復習ログ CSV、出力は DefaultScheduler やカスタムの defineScheduler に渡せる重みの配列です。

例は @open-spaced-repetition/binding を import します。Node ではネイティブの napi モジュール、ブラウザでは WASI Preview 1 の wasm ビルドに解決されます(スレッドの説明はOptimizer 概要を参照)。

復習ログをアイテムに変換する

convertCsvToFsrsItems は CSV テキストを読み、カードごとに行をまとめて FSRSItem にします。列は次のとおりです。

列意味
card_idカードの安定した識別子。
review_time復習時刻(epoch ミリ秒)。
review_rating評価(1 Again 〜 4 Easy)。
review_duration復習に要した時間(ミリ秒)。
review_state復習時点のカード状態。

nextDayStartsAt(翌日が始まる時刻)と、IANA タイムゾーン('UTC' など)か固定の UTC オフセット(分)を渡します。Uint8Array 入力の場合は同期でアイテムを返します。

import { convertCsvToFsrsItems } from '@open-spaced-repetition/binding'

// One card with two reviews: first review today, second the next day.
const csv = [
  'review_time,card_id,review_rating,review_duration,review_state',
  '1704067200000,card-one,3,1000,0',
  '1704153600000,card-one,4,900,2',
].join('\n')

// The day starts at 04:00 local, in the UTC timezone.
const items = convertCsvToFsrsItems(
  new TextEncoder().encode(csv),
  4,
  'UTC',
  'FSRS-7'
)

console.log(
  JSON.stringify(
    {
      itemCount: items.length,
      reviewsPerItem: items.map((item) => item.reviews.length),
      ratings: items.map((item) => item.reviews.map((review) => review.rating)),
    },
    null,
    2
  )
)

既存の変換関数は引き続き配列を返します。CSV の任意のカード識別子を一度だけ数値化するには、convertCsvToFsrsItemsWithCardIds を使います。戻り値は { items, cardIds }(ストリーム入力では Promise)です。数値 ID は今回の変換で残ったカードごとに割り当てられ、ソート後の items と添字で対応します。元の識別子ではありません。同じ IDs を学習と直接評価に再利用し、別々の変換結果の IDs を混在させないでください。

computeParameters と evaluateWithTimeSeriesSplits は任意の options.cardIds を受け取ります。

import {
  computeParameters,
  convertCsvToFsrsItemsWithCardIds,
  evaluateWithTimeSeriesSplits,
} from '@open-spaced-repetition/binding'

const response = await fetch(`${import.meta.env.BASE_URL}/revlog.csv`, {
  cache: 'force-cache',
})
if (!response.ok) throw new Error(`revlog.csv: ${response.status}`)
if (!response.body) throw new Error('revlog.csv: empty response body')
console.log('Response received. Converting reviews and training…')

const dataset = await convertCsvToFsrsItemsWithCardIds(
  response.body,
  4,
  'UTC',
  'FSRS-7'
)
const optimizedWeights = await computeParameters(dataset.items, {
  modelVersion: 'FSRS-7',
  enableShortTerm: true,
  cardIds: dataset.cardIds,
})
const metrics = await evaluateWithTimeSeriesSplits(dataset.items, {
  modelVersion: 'FSRS-7',
  enableShortTerm: true,
  cardIds: dataset.cardIds,
})

console.log(JSON.stringify({ optimizedWeights, metrics }, null, 2))

CSV 変換・学習・評価・スケジューリングでは同じ modelVersion(既定は 'FSRS-7'、または 'FSRS-6')を使います。convertCsvToFsrsItems の第 4 引数と学習・評価のオプションに渡し、DefaultScheduler({ version: modelVersion, weights }) で利用します。FSRS-7 は 34 個の重みを返し、現地の学習日の実際の長さで正規化した小数・同日間隔を保持します。FSRS-6 は 21 個の重みと整数の学習日を使います。同日の追加復習も FSRS-7 の学習に利用できます。

重みを学習する

computeParameters(items, options) は非同期で、学習済みの重みを返します。enableShortTerm は必須です。numRelearningSteps と trainingConfig は省略でき、progress は学習中に (current, total) を報告します。

const weights = await computeParameters(items, {
  modelVersion: 'FSRS-7',
  enableShortTerm: true,
  enableSchedPenalties: true,
})

enableSchedPenalties は任意で、既定値は false です。true にすると、FSRS-7 の間隔の成長と短い間隔へのペナルティを学習損失に追加します。evaluateWithTimeSeriesSplits 内部の学習にも適用されますが、FSRS-6 では無視され、スケジューリングの数式は変わりません。

trainingConfig(epochs、batch size、seed、最大系列長、学習率、L2 重み)は省略可能で、省略時は binding の既定値を使います。computeParameters は実際の学習ループを実行するため、メインスレッドではなく Worker で呼んでください。Playgroundページのトレーナーは同じ経路を Web Worker で実行し、進捗をライブで報告します。返された weights 配列を DefaultScheduler({ version: modelVersion, weights }) や defineScheduler の設定に渡し、モデルの既定値を置き換えます。

適合度を評価する

evaluateWithTimeSeriesSplits(items, options) は復習履歴を時刻で分割し、logLoss と rmseBins を持つ ModelEvaluation を返します。学習済みの重みが保留した復習をどれだけ予測するかを判断できます。computeOptimalSteps はさらに進み、復習と目標保持率から学習・再学習ステップの推奨時間を返します。

インストールコマンドと二つの実行環境はOptimizer 概要を参照してください。