13ポイント上がったのは実力か偶然か
統計的有意性は、2つのエージェントの差が、偶然で生じる大きさを超えているかを問います。必要な理由は、エージェントが実行のたびに違う結果を出すため、バージョンごとの合格率を1つずつ見ても、逆の向きを指すことがあるからです。
店のエージェントの新バージョンは、13ポイント高い得点です。公開しますか。
このレッスンのゴール
メモ
実行のたびに結果が変わるとき、あるエージェントが別のエージェントより良いかを言える。
キーワード
| ことば | いみ |
|---|---|
| k回のどこかで合格 | k回の実行のうち少なくとも1回で合格したケース |
| 毎回合格 | k回の実行のすべてで合格したケース |
| 区間 | 合格率が本当に収まりうる範囲 |
| 符号検定 | 良くなったケースと悪くなったケースの数による検定 |
| p値 | 偶然だけでこれほどの差が出る確率 |
学生が入力するセルは、このプレビューでは空白です。
各ケースを何回も実行する
各ケースを、バージョンごとにk回実行します。ここでは5回です。ケースは2つの数で表せます。k回のどこかで合格は、少なくとも1回は通ったことを示し、できることを表します。毎回合格は、k回すべてで通ったことを示し、信頼できることを表します。
毎回通る必要があるサポートエージェントは、ときどき通ればよいものより、高い基準を求められます。
例: 8ケース、各5回の実行
| バージョン | 合格率 | 5回のどこかで合格 | 毎回合格 |
|---|---|---|---|
| 旧 | 60% | 8のうち7 | 8のうち2 |
| 新 | 73% | 8のうち8 | 8のうち3 |
学生が入力するセルは、このプレビューでは空白です。
差のどこまでが偶然かを問う
40回の実行から出した合格率は、推定値です。その両側に標準誤差の約2倍の区間を引きます。標準誤差とは、その合格率に出る偶然のふつうの大きさです。旧版と新版の区間が大きく重なるなら、その差は運かもしれません。
実行とケースを増やすと、区間は狭くなります。小さな差をはっきりさせる誠実な方法は、それだけです。
動いたケースを数える
符号検定は、変化の大きさを無視します。良くなったケースと悪くなったケースを数えます。同じケースは数えません。
p値は、2つのバージョンが本当は同じとしたとき、これほど偏る確率です。基準は先に決めます。ここでは 0.05 で、これより小さければ、改善か悪化と言えます。
記録済みの実行を書く
docker exec -w /home/node/project agent sh -c "printf '%s\n' '// 各ケースの記録済みの5回の実行。1は合格、0は不合格です。' 'const oldVersion = [\"11111\", \"11101\", \"10100\", \"11011\", \"00000\", \"01101\", \"11111\", \"00010\"];' 'const newVersion = [\"11111\", \"11111\", \"10101\", \"11110\", \"00100\", \"11011\", \"11111\", \"01010\"];' 'module.exports = { oldVersion, newVersion };' > runs.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
比較を書く(1)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { oldVersion, newVersion } = require(\"./runs\");' 'function passes(text) {' ' return text.split(\"\").filter(function (c) { return c === \"1\"; }).length;' '}' > stats.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
比較を書く(2)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function summary(name, version) {' ' const counts = version.map(passes);' ' const total = counts.reduce(function (a, b) { return a + b; }, 0);' ' const runs = version.length * version[0].length;' ' const p = total / runs;' ' const two = 2 * Math.sqrt(p * (1 - p) / runs);' ' const atLeast = counts.filter(function (n) { return n > 0; }).length;' ' const every = counts.filter(function (n) { return n === version[0].length; }).length;' ' console.log(name + \": 合格率 \" + Math.round(p * 100) + \"%、区間 \" + Math.round((p - two) * 100) + \" から \" + Math.round((p + two) * 100));' ' console.log(name + \": 5回のどこかで合格 \" + atLeast + \" / \" + version.length + \"、毎回合格 \" + every + \" / \" + version.length);' '}' 'summary(\"旧\", oldVersion);' 'summary(\"新\", newVersion);' >> stats.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
比較を書く(3)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function signP(better, worse) {' ' const n = better + worse;' ' if (n === 0) return 1;' ' const low = Math.min(better, worse);' ' let total = 0;' ' let ways = 1;' ' for (let i = 0; i <= low; i = i + 1) {' ' total = total + ways;' ' ways = ways * (n - i) / (i + 1);' ' }' ' return Math.min(1, 2 * total / Math.pow(2, n));' '}' >> stats.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
比較を書く(4)
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'let better = 0;' 'let worse = 0;' 'oldVersion.forEach(function (text, at) {' ' const a = passes(text);' ' const b = passes(newVersion[at]);' ' if (b > a) better = better + 1;' ' if (b < a) worse = worse + 1;' '});' 'const p = signP(better, worse);' 'console.log(\"良くなったケース: \" + better + \"、悪くなったケース: \" + worse + \"、同じ: \" + (oldVersion.length - better - worse));' 'console.log(\"符号検定の p: \" + p.toFixed(4));' 'console.log(\"判定: \" + (p < 0.05 ? (better > worse ? \"改善\" : \"悪化\") : \"不明\"));' >> stats.js"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
2つのバージョンを比べる
docker exec -w /home/node/project agent node stats.jsここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
比較が表示するもの
| 行 | 示すこと |
|---|---|
| 旧の合格率 | 60%、区間は 45 から 75 |
| 新の合格率 | 73%、区間は 58 から 87 |
| ケース | 良い 5、悪い 0、同じ 3 |
| 符号検定の p | 0.0625 |
| 判定 | 不明 |
学生が入力するセルは、このプレビューでは空白です。
試してみましょう
ヒント
runs.js で、newVersion の4つ目のケースを "11110" から "11111" に変えて、もう一度比べます。良いケースが6つ、悪いケースが0になり、p は 0.05 を下回ります。
よくある間違い
注意
p値が 0.05 を下回るまで比較をやり直し、下回ったら止める人がいます。やり直すたびに、運を引く機会が増えます。先にケース数と実行回数を決め、1回だけ実行し、出た結果をそのまま報告します。