For AI agents: the complete documentation index is available at https://open-spaced-repetition.github.io/ts-fsrs/zh-CN/llms.txt, the full documentation bundle is available at https://open-spaced-repetition.github.io/ts-fsrs/zh-CN/llms-full.txt, and this page is available as Markdown at https://open-spaced-repetition.github.io/ts-fsrs/zh-CN/guide/optimizer/train-evaluate.md.
  • 简体中文
  • 训练与评估

    训练通过几次 binding 调用把复习历史跑完。输入是一份复习日志 CSV;输出是可直接交给 DefaultScheduler 或自定义 defineScheduler 的权重数组。

    示例导入 @open-spaced-repetition/binding。在 Node 中是原生 napi 模块;在浏览器中解析为 WASI Preview 1 的 wasm 构建(多线程说明见训练器概览)。

    把复习日志转成项

    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 的第四个参数,并传入训练和评估选项;调度时使用 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 更进一步:给定复习与目标保留率,推荐学习与再学习步骤的时长。

    安装命令与两种运行时见训练器概览。