fix(common/models): adds 'soft bound' for reasonable 100% fat-finger corrections

This commit is contained in:
Joshua A. Horton 2022-09-09 15:35:12 +07:00
parent 9b29339594
commit 666b639404

View file

@ -171,6 +171,16 @@ class ModelCompositor {
}
}
// Is the token under construction newly-constructed / is there no pre-existing root?
// If so, we want to strongly avoid overcorrection, even for 'nearby' keys.
// (Strong lexical frequency differences can easily cause overcorrection when only
// one key's available.)
//
// NOTE: we only want this applied word-initially, when any corrections 'correct'
// 100% of the word. Things are generally fine once it's not "all or nothing."
let tailToken = contextTokens[contextTokens.length - 1];
const isTokenStart = tailToken.transformDistributions.length <= 1;
// TODO: whitespace, backspace filtering. Do it here.
// Whitespace is probably fine, actually. Less sure about backspace.
@ -212,9 +222,39 @@ class ModelCompositor {
id: inputTransform.id // The correction should always be based on the most recent external transform/transcription ID.
}
let rootCost = match.totalCost;
/* If we're dealing with the FIRST keystroke of a new sequence, we'll **dramatically** boost
* the exponent to ensure only VERY nearby corrections have a chance of winning, and only if
* there are significantly more likely words. We only need this to allow very minor fat-finger
* adjustments for 100% keystroke-sequence corrections in order to prevent finickiness on
* key borders.
*
* Technically, the probabilities this produces won't be normalized as-is... but there's no
* true NEED to do so for it, even if it'd be 'nice to have'. Consistently tracking when
* to apply it could become tricky, so it's simpler to leave out.
*
* Worst-case, it's possible to temporarily add normalization if a code deep-dive
* is needed in the future.
*/
if(isTokenStart) {
/* Suppose a key distribution: most likely with p=0.5,, second-most with 0.4 - a pretty
* ambiguous case that would only arise very near the center of the boundary between two keys.
* Raising (0.5/0.4)^16 ~= 35.53.
* That seems 'within reason' for correction very near boundaries.
*
* So, with the second-most-likely key being that close in probability, its best suggestion
* must be ~ 35.5x more likely than that of the truly-most-likely key to "win". So, it's not
* a HARD cutoff, but more of a 'soft' one. Keeping the principles in mind documented above,
* it's possible to tweak this to a more harsh or lenient setting if desired, rather than
* being totally "all or nothing" on which key is taken for highly-ambiguous keypresses.
*/
rootCost *= 16;
}
return {
sample: correctionTransform,
p: Math.exp(-match.totalCost)
p: Math.exp(-rootCost)
};
}, this);