Cómo juzgar un conjunto de evaluación
Un conjunto de evaluación es la lista de casos con la que puntúas una función de IA. La nota solo vale lo que vale esa lista.
Esta lección profundiza el módulo sobre evaluación y pruebas, que enseña a construir un primer conjunto. Aquí haces una pregunta más difícil: ¿puedes fiarte de la nota que te da?
Al final de esta lección
Nota
Puedo decir si un conjunto de evaluación es lo bastante bueno para fiarme de él.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Cobertura | cómo se reparten los casos entre los tipos de entrada | |
| Etiqueta | la respuesta que una persona dice que es la buena para un caso | si |
| Desacuerdo | dos personas que dan dos etiquetas a un mismo caso | |
| Margen | cuánto puede moverse una nota por puro azar | |
| Diferencia | lo que separa las notas de dos versiones |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Cobertura es probar cada tipo de entrada
Reparte tus casos por tipos, como simple, mixto, límite y rechazo. Cuenta cuántos hay de cada tipo. Un tipo con uno o dos casos es escaso.
Un tipo escaso esconde fallos. Si una función falla todos los casos de rechazo, dos casos de veinte mueven muy poco la nota.
Ejemplo resuelto: veinte casos por tipo
| Tipo | Casos | Parte | Veredicto |
|---|---|---|---|
| simple | 10 | 50 % | Bastan |
| mixto | 5 | 25 % | Bastan |
| límite | 3 | 15 % | Bastan |
| rechazo | 2 | 10 % | Escaso, añade más |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Dos personas revisan las etiquetas una de otra
Una etiqueta es la opinión de una persona. Pide a una segunda persona que etiquete los mismos casos sin ver las primeras etiquetas. Después compara.
Donde coinciden, el caso está claro. Donde difieren, el caso o la regla no está clara. Revisa esos casos antes de puntuar nada.
Un error frecuente
Advertencia
Mucha gente cree que la etiqueta de un experto es la verdad. Es una sola opinión. Úsala solo si una segunda persona está de acuerdo o si has escrito por qué el caso lleva esa etiqueta.
Un conjunto pequeño no distingue dos versiones
Una nota se mueve por azar. Una regla aproximada para el margen es 100 dividido entre la raíz cuadrada del número de casos, en puntos. Con 100 casos, el margen es de 10 puntos.
Una diferencia menor que el margen puede ser ruido. Para ver una diferencia de 5 puntos hacen falta unos 400 casos.
Ejemplo resuelto: casos y margen
| Casos | Margen en puntos | Diferencia menor de la que puedes fiarte |
|---|---|---|
| 25 | 20 | Unos 20 puntos |
| 100 | 10 | Unos 10 puntos |
| 400 | 5 | Unos 5 puntos |
| 2500 | 2 | Unos 2 puntos |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Escribe el ayudante del modelo, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const base = process.env.AI_URL || \"http://ai:4000\";' '// Los tokens de una respuesta, o null si no trae ninguno.' 'function count(data, name) {' ' return data.usage && typeof data.usage[name] === \"number\" ? data.usage[name] : null;' '}' > model.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe el ayudante del modelo, parte 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(\"estado \" + 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(\"Muestra grabada: ningún modelo respondió (\" + error.message + \").\");' ' return { text: sample, inTokens: null, outTokens: null, recorded: true };' ' }' '}' 'module.exports = { ask };' >> model.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe la auditoría del conjunto, parte 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { ask } = require(\"./model\");' 'const rows = [' ' \"1 simple si si\", \"2 simple si si\", \"3 simple no no\", \"4 simple si si\", \"5 simple no no\",' ' \"6 simple si si\", \"7 mixto si no\", \"8 mixto no no\", \"9 mixto si si\", \"10 simple no no\",' ' \"11 mixto no no\", \"12 limite si si\", \"13 mixto si no\", \"14 limite no no\", \"15 simple si si\",' ' \"16 simple no no\", \"17 limite si si\", \"18 simple si no\", \"19 rechazo no no\", \"20 rechazo no no\",' '].map(function (r) {' ' const p = r.split(\" \");' ' return { id: Number(p[0]), kind: p[1], a: p[2], b: p[3] };' '});' > audit.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe la auditoría del conjunto, parte 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const counts = {};' 'rows.forEach(function (r) { counts[r.kind] = (counts[r.kind] || 0) + 1; });' 'const thin = Object.keys(counts).filter(function (k) { return counts[k] < 3; });' 'const apart = rows.filter(function (r) { return r.a < r.b || r.a > r.b; });' 'const same = rows.length - apart.length;' 'const gap = 5;' 'const needed = (100 / gap) * (100 / gap);' >> audit.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Escribe la auditoría del conjunto, parte 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' console.log(\"casos: \" + rows.length + \" por tipo: \" + JSON.stringify(counts));' ' console.log(\"tipos escasos (menos de 3): \" + thin.join(\", \"));' ' console.log(\"coinciden: \" + (same * 100 / rows.length) + \" por ciento\");' ' console.log(\"revisa estos ids: \" + apart.map(function (r) { return r.id; }).join(\", \"));' ' console.log(\"para ver una diferencia de \" + gap + \" puntos hacen falta unos \" + needed + \" casos\");' ' const q = \"En una frase corta, ¿por qué dos personas deben etiquetar los mismos casos?\";' ' const sample = \"Donde no coinciden, el caso o la regla no está clara, y una nota sobre él vale poco.\";' ' const reply = await ask([{ role: \"user\", content: q }], sample, 60);' ' console.log(\"el modelo dijo: \" + reply.text);' '}' 'main();' >> audit.js"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Ejecuta la auditoría
docker exec -w /home/node/project agent node audit.jsSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Lo que imprime la auditoría
| Línea | Qué muestra |
|---|---|
| casos: 20 por tipo: {...} | Cuántos casos tiene cada tipo |
| tipos escasos (menos de 3): rechazo | Tipos que necesitan más casos |
| coinciden: 85 por ciento | Cuántas veces coincidieron las dos personas |
| revisa estos ids: 7, 13, 18 | Casos en que difieren |
| para ver una diferencia de 5 puntos hacen falta unos 400 casos | Cuántos casos hacen falta para notar una diferencia pequeña |
| el modelo dijo: ... | Una frase del laboratorio. Una muestra grabada si ningún modelo responde |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.