brainy/examples/test-threshold-tuning.js

78 lines
2.8 KiB
JavaScript
Raw Normal View History

feat: Phase 3 - Unified Semantic Type Inference (Nouns + Verbs) New Features: - Unified semantic type inference for 31 NounTypes + 40 VerbTypes - 4 new public APIs: inferTypes(), inferNouns(), inferVerbs(), inferIntent() - 1050 keywords with pre-computed embeddings (716 nouns + 334 verbs) - TypeAwareQueryPlanner with intelligent routing (up to 31x speedup) - Sub-millisecond inference latency with 95%+ accuracy Technical Implementation: - Single HNSW index for O(log n) semantic search across all types - Handles typos, synonyms, and semantic similarity automatically - 11MB embedded keywords optimized with Q8 quantization - Automated build system for keyword embedding generation - Complete TypeScript support with full type safety Integration Points: - Triple Intelligence System enhanced with type-aware planning - TypeAwareQueryPlanner uses inferNouns() for intelligent routing - Ready for import pipeline (entity + relationship extraction) - Ready for neural operations (concept + action extraction) Performance Characteristics: - Inference: 1-2ms (uncached), 0.2-0.5ms (cached) - Query speedup: 31x single-type, 6-15x multi-type - Completes Phase 1-3 billion-scale optimization strategy - Combined: 99.76% memory reduction + 6000x rebuild + 31x queries Backward Compatibility: - Zero breaking changes to existing APIs - All existing code works unchanged - New features opt-in via new public functions - Tests: 514 passing (61 pre-existing failures in storage UUID validation) Files Changed: - New: src/query/semanticTypeInference.ts (440 lines) - New: src/query/typeAwareQueryPlanner.ts (453 lines) - New: scripts/buildKeywordEmbeddings.ts (571 lines) - New: src/neural/embeddedKeywordEmbeddings.ts (11MB, 1050 keywords) - Modified: src/brainy.ts, src/triple/TripleIntelligenceSystem.ts - Modified: src/index.ts (export 4 new APIs) - New: 4 integration tests, 4 example demos - New: R2 storage adapter 🧠 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-16 10:59:26 -07:00
/**
* Test different vector thresholds to find optimal balance
*/
import { TypeInferenceSystem } from '../dist/query/typeInference.js';
async function testThresholds() {
console.log('🎯 Vector Threshold Tuning Test\n');
console.log('='.repeat(60));
// Test queries: typos and edge cases
const testCases = [
{ query: 'Find pysicians', expected: 'person', description: 'Typo: physician' },
{ query: 'Find documnets', expected: 'document', description: 'Typo: documents' },
{ query: 'Find organiztions', expected: 'organization', description: 'Typo: organizations' },
{ query: 'Find kompanies', expected: 'organization', description: 'Severe typo: companies' },
{ query: 'Find enginners', expected: 'person', description: 'Typo: engineers' },
{ query: 'Find xyzabc', expected: null, description: 'Nonsense word (should fail)' }
];
// Test with different thresholds
const thresholds = [0.35, 0.30, 0.25, 0.20];
for (const threshold of thresholds) {
console.log(`\n📊 Testing with vectorThreshold = ${threshold}`);
console.log('-'.repeat(60));
const system = new TypeInferenceSystem({
enableVectorFallback: true,
fallbackConfidenceThreshold: 0.7,
vectorThreshold: threshold,
debug: false
});
let successes = 0;
let falsePositives = 0;
for (const testCase of testCases) {
const results = await system.inferTypesAsync(testCase.query);
const matched = results.length > 0;
const correctType = results.length > 0 && results[0].type === testCase.expected;
if (testCase.expected === null) {
// Should NOT match
if (!matched) {
successes++;
console.log(` ✅ "${testCase.query}" correctly returned no matches`);
} else {
falsePositives++;
console.log(` ❌ "${testCase.query}" false positive: ${results[0].type} (${(results[0].confidence * 100).toFixed(1)}%)`);
}
} else {
// Should match expected type
if (correctType) {
successes++;
console.log(` ✅ "${testCase.query}" → ${results[0].type} (${(results[0].confidence * 100).toFixed(1)}%)`);
} else if (matched) {
console.log(` ⚠️ "${testCase.query}" → ${results[0].type} (expected ${testCase.expected})`);
} else {
console.log(` ❌ "${testCase.query}" no match (expected ${testCase.expected})`);
}
}
}
const accuracy = (successes / testCases.length) * 100;
console.log(`\n Accuracy: ${successes}/${testCases.length} (${accuracy.toFixed(0)}%), False positives: ${falsePositives}`);
}
console.log('\n' + '='.repeat(60));
console.log('✅ Threshold tuning complete!');
console.log('='.repeat(60));
}
testThresholds().catch(err => {
console.error('❌ Error:', err.message);
process.exit(1);
});