בירור | יצירת אלגוריתם/כללים למנוע חיפוש
-
מהבדיקה האחרונה יוצא שהבעיה העקרית היא שחיפוש וקטורי תמיד מחזיר תשובה, גם אם היא שגויה לחלוטין, מה שגרוע מאוד במקרה שלי.
-
@ע-ה-דכו-ע תשובות שגויות נותנות ציון גבוה כמו תשובות נכונות... תשובות נכונות קיבלו ציון בין 0.73 ל-0.88, ושגויות עד 0.844
מה לגבי זה?
עידו300 כתב:
תראו מה יש עד עכשיו, בקשתי מקלוד שיתמצת בשביל להראות לחבר שיחווה דעתו.
לדעתי עשה שם שטויות, אבל אני לא מבין בזה.
בעקרון הוא חילק את זה ל-4 לא ל-2.
מפת החיפוש.pdf
-
@ע-ה-דכו-ע תשובות שגויות נותנות ציון גבוה כמו תשובות נכונות... תשובות נכונות קיבלו ציון בין 0.73 ל-0.88, ושגויות עד 0.844
מה לגבי זה?
עידו300 כתב:
תראו מה יש עד עכשיו, בקשתי מקלוד שיתמצת בשביל להראות לחבר שיחווה דעתו.
לדעתי עשה שם שטויות, אבל אני לא מבין בזה.
בעקרון הוא חילק את זה ל-4 לא ל-2.
מפת החיפוש.pdf
@ע-ה-דכו-ע תשובות שגויות נותנות ציון גבוה כמו תשובות נכונות... תשובות נכונות קיבלו ציון בין 0.73 ל-0.88, ושגויות עד 0.844
שגויות שאין ביניהם שום קשר? אולי באמת יש קשר סמנטי, נניח עוז והדר יכול בהחלט להיות קרוב סמנטית למילה ספר
באיזה מודל הטמעה השתמשת? ואיזה מנוע חיפוש?
-
@ע-ה-דכו-ע תשובות שגויות נותנות ציון גבוה כמו תשובות נכונות... תשובות נכונות קיבלו ציון בין 0.73 ל-0.88, ושגויות עד 0.844
שגויות שאין ביניהם שום קשר? אולי באמת יש קשר סמנטי, נניח עוז והדר יכול בהחלט להיות קרוב סמנטית למילה ספר
באיזה מודל הטמעה השתמשת? ואיזה מנוע חיפוש?
-
ספר עם שם דומה, אבל ספר אחר: 8 טעויות
הלקוח ביקש -> החיפוש הוקטורי החזיר
רמב"ן המבואר -> רמב"ם מבואר המורחב, שופטים (אבל)
סט רמב"ן המבואר -> סט רמב"ם מבואר כחול (34 כר')
רמב"ן המבואר על התורה -> סט רמב"ן מנוקד על התורה (כלומר מהדורה אחרת, עוד נסבל אבל לא תקין).
ערוך השלחן -> שולחן ערוך יומי בכרך אחד
בית יוסף -> ראש יוסף מסכת ביצה (למרות שאין ספר בית יוסף עד כמה שזכור לי, עדיין הוא לא היה אמור למצוא את זה)
ספר חסידים -> סט אוצר החסידות (29 כר')
תלמוד בבלי -> חוברת יד משס תלמודו, בבא בתרא
משנה ברורה (נשמע "משנא ברורה") -> חוברת משנ"ב חנוכה (בתכלס זה נכון אבל זו לא התשובה הנכונה כי אנחנו מצפים לסטים הסונדרטיים ולא לאיזה חוברת לא ידועה שהוציאו)
את "רמב"ן" ו"רמב"ם" הוא מבלבל בשתי הגרסאות. -
שאילתה שמתארת ספר: 2 טעויות
הלקוח ביקש -> החיפוש הוקטורי החזיר
ספר מוסר על מידות טובות -> שכל טוב ב (מדרש על התורה)
משניות עם פירוש מבואר -> פנינים משנ"ב המבואר (משנה ברורה ולא משניות) -
שיבוש בשמיעה או כתיב שגוי: 4 טעויות
הלקוח ביקש -> החיפוש הוקטורי החזיר
שוקאמין (ש"ס חתנים, איך ג'ימני הגיע לשוקאמין, אין לי מושג...) -> סידור השלם סקאי, אשכנז (למען האמת אני לא מצפה שמישהו כן יבין את זה...)
שף חתנים (ש"ס חתנים) -> אוצר מחמדים חלק ד
מילתך בדרך (בלכתך בדרך) -> מילתא חדתא במדבר
דף יומי (לעוז והדר יש כאלו גמרות, לדוגמא "ברכות מנוקד מאורות דף היומי") -> אור החיים כרך אחד לוח יומי -
ספר שלא קיים בקטלוג: 20 מתוך 20 טעויות
על כל שאילתה הוא החזיר ספר כלשהו. כמה דוגמאות:
הלקוח ביקש -> החיפוש הוקטורי החזיר
נתיבות המשפט -> נתיבות דעת בראשית
אגרות משה -> תורת משה, אלשיך המבואר ויקרא
ים של שלמה -> מנחת שלמה ב"מ א
מורה נבוכים -> רמב"ם מבואר המורחב, שופטים (מלכים)
שמירת שבת כהלכתה -> זמירות שבת אלבומי יגל יעקב
מקדחה נטענת -> סט נ"ך מקראות גדולות (25 כר')
שעון קיר -> 5 זמירות שבת יגל יעקב במעמדקלוד יצר בשביל זה מנוע חיפוש, לא השתמש במנוע קיים.
המודל הוא מה שדיברנו עליו EmbeddingGemma 2 של גוגל, בגרסת ONNX הדחוסה (q4). הוא רץ על המעבד של השרת דרך הספרייה transformers.js 4.3.1.
את השורות הבאות לא הבנתי אז הבאתי כלשונו:
לכל שאילתה חישבתי ציון דמיון מול כל 4,077 הספרים, ומיינתי לפי הציון.
מה זה אומר על הטעויות: כל אחד מ-4,077 הספרים קיבל ציון, אז אין כאן טעויות של קירוב. כל טעות נובעת מהמודל עצמו. שני גורמים אפשריים לא בדקתי: הדחיסה של המודל (q4), ותבנית המסמך שבחרתי. -
-
-
ספר עם שם דומה, אבל ספר אחר: 8 טעויות
הלקוח ביקש -> החיפוש הוקטורי החזיר
רמב"ן המבואר -> רמב"ם מבואר המורחב, שופטים (אבל)
סט רמב"ן המבואר -> סט רמב"ם מבואר כחול (34 כר')
רמב"ן המבואר על התורה -> סט רמב"ן מנוקד על התורה (כלומר מהדורה אחרת, עוד נסבל אבל לא תקין).
ערוך השלחן -> שולחן ערוך יומי בכרך אחד
בית יוסף -> ראש יוסף מסכת ביצה (למרות שאין ספר בית יוסף עד כמה שזכור לי, עדיין הוא לא היה אמור למצוא את זה)
ספר חסידים -> סט אוצר החסידות (29 כר')
תלמוד בבלי -> חוברת יד משס תלמודו, בבא בתרא
משנה ברורה (נשמע "משנא ברורה") -> חוברת משנ"ב חנוכה (בתכלס זה נכון אבל זו לא התשובה הנכונה כי אנחנו מצפים לסטים הסונדרטיים ולא לאיזה חוברת לא ידועה שהוציאו)
את "רמב"ן" ו"רמב"ם" הוא מבלבל בשתי הגרסאות. -
שאילתה שמתארת ספר: 2 טעויות
הלקוח ביקש -> החיפוש הוקטורי החזיר
ספר מוסר על מידות טובות -> שכל טוב ב (מדרש על התורה)
משניות עם פירוש מבואר -> פנינים משנ"ב המבואר (משנה ברורה ולא משניות) -
שיבוש בשמיעה או כתיב שגוי: 4 טעויות
הלקוח ביקש -> החיפוש הוקטורי החזיר
שוקאמין (ש"ס חתנים, איך ג'ימני הגיע לשוקאמין, אין לי מושג...) -> סידור השלם סקאי, אשכנז (למען האמת אני לא מצפה שמישהו כן יבין את זה...)
שף חתנים (ש"ס חתנים) -> אוצר מחמדים חלק ד
מילתך בדרך (בלכתך בדרך) -> מילתא חדתא במדבר
דף יומי (לעוז והדר יש כאלו גמרות, לדוגמא "ברכות מנוקד מאורות דף היומי") -> אור החיים כרך אחד לוח יומי -
ספר שלא קיים בקטלוג: 20 מתוך 20 טעויות
על כל שאילתה הוא החזיר ספר כלשהו. כמה דוגמאות:
הלקוח ביקש -> החיפוש הוקטורי החזיר
נתיבות המשפט -> נתיבות דעת בראשית
אגרות משה -> תורת משה, אלשיך המבואר ויקרא
ים של שלמה -> מנחת שלמה ב"מ א
מורה נבוכים -> רמב"ם מבואר המורחב, שופטים (מלכים)
שמירת שבת כהלכתה -> זמירות שבת אלבומי יגל יעקב
מקדחה נטענת -> סט נ"ך מקראות גדולות (25 כר')
שעון קיר -> 5 זמירות שבת יגל יעקב במעמדקלוד יצר בשביל זה מנוע חיפוש, לא השתמש במנוע קיים.
המודל הוא מה שדיברנו עליו EmbeddingGemma 2 של גוגל, בגרסת ONNX הדחוסה (q4). הוא רץ על המעבד של השרת דרך הספרייה transformers.js 4.3.1.
את השורות הבאות לא הבנתי אז הבאתי כלשונו:
לכל שאילתה חישבתי ציון דמיון מול כל 4,077 הספרים, ומיינתי לפי הציון.
מה זה אומר על הטעויות: כל אחד מ-4,077 הספרים קיבל ציון, אז אין כאן טעויות של קירוב. כל טעות נובעת מהמודל עצמו. שני גורמים אפשריים לא בדקתי: הדחיסה של המודל (q4), ותבנית המסמך שבחרתי.@עידו300 חוץ מהמקדחה והשעון קיר כל שאר השאילתות באמת התשובה מאוד קרובה מבחינה וקטורית לכאו', אולי אם תכוונן מודל לנתונים שלך זה יעזור יותר...
השאלה אם אפשר בכלל לסמוך על קלוד שהמנוע שהוא עשה עובד בכלל, איך הוא כתב אותו? באיזה שפה? איך הוא בכלל שמר את האינדקס הוקטורי?
-
-
@עידו300 חוץ מהמקדחה והשעון קיר כל שאר השאילתות באמת התשובה מאוד קרובה מבחינה וקטורית לכאו', אולי אם תכוונן מודל לנתונים שלך זה יעזור יותר...
השאלה אם אפשר בכלל לסמוך על קלוד שהמנוע שהוא עשה עובד בכלל, איך הוא כתב אותו? באיזה שפה? איך הוא בכלל שמר את האינדקס הוקטורי?
@ע-ה-דכו-ע כתב בJS
מה זאת אומרת איך הוא שמר? הוא השתמש בספריה הרשמית כמדומני.אם זה משנה, ניסיתי לשלוף מה"חשיבה" שלו את מה שהוא עשה, מקוה שאלו הקודים הנכונים.
זה הקוד של ההטמעה:// מטמיע את כל ספרי העותק בגרסת מסמך נתונה. קריאה בלבד מהמסד. // node embed.mjs <db> <variant: name|desc|desc_sup> [dtype] import { pipeline, env } from '@huggingface/transformers'; import Database from '/var/www/responsa/node_modules/better-sqlite3/lib/index.js'; import fs from 'fs'; env.cacheDir = new URL('./models/', import.meta.url).pathname; const [dbPath, variant, dtype = 'q4'] = process.argv.slice(2); const db = new Database(dbPath, { readonly: true }); const rows = db.prepare(`SELECT b.id, b.name, b.notes, s.name AS supplier FROM books b LEFT JOIN suppliers s ON s.id = b.supplier_id ORDER BY b.id`).all(); // "תיאור:" מופיע בראש כמעט כל הערה — רעש שחוזר בכל המסמכים const clean = (t) => (t || '').replace(/^\s*תיאור\s*:\s*/, '').replace(/\s+/g, ' ').trim(); const DOC = { name: (r) => `title: none | text: ${r.name}`, desc: (r) => `title: ${r.name} | text: ${clean(r.notes) || r.name}`, desc_sup: (r) => `title: ${r.name} | text: ${[clean(r.notes), r.supplier && `הוצאה: ${r.supplier}`].filter(Boolean).join('. ') || r.name}`, }; if (!DOC[variant]) throw new Error(`גרסה לא מוכרת: ${variant}`); const ex = await pipeline('feature-extraction', 'onnx-community/embeddinggemma-2-ONNX', { device: 'cpu', dtype }); const t0 = Date.now(); const out = []; let peak = 0; const BATCH = 8; for (let i = 0; i < rows.length; i += BATCH) { const batch = rows.slice(i, i + BATCH); const e = await ex(batch.map(DOC[variant]), { pooling: 'mean', normalize: true }); e.tolist().forEach((v, j) => out.push({ id: batch[j].id, name: batch[j].name, v: v.map((x) => +x.toFixed(5)) })); peak = Math.max(peak, process.memoryUsage().rss); if (i % 400 === 0) console.log(`${variant} ${i}/${rows.length} ${Math.round((Date.now() - t0) / 1000)}s rss ${Math.round(peak / 1e6)}MB`); } fs.writeFileSync(`vectors-${variant}-${dtype}.json`, JSON.stringify(out)); console.log(`DONE ${variant} ${out.length} sec ${Math.round((Date.now() - t0) / 1000)} peak ${Math.round(peak / 1e6)}MB`);וזה החיפוש:
// ניסוי חוזר: חיפוש וקטורי בגרסאות מסמך שונות מול החיפוש הקיים (קוד הענף). // קריאה בלבד: עותק הגיבוי, וקטורים שחושבו מראש, הקורפוס מהריפו. // // node eval.mjs <db> <variant,...> [dtype] import { pipeline, env } from '@huggingface/transformers'; import Database from '/var/www/responsa/node_modules/better-sqlite3/lib/index.js'; import fs from 'fs'; import { compileQuery, tokenize, } from '/var/www/responsa/apps/catalog/lib/search.js'; import { searchBooks, } from '/var/www/responsa/apps/voice/facts/book-search.js'; import { toCustomerBook, } from '/var/www/responsa/apps/voice/facts/catalog-client.js'; env.cacheDir = new URL('./models/', import.meta.url).pathname; const [dbPath, variantsArg, dtype = 'q4'] = process.argv.slice(2); const variants = variantsArg.split(','); const db = new Database(dbPath, { readonly: true, }); const rows = db.prepare(` SELECT b.id, b.name, b.category, b.notes, s.name AS supplier_name FROM books b LEFT JOIN suppliers s ON s.id = b.supplier_id ORDER BY b.name, b.id `).all(); const { queries, } = JSON.parse( fs.readFileSync( '/var/www/responsa/apps/voice/scripts/search-corpus.json', 'utf8' ) ); function engineCatalog(term) { const c = compileQuery(term); if (c.empty) { return rows; } return rows .filter((b) => c.test( tokenize( [ b.name, b.category, b.supplier_name, b.notes, ] .map((x) => x || '') .join(' ') ) ) ) .map((b, i) => ({ b, i, s: c.score( tokenize(b.name || '') ), })) .sort( (x, y) => y.s - x.s || x.i - y.i ) .map((e) => e.b); } const client = { async search(term, limit = 25) { const all = engineCatalog(term); return { ok: true, total: all.length, books: all .slice(0, limit) .map((b) => toCustomerBook({ ...b, pricing: { effective: 1, }, }) ), }; }, }; const ex = await pipeline( 'feature-extraction', 'onnx-community/embeddinggemma-2-ONNX', { device: 'cpu', dtype, } ); const lat = []; const qvecs = new Map(); for (const { q } of queries) { const t = Date.now(); qvecs.set( q, ( await ex( [ `task: search result | query: ${q}`, ], { pooling: 'mean', normalize: true, } ) ).tolist()[0] ); lat.push(Date.now() - t); } const dot = (a, b) => { let s = 0; for (let i = 0; i < a.length; i++) { s += a[i] * b[i]; } return s; }; const lexical = []; for (const item of queries) { const r = await searchBooks( item.q, { client, limit: 5, } ); lexical.push( r.books.map((b) => b.title) ); } const report = { dtype, n: queries.length, latencyMs: { median: lat.sort((a, b) => a - b)[ lat.length >> 1 ], max: lat.at(-1), }, variants: {}, }; for (const variant of variants) { const docs = JSON.parse( fs.readFileSync( `vectors-${variant}-${dtype}.json`, 'utf8' ) ); const per = queries.map( (item, k) => { const qv = qvecs.get(item.q); const top = docs .map((d) => ({ name: d.name, s: dot(qv, d.v), })) .sort( (a, b) => b.s - a.s ) .slice(0, 5); const re = item.expect === null ? null : new RegExp(item.expect); const lex = lexical[k]; return { q: item.q, src: item.src, positive: re !== null, lexTop1: re ? lex.length > 0 && re.test(lex[0]) : lex.length === 0, lexEmpty: lex.length === 0, vTop1: re ? re.test(top[0].name) : false, vTop5: re ? top.some((t) => re.test(t.name) ) : false, score: +top[0].s.toFixed(3), top: top[0].name, }; } ); const pos = per.filter( (p) => p.positive ); const neg = per.filter( (p) => !p.positive ); const desc = per.filter( (p) => p.src === 'תיאור' ); const cnt = (arr, f) => arr.filter(f).length; const right = per .filter((p) => p.vTop1) .map((p) => p.score) .sort((a, b) => a - b); const wrong = per .filter((p) => !p.vTop1) .map((p) => p.score) .sort((a, b) => a - b); const fallback = per.filter( (p) => p.lexEmpty ); const sweep = []; for ( let tau = 0.75; tau <= 0.951; tau += 0.025 ) { const offered = fallback.filter( (p) => p.score >= tau ); sweep.push({ tau: +tau.toFixed(3), offered: offered.length, right: cnt( offered, (p) => p.vTop1 ), wrong: cnt( offered, (p) => !p.vTop1 ), }); } report.variants[variant] = { positives: { n: pos.length, lexTop1: cnt( pos, (p) => p.lexTop1 ), vTop1: cnt( pos, (p) => p.vTop1 ), vTop5: cnt( pos, (p) => p.vTop5 ), }, descriptive: { n: desc.length, lexTop1: cnt( desc, (p) => p.lexTop1 ), vTop1: cnt( desc, (p) => p.vTop1 ), vTop5: cnt( desc, (p) => p.vTop5 ), }, negatives: { n: neg.length, lexCorrect: cnt( neg, (p) => p.lexTop1 ), maxScore: Math.max( ...neg.map( (p) => p.score ) ), }, scoreSpread: { right: { n: right.length, min: right[0], median: right[ right.length >> 1 ], }, wrong: { n: wrong.length, median: wrong[ wrong.length >> 1 ], max: wrong.at(-1), }, rightAboveAllWrong: cnt( right, (s) => s > wrong.at(-1) ), }, fallback: { n: fallback.length, sweep, }, rows: per, }; } report.rssMB = Math.round( process.memoryUsage().rss / 1e6 ); fs.writeFileSync( `eval-${variants.join('+')}-${dtype}.json`, JSON.stringify( report, null, 1 ) ); for ( const [v, r] of Object.entries( report.variants ) ) { console.log( `\n== ${v} (${dtype})` ); console.log( 'positives', r.positives, '\ndescriptive', r.descriptive, '\nnegatives', r.negatives ); console.log( 'spread', JSON.stringify( r.scoreSpread ) ); console.log( 'fallback n', r.fallback.n, r.fallback.sweep .map( (s) => `${s.tau}:${s.right}/${s.wrong}` ) .join(' ') ); } console.log( '\nlatency', report.latencyMs, 'rss', report.rssMB );אם יעזור ניתוח של GPT (שאותי מאוד בילבל) אז יש את זה https://chatgpt.com/share/6ac60b3e-71e0-83ed-bcc0-66dc593b42ab
-
זה המסלול שהטקסט עובר כיום אחרי ההמלצה כאן בשרשור:
הפלט שחוזר מהמודל עובר בדיקת אורך תווים -> ניקוי תוים מסוימים -> תיקונים על פי טבלת תיקונים והחלפות שנצפו בתיעודים (הרי זה תמלול והוא לא תמיד מדוייק אז "בלכתך" הופך ל"מלתך" ו"משנה" ל"משנא") -> נרמול -> הסרת אותיות שימוש מובילות לצורך השוואה (השמיטה -> שמיטה).
כל זה במנגנון הדיבור.
במנגנון החיפוש עצמו:
מורצות שתי שאילתות:
1 - כמו שהיא, לדוגמא "שס חתנים"
2 - החלפות מסוימות כמו ש"ס -> סט "סט חתנים"אם שתי השאילתות האלו לא הניבו תוצאות אז עוברים לשאילתות אחרות:
1 - אותה השאילתא רק בלי מילים תיאוריות (חומש, ספר, מהדורת, הוצאת) ובלי שם הוצאה שנאמר במלואו, לדוגמא "סט חומש מקראות גדולות" יהפוך ל"סט מקראות גדולות".
2 - אותו דבר רק עם החלפת ש"ס לסט.כל מילה בשאילתא חייבת להתאים לעמודה אחת לפחות (במילים בנות 4 אותיות יכולה להיות טעות אחת, ומילים בנות 7 אותיות יכולות להיות 2 טעויות) הדירוג בפועל יהיה לפי שם הספר.
את השלב הזה לא הבנתי... וחלקו בכלל לא ברור לי למה הוא עשה אותו.
מה שכן הבנתי זה שהוא קודם בודק אם שם הספר תואם (לא מבין למה, אם שכחו מה שם הספר וביקשו משהו לפי התיאור והוא מתאים בהערות, למה לזרוק את הספר שנמצא?) ואם לא הוא מוציא אותו מהרשימה. אח"כ עושה מניפולציה על המילים, תלוי בסוג המילה ובאורך שלה ומחליף אותיות שלפעמים נשמעות אותו הדבר.שלב 3 · שער הכיסוי (בערוץ), שבו נופלות ההחלטות
כל מועמד שהשרת החזיר עובר בדיקות מול שם הספר בלבד, לא מול ההערות. מועמד שלא עבר נזרק, גם אם השרת אהב אותו.א. מילות תוכן: כל אחת חייבת להימצא בשם
מילת תוכן היא מילה בת 3 אותיות לפחות, שאינה מילה מבנית (סט, שס, ספר, כרך, גדול, מנוקד, עור, רוצה, יש וכו'). איך היא נבדקת תלוי באורך הגזע שלה:אורך הגזע מה נדרש
2 (מילה של 3 שהגיזום קיצר) הצורה המקורית מופיעה בשם כמילה שלמה
3–4 הגזע מוכל בטוקן של השם. בלי שום סובלנות לשגיאה
5 ומעלה שני תנאים יחד: השרת היה מתאים אותה, וגם כל ההבדל "נשמע". זה השינוי של ס46
"נשמע" פירושו שמותרות רק שתי עריכות:החלפה בין אותיות שנשמעות אותו דבר: ט/ת, כ/ח, כ/ק, ס/ש, א/ע/ה, ב/ו, ועוד זוג אחד שנצפה בשיחה אמיתית, ד/ת ("שס חדנים").
הוספה או השמטה של אם קריאה (א, ה, ו, י), כמו שולחן/שלחן.
כל החלפה אחרת פוסלת. לכן "שס קטנים" כבר לא מחזיר את "קרנים": ט ו-ר אינן נשמעות דומה. ההשוואה נעשית גם על הגזע וגם על צורת פני השטח, כדי ש"סמיטה" ימצא את "שמיטה" למרות שהגיזום הוריד את ה-ש רק בצד אחד.ב. מילים בנות שתי אותיות שאינן מבניות
מילה כזו לבדה לא מזהה ספר. אבל אם נאמרה, היא חייבת להופיע בשם בדיוק, למשל ים של שלמה.ג. שלילה
"לא מנוקד" פוסל שם שאומר "מנוקד" בלי "לא" לפניו, וההפך. שם שלא מזכיר את המאפיין בכלל עובר.ד. אם אף מועמד לא עבר
עוברים לניסיון הבא. אם אף ניסיון לא הניב כלום, התשובה היא 0 תוצאות, במכוון (כ8).
בחזרה למנגנון הדיבור:
בודק אם יש התאמות של מאפיינים, לדוגמא כריכת עור, אם יש - כל מה שלא מתאים מסונן.
סדרות של יותר מ4 כרכים שכל כרך נמכר בנפרד מקובצות ל"סדרה של X כרכים" (הניסוח קצת מטעה בעיני)
יש עדיפות לספרים עם שם מדויק יותר
אם יש יותר מ5 תוצאות מבקשים מהמאזין לדייק בשם הספרמה אתם אומרים?
ברור שיש עוד תיקונים לעשות והוא עוד לא מושלם אבל מה הכיוןן?@pcinfogmach במקום אחר המלצת למישהו לעשות מנגנון פיצוי/ניקוד, על מה מדובר?
-
זה המסלול שהטקסט עובר כיום אחרי ההמלצה כאן בשרשור:
הפלט שחוזר מהמודל עובר בדיקת אורך תווים -> ניקוי תוים מסוימים -> תיקונים על פי טבלת תיקונים והחלפות שנצפו בתיעודים (הרי זה תמלול והוא לא תמיד מדוייק אז "בלכתך" הופך ל"מלתך" ו"משנה" ל"משנא") -> נרמול -> הסרת אותיות שימוש מובילות לצורך השוואה (השמיטה -> שמיטה).
כל זה במנגנון הדיבור.
במנגנון החיפוש עצמו:
מורצות שתי שאילתות:
1 - כמו שהיא, לדוגמא "שס חתנים"
2 - החלפות מסוימות כמו ש"ס -> סט "סט חתנים"אם שתי השאילתות האלו לא הניבו תוצאות אז עוברים לשאילתות אחרות:
1 - אותה השאילתא רק בלי מילים תיאוריות (חומש, ספר, מהדורת, הוצאת) ובלי שם הוצאה שנאמר במלואו, לדוגמא "סט חומש מקראות גדולות" יהפוך ל"סט מקראות גדולות".
2 - אותו דבר רק עם החלפת ש"ס לסט.כל מילה בשאילתא חייבת להתאים לעמודה אחת לפחות (במילים בנות 4 אותיות יכולה להיות טעות אחת, ומילים בנות 7 אותיות יכולות להיות 2 טעויות) הדירוג בפועל יהיה לפי שם הספר.
את השלב הזה לא הבנתי... וחלקו בכלל לא ברור לי למה הוא עשה אותו.
מה שכן הבנתי זה שהוא קודם בודק אם שם הספר תואם (לא מבין למה, אם שכחו מה שם הספר וביקשו משהו לפי התיאור והוא מתאים בהערות, למה לזרוק את הספר שנמצא?) ואם לא הוא מוציא אותו מהרשימה. אח"כ עושה מניפולציה על המילים, תלוי בסוג המילה ובאורך שלה ומחליף אותיות שלפעמים נשמעות אותו הדבר.שלב 3 · שער הכיסוי (בערוץ), שבו נופלות ההחלטות
כל מועמד שהשרת החזיר עובר בדיקות מול שם הספר בלבד, לא מול ההערות. מועמד שלא עבר נזרק, גם אם השרת אהב אותו.א. מילות תוכן: כל אחת חייבת להימצא בשם
מילת תוכן היא מילה בת 3 אותיות לפחות, שאינה מילה מבנית (סט, שס, ספר, כרך, גדול, מנוקד, עור, רוצה, יש וכו'). איך היא נבדקת תלוי באורך הגזע שלה:אורך הגזע מה נדרש
2 (מילה של 3 שהגיזום קיצר) הצורה המקורית מופיעה בשם כמילה שלמה
3–4 הגזע מוכל בטוקן של השם. בלי שום סובלנות לשגיאה
5 ומעלה שני תנאים יחד: השרת היה מתאים אותה, וגם כל ההבדל "נשמע". זה השינוי של ס46
"נשמע" פירושו שמותרות רק שתי עריכות:החלפה בין אותיות שנשמעות אותו דבר: ט/ת, כ/ח, כ/ק, ס/ש, א/ע/ה, ב/ו, ועוד זוג אחד שנצפה בשיחה אמיתית, ד/ת ("שס חדנים").
הוספה או השמטה של אם קריאה (א, ה, ו, י), כמו שולחן/שלחן.
כל החלפה אחרת פוסלת. לכן "שס קטנים" כבר לא מחזיר את "קרנים": ט ו-ר אינן נשמעות דומה. ההשוואה נעשית גם על הגזע וגם על צורת פני השטח, כדי ש"סמיטה" ימצא את "שמיטה" למרות שהגיזום הוריד את ה-ש רק בצד אחד.ב. מילים בנות שתי אותיות שאינן מבניות
מילה כזו לבדה לא מזהה ספר. אבל אם נאמרה, היא חייבת להופיע בשם בדיוק, למשל ים של שלמה.ג. שלילה
"לא מנוקד" פוסל שם שאומר "מנוקד" בלי "לא" לפניו, וההפך. שם שלא מזכיר את המאפיין בכלל עובר.ד. אם אף מועמד לא עבר
עוברים לניסיון הבא. אם אף ניסיון לא הניב כלום, התשובה היא 0 תוצאות, במכוון (כ8).
בחזרה למנגנון הדיבור:
בודק אם יש התאמות של מאפיינים, לדוגמא כריכת עור, אם יש - כל מה שלא מתאים מסונן.
סדרות של יותר מ4 כרכים שכל כרך נמכר בנפרד מקובצות ל"סדרה של X כרכים" (הניסוח קצת מטעה בעיני)
יש עדיפות לספרים עם שם מדויק יותר
אם יש יותר מ5 תוצאות מבקשים מהמאזין לדייק בשם הספרמה אתם אומרים?
ברור שיש עוד תיקונים לעשות והוא עוד לא מושלם אבל מה הכיוןן?@pcinfogmach במקום אחר המלצת למישהו לעשות מנגנון פיצוי/ניקוד, על מה מדובר?
-
@עידו300
מחילה
אם אתה רוצה שאעזור לך תגיד לי בקצרה במה מדובר ואל תעלה לי םה מה שהבינה אמרה לך
אין לי זמן לקרוא מגילות וגם לא לפענח רמזים
רק תתאמץ קצת אין לך מה להסתיר וכבר תקבל כל מה שאתה רוצה על מגש של כסף@pcinfogmach אני מאוד מעריך את את העזרה של כולם, ואני לא רואה בעין יפה שזורקים פלט של AI לעוזרים.
לכן בקשתי מהבינה שתכתוב לי איך המנגנון כיום אחרי השינויים שהציעו כאן עובד (אין לי מושג איך היא בנתה אותו הייתי חייב לברר לפני שאני שואל כאן) ואני לקחתי ותמצתתי וכתבתי את כל הקטע הנ"ל במו ידי על אף השעה. השתדלתי שיהיה בצורה מאוד קלילה וברורה בלי אריכות וסיבוכים של AI (אם יש דבר אחד שAI לא יודע לעשות, או לפחות לא עושה את זה כברירת מחדל, זה לכתוב כמו שצריך, במקום משפט הוא כותב 2-3), אם חשבתם שפשוט זרקתי לכם את התוצאה של הAI, עמכם הסליחה! (אולי גם עימי על "חושד בכשרים", אבל לא משנה
).בכל אופן, המטרה של הפרויקט היא יצירת מערכת בוטי מידע ושירות לקוחות (לפחות בשלב זה) לבעלי עסקים.
הלב של הפרויקט הוא מערכת שמכילה את המוצרים והמידע של העסק ושיודעת לחפש בהם ולהפיק הצעות מחיר. וגם לנהל את המידע עם API (לטובת שימוש בAI)..
מכאן זה מתחלק לבוטים במייל, טלפון ובהמשך צ'אטים וכו'.
הבעיה מתחילה בבוט הטלפוני שם התמלול עושה שמות וצריך חיפוש שידע להתאים את זה נכון, אבל לא יהיה רך מידי וימצא גם דברים שממש לא קשורים.
בגלל שעיקר הבעיה היא בבוט הטלפוני אז חלק מהכללים צריכים להיות רק בו ולא במנגנון הראשי, אין טעם לאלץ את כל הבוטים בגלל האילוצים שלו.
שלום! נראה שהשיחה הזו מעניינת אותך, אבל עדיין אין לך חשבון.
נמאס לכם לגלול בין אותם הפוסטים בכל ביקור? כשנרשמים לחשבון, תמיד תחזרו בדיוק למקום שבו הייתם קודם, ותוכלו לבחור לקבל התראות על תגובות חדשות (בין אם במייל, ובין אם בהתראת פוש). תוכלו גם לשמור סימניות ולפרגן ב-upvote לפוסטים כדי להביע הערכה לחברי קהילה אחרים.
בעזרת התרומה שלך, הפוסט הזה יכול להיות אפילו טוב יותר 💗
הרשמה התחברות