Suchmaße: Recall und reziproker Rang
Viele KI-Funktionen durchsuchen eine Menge von Dokumenten und antworten dann aus dem, was sie finden. Ist die Antwort falsch: Welcher Teil hat versagt, die Suche oder die Antwort?
Sie können die Suche für sich bewerten. Hier ist die Suche ein Schlüsselwort-Zähler in Code, es gibt also keine Einbettungen.
Am Ende dieser Lektion
Notiz
Ich kann die Suche getrennt von der Antwort bewerten.
Schlüsselwörter
| Begriff | Was er bedeutet | Beispiel |
|---|---|---|
| Sucher | der Teil, der zu einer Frage Dokumente findet | |
| Rangliste | Dokumente der Reihe nach, das beste zuerst | |
| Relevant | ein Dokument, das die Antwort wirklich enthält | |
| Recall bei k | der Anteil der relevanten Dokumente unter den ersten k | 0,5 |
| Reziproker Rang | eins geteilt durch den Rang des ersten relevanten Dokuments | 0,5 |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Ein Schlüsselwort-Sucher zählt gemeinsame Wörter
Schreiben Sie die Frage klein. Ersetzen Sie ä, ö, ü und ß durch ae, oe, ue und ss. Lassen Sie kleine Wörter wie die und ist weg. Zählen Sie für jedes Dokument, wie viele Fragewörter es enthält. Sortieren Sie danach, das beste zuerst.
Das ist einfach und hat Grenzen. Er stemmt nicht: darf und dürfen gelten als zwei Wörter. Auch Ausleihfrist und Leihfrist treffen sich nicht, obwohl sie dasselbe meinen.
Durchgerechnetes Beispiel: eine Frage, drei Dokumente
| Fragewörter | Dokument | Gemeinsame Wörter | Rang |
|---|---|---|---|
| viele, bücher, darf, pro, tag, ausleihen | Verspätete Bücher kosten zwanzig Cent pro Tag | 3 | 1 |
| viele, bücher, darf, pro, tag, ausleihen | Mitglieder dürfen sechs Bücher ausleihen | 2 | 2 |
| viele, bücher, darf, pro, tag, ausleihen | Drucken kostet zehn Cent pro Seite | 1 | 3 |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Recall und Rang bewerten die Liste
Recall bei k fragt, wie viele der richtigen Dokumente unter den ersten k stehen. Zwei sind richtig und eines steht unter den ersten 2: Recall bei 2 ist 0,5.
Der reziproke Rang beachtet nur das erste richtige Dokument. Auf Rang 1 ergibt er 1, auf Rang 2 ergibt er 0,5, auf Rang 4 ergibt er 0,25. Der Mittelwert über viele Fragen ist der mittlere reziproke Rang.
Durchgerechnetes Beispiel: fünf Fragen
| Frage | Richtiges Dokument auf Rang | Reziproker Rang | Recall bei 1 |
|---|---|---|---|
| Wann öffnet die Bibliothek | 1 | 1 | 1 |
| Wann ist die Bibliothek geschlossen (zwei richtig) | 1 und 2 | 1 | 0,5 |
| Wie viele Bücher darf ich pro Tag ausleihen | 2 | 0,5 | 0 |
| Wie lange ist die Ausleihfrist | nicht gefunden | 0 | 0 |
| Was kostet das Drucken einer Seite | 1 | 1 | 1 |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Ein häufiger Fehler
Warnung
Viele denken, eine falsche Antwort heiße, das Modell sei schlecht. Wurde das richtige Dokument nie gefunden, kann auch ein perfektes Modell nicht antworten. Bewerten Sie erst die Suche, dann die Antwort.
Die Modellhilfe schreiben, Teil 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const basis = process.env.AI_URL || \"http://ai:4000\";' '// Die Token einer Antwort oder null, wenn sie keine nennt.' 'function zaehlen(daten, name) {' ' return daten.usage && typeof daten.usage[name] === \"number\" ? daten.usage[name] : null;' '}' > model.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Modellhilfe schreiben, Teil 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function fragen(nachrichten, probe, max) {' ' try {' ' const res = await fetch(basis + \"/v1/chat/completions\", {' ' method: \"POST\",' ' headers: { \"content-type\": \"application/json\", authorization: \"Bearer lab\" },' ' body: JSON.stringify({ model: \"lab\", messages: nachrichten, 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, eingabe: zaehlen(d, \"prompt_tokens\"), ausgabe: zaehlen(d, \"completion_tokens\"), aufgezeichnet: false };' ' } catch (fehler) {' ' console.log(\"Aufgezeichnete Probe: Kein Modell hat geantwortet (\" + fehler.message + \").\");' ' return { text: probe, eingabe: null, ausgabe: null, aufgezeichnet: true };' ' }' '}' 'module.exports = { fragen };' >> model.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Schlüsselwort-Suche schreiben, Teil 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const { fragen } = require(\"./model\");' 'const dokumente = {' ' d1: \"Die Bibliothek öffnet um neun Uhr und schließt um siebzehn Uhr\",' ' d2: \"Mitglieder dürfen sechs Bücher ausleihen\",' ' d3: \"Verspätete Bücher kosten zwanzig Cent pro Tag\",' ' d4: \"Das Café verkauft Suppe und Tee\",' ' d5: \"Computer können Sie eine Stunde täglich kostenlos nutzen\",' ' d6: \"Die Leihfrist beträgt drei Wochen und lässt sich am Schalter verlängern\",' ' d7: \"Die Bibliothek ist sonntags geschlossen\",' ' d8: \"Drucken kostet zehn Cent pro Seite\",' '};' > suche.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Schlüsselwort-Suche schreiben, Teil 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const falten = { \"ä\": \"ae\", \"ö\": \"oe\", \"ü\": \"ue\", \"ß\": \"ss\" };' 'const stopp = [\"die\", \"der\", \"das\", \"und\", \"ist\", \"wie\", \"wann\", \"was\", \"kann\", \"ich\", \"ein\", \"eine\", \"einer\", \"am\", \"zu\", \"oder\", \"sie\"];' 'function normal(text) {' ' let aus = \"\";' ' text.toLowerCase().split(\"\").forEach(function (z) {' ' if (\",.?;:\".indexOf(z) >= 0) aus += \" \";' ' else aus += falten[z] || z;' ' });' ' return aus;' '}' 'function woerter(text) {' ' return normal(text).split(\" \").filter(function (w) { return w.length > 0 && stopp.indexOf(w) < 0; });' '}' >> suche.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Schlüsselwort-Suche schreiben, Teil 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'function suchen(frage) {' ' const f = woerter(frage);' ' const bewertet = Object.keys(dokumente).map(function (id) {' ' const hat = woerter(dokumente[id]);' ' return { id: id, wert: f.filter(function (w) { return hat.indexOf(w) >= 0; }).length };' ' }).filter(function (b) { return b.wert > 0; });' ' bewertet.sort(function (a, b) { return b.wert - a.wert || (a.id < b.id ? -1 : 1); });' ' return bewertet.map(function (b) { return b.id; });' '}' >> suche.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Schlüsselwort-Suche schreiben, Teil 4
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const fragenliste = [' ' [\"Wann öffnet die Bibliothek\", [\"d1\"]], [\"Wann ist die Bibliothek geschlossen\", [\"d1\", \"d7\"]],' ' [\"Wie viele Bücher darf ich pro Tag ausleihen\", [\"d2\"]],' ' [\"Wie lange ist die Ausleihfrist\", [\"d6\"]], [\"Was kostet das Drucken einer Seite\", [\"d8\"]],' '];' 'let summeRang = 0;' 'let summeRecall = 0;' 'fragenliste.forEach(function (eintrag) {' ' const rangliste = suchen(eintrag[0]);' ' const stelle = rangliste.findIndex(function (id) { return eintrag[1].indexOf(id) >= 0; });' ' const rr = stelle < 0 ? 0 : 1 / (stelle + 1);' ' const treffer = rangliste.slice(0, 1).filter(function (id) { return eintrag[1].indexOf(id) >= 0; }).length;' ' summeRang += rr;' ' summeRecall += treffer / eintrag[1].length;' ' console.log(eintrag[0] + \" -> \" + (rangliste.join(\",\") || \"nichts\") + \" rr \" + rr.toFixed(2));' '});' >> suche.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Schlüsselwort-Suche schreiben, Teil 5
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'async function main() {' ' console.log(\"mittlerer reziproker Rang: \" + (summeRang / fragenliste.length).toFixed(2));' ' console.log(\"mittlerer Recall bei 1: \" + (summeRecall / fragenliste.length).toFixed(2));' ' const q = \"Antworten Sie in einem Satz und nur mit diesem Text: \" + dokumente.d3 + \". Frage: Wie viele Bücher darf ich ausleihen?\";' ' const probe = \"Verspätete Bücher kosten zwanzig Cent pro Tag.\";' ' const antwort = await fragen([{ role: \"user\", content: q }], probe, 60);' ' console.log(\"Antwort aus dem obersten Dokument: \" + antwort.text);' '}' 'main();' >> suche.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Die Suche ausführen und bewerten
docker exec -w /home/node/project agent node suche.jsHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Was der Run ausgibt
| Zeile | Was sie zeigt |
|---|---|
| Wann öffnet die Bibliothek -> d1,d7 rr 1.00 | Die Rangliste und ihr Rangwert |
| Wie viele Bücher darf ich pro Tag ausleihen -> d3,d2,d8 rr 0.50 | Das richtige Dokument steht auf Rang 2 |
| Wie lange ist die Ausleihfrist -> nichts rr 0.00 | Ein Wort, das der Zähler nicht verbinden kann |
| mittlerer reziproker Rang: 0.70 | Der Mittelwert über fünf Fragen |
| Antwort aus dem obersten Dokument: ... | Ein Satz aus dem Labor. Eine Aufgezeichnete Probe, wenn kein Modell antwortet |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.