> 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.

# 学習と評価

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

例は `@open-spaced-repetition/binding` を import します。Node ではネイティブの napi モジュール、ブラウザでは WASI Preview 1 の wasm ビルドに解決されます（スレッドの説明は[Optimizer 概要](https://open-spaced-repetition.github.io/ts-fsrs/ja-JP/guide/optimizer/index.md)を参照）。

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

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

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

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

```ts file="../../../snippets/run-code/optimizer-csv.ts"
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` を受け取ります。

```ts file="../../../snippets/run-code/optimizer-card-ids.ts"
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)` を報告します。

```ts
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](https://open-spaced-repetition.github.io/ts-fsrs/ja-JP/playground.md)ページのトレーナーは同じ経路を Web Worker で実行し、進捗をライブで報告します。返された `weights` 配列を `DefaultScheduler({ version: modelVersion, weights })` や `defineScheduler` の設定に渡し、モデルの既定値を置き換えます。

## 適合度を評価する

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

インストールコマンドと二つの実行環境は[Optimizer 概要](https://open-spaced-repetition.github.io/ts-fsrs/ja-JP/guide/optimizer/index.md)を参照してください。
