クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

学習、検証、テストに分ける

このレッスンのあとで: テストのケースを、学習データの外に置ける。

60分のレッスンコマンド6件AI コーディングエージェントのラボ:opencode でコードを説明・修正し、その結果を確かめる

見たことのあるテスト

学習、検証、テストは、例を三つに分けた山です。モデルは一つ目から学び、二つ目で調整し、三つ目で良し悪しを判断します。

テストのケースが学習の山にもあると、モデルはそれを覚えているだけかもしれません。点数は良く見えても、何も意味しません。

このレッスンのゴール

メモ

テストのケースを、学習データの外に置ける。

キーワード

ことばいみ
学習用モデルが学ぶ例
検証用選び方を調整するための例
テスト用結果の判断のために取っておく例
漏れテストのケースが学習にもあること
重複同じ例が二度あること

学生が入力するセルは、このプレビューでは空白です。

三つの山と、三つの役目

学習の前に、確かめたファイルを分けます。ほとんどの例は学習用に入れます。小さい検証用の山は、進めながら選び方を比べるために使います。テスト用は、最後に一度だけ使います。

分け方は、位置のような決まった規則にします。そうすれば、毎回同じ行が同じ山に入ります。

例: 十行を三つの山に

山行使い道
学習用1 から 6学ぶ
検証用7 と 8版の選び分け
テスト用9 と 10最後の判断を一回

学生が入力するセルは、このプレビューでは空白です。

近い写しも、漏れ

1 行目は「荷物はどこですか」で、7 行目は「荷物はどこですか?」です。言葉は同じなので、モデルはもう答えを見ています。

こうした写しを見つけるには、まず二つの文を簡単な形にします。小文字にして、句読点も空白も捨て、文字と数字だけを残します。そのうえで比べます。

よくある間違い

注意

「ファイルをでたらめに混ぜれば、テスト用は安全だ」と考えがちです。混ぜると、同じ例の写しが別々の山に散るだけです。先に重複を取り除いてから、分けます。

モデル用の補助を書く(1)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' '// 応答に含まれるトークン数。なければ null。' 'function count(data, name) {' '  return data.usage && typeof data.usage[name] === \"number\" ? data.usage[name] : null;' '}' > model.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

モデル用の補助を書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function ask(messages, sample, max) {' '  try {' '    const res = await fetch(base + \"/v1/chat/completions\", {' '      method: \"POST\",' '      headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' '      body: JSON.stringify({ model: \"lab\", messages: messages, max_tokens: max || 100 }),' '      signal: AbortSignal.timeout(30000),' '    });' '    if (res.ok === false) throw new Error(\"status \" + res.status);' '    const d = await res.json();' '    return { text: d.choices[0].message.content, inTokens: count(d, \"prompt_tokens\"), outTokens: count(d, \"completion_tokens\"), recorded: false };' '  } catch (error) {' '    console.log(\"記録済みサンプル: モデルが答えませんでした (\" + error.message + \")。\");' '    return { text: sample, inTokens: null, outTokens: null, recorded: true };' '  }' '}' 'module.exports = { ask };' >> model.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

漏れを探すスクリプトを書く(1)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const rows = [' '  \"荷物はどこですか\", \"二重に請求されました\", \"注文をキャンセルしてください\",' '  \"箱がつぶれて届きました\", \"請求書の金額が違います\", \"住所を変えられますか\",' '  \"荷物はどこですか?\", \"いいお店ですね\", \"返金がまだ届きません\", \"日曜日も店は開いていますか\",' '];' > adapt3.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

漏れを探すスクリプトを書く(2)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function normal(text) {' '  let out = \"\";' '  for (const ch of text.toLowerCase()) {' '    if (/[\p{L}\p{N}]/u.test(ch)) out = out + ch;' '  }' '  return out;' '}' 'const train = rows.slice(0, 6);' 'const validation = rows.slice(6, 8);' 'const test = rows.slice(8);' >> adapt3.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

漏れを探すスクリプトを書く(3)

コマンド
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function leaks(from, into) {' '  const seen = from.map(normal);' '  return into.filter(function (t) { return seen.includes(normal(t)); });' '}' 'async function main() {' '  console.log(\"学習 \" + train.length + \"、検証 \" + validation.length + \"、テスト \" + test.length);' '  console.log(\"検証への漏れ: \" + leaks(train, validation).join(\" | \"));' '  console.log(\"テストへの漏れ: \" + leaks(train, test).length);' '  const q = \"テスト用のケースを学習データに入れてはいけないのは、なぜですか。短い一文で答えてください。\";' '  const sample = \"モデルは見た例をそのまま繰り返せるので、漏れたケースがあると点数が実際より良く見えるからです。\";' '  const reply = await ask([{ role: \"user\", content: q }], sample, 60);' '  console.log(\"返事: \" + reply.text);' '}' 'main();' >> adapt3.js"

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

漏れを探す

コマンド
docker exec -w /home/node/project agent node adapt3.js

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

探した結果

Run は、架空の十文を位置で分け、それぞれを簡単な形にして比べます。漏れは、検証用の山に一つ見つかり、テスト用の山にはありません。

最後の行は、短いモデルの呼び出しか、「記録済みサンプル」です。

このラボとソースについて: AI コーディングエージェントのラボ:opencode でコードを説明・修正し、その結果を確かめる

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。