Optimize lexical timing diagnostics and suppress dense WHERE diffusion edges

This commit is contained in:
2026-02-14 15:13:00 +08:00
parent 39aa7431c6
commit 15640d48f2
4 changed files with 40 additions and 7 deletions

View File

@@ -53,6 +53,9 @@ const CONFIG = {
where: 0.15, // location exact match — binary
how: 0.30, // action-term co-occurrence — Jaccard
},
WHERE_MAX_GROUP_SIZE: 16, // skip location-only pair expansion for over-common places
WHERE_FREQ_DAMP_PIVOT: 6, // location freq <= pivot keeps full WHERE score
WHERE_FREQ_DAMP_MIN: 0.20, // lower bound for damped WHERE contribution
// Post-verification (Cosine Gate)
COSINE_GATE: 0.45, // min cosine(queryVector, stateVector)
@@ -275,11 +278,24 @@ function buildGraph(allAtoms, excludeEntities = new Set()) {
const features = extractAllFeatures(allAtoms, excludeEntities);
const { entityIndex, locationIndex } = buildInvertedIndices(features);
const locationFreq = new Map();
for (const [loc, indices] of locationIndex.entries()) {
locationFreq.set(loc, indices.length);
}
// Candidate pairs: share ≥1 entity or same location
const pairSet = new Set();
collectPairsFromIndex(entityIndex, pairSet, N);
collectPairsFromIndex(locationIndex, pairSet, N);
let skippedLocationGroups = 0;
for (const [loc, indices] of locationIndex.entries()) {
if (!loc) continue;
if (indices.length > CONFIG.WHERE_MAX_GROUP_SIZE) {
skippedLocationGroups++;
continue;
}
const oneLocMap = new Map([[loc, indices]]);
collectPairsFromIndex(oneLocMap, pairSet, N);
}
// Compute three-channel edge weights for all candidates
const neighbors = Array.from({ length: N }, () => []);
@@ -294,7 +310,15 @@ function buildGraph(allAtoms, excludeEntities = new Set()) {
const fj = features[j];
const wWhat = overlapCoefficient(fi.interactionPairs, fj.interactionPairs);
const wWhere = (fi.location && fi.location === fj.location) ? 1.0 : 0.0;
let wWhere = 0.0;
if (fi.location && fi.location === fj.location) {
const freq = locationFreq.get(fi.location) || 1;
const damp = Math.max(
CONFIG.WHERE_FREQ_DAMP_MIN,
Math.min(1, CONFIG.WHERE_FREQ_DAMP_PIVOT / Math.max(1, freq))
);
wWhere = damp;
}
const wHow = jaccard(fi.actionTerms, fj.actionTerms);
const weight =
@@ -318,6 +342,7 @@ function buildGraph(allAtoms, excludeEntities = new Set()) {
xbLog.info(MODULE_ID,
`Graph: ${N} nodes, ${edgeCount} edges ` +
`(what=${channelStats.what} where=${channelStats.where} how=${channelStats.how}) ` +
`(whereSkippedGroups=${skippedLocationGroups}) ` +
`(${buildTime}ms)`
);