Spaces:
Running
Running
| function termFreq(text) { | |
| const words = text.toLowerCase().match(/\w+/g) || []; | |
| const freq = {}; | |
| words.forEach(w => freq[w] = (freq[w] || 0) + 1); | |
| return freq; | |
| } | |
| export function cosineSimilarity(textA, textB) { | |
| const fA = termFreq(textA); | |
| const fB = termFreq(textB); | |
| const words = new Set([...Object.keys(fA), ...Object.keys(fB)]); | |
| let dot = 0, magA = 0, magB = 0; | |
| words.forEach(w => { | |
| const a = fA[w] || 0; | |
| const b = fB[w] || 0; | |
| dot += a * b; | |
| magA += a * a; | |
| magB += b * b; | |
| }); | |
| if (!magA || !magB) return 0; | |
| return dot / (Math.sqrt(magA) * Math.sqrt(magB)); | |
| } | |
| export function searchChunks(query, chunks, topK = 2) { | |
| if (!chunks || chunks.length === 0) return []; | |
| return chunks | |
| .map(c => ({ text: c, score: cosineSimilarity(query, c) })) | |
| .sort((a, b) => b.score - a.score) | |
| .slice(0, topK) | |
| .map(item => item.text); | |
| } |