synonym-optimizer
Version:
Finds the text which has the least number of repetitions
147 lines • 5.13 kB
JavaScript
;
/**
* @license
* Copyright 2019 Ludan Stoecklé
* SPDX-License-Identifier: Apache-2.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.SynOptimizer = void 0;
const helper_1 = require("./helper");
class SynOptimizer {
constructor(language) {
this.languageSyn = (0, helper_1.buildLanguageSyn)((0, helper_1.getIso2fromLocale)(language));
}
getStopWords(stopWordsToAdd, stopWordsToRemove, stopWordsOverride) {
let baseList;
// the base list
if (stopWordsOverride) {
baseList = stopWordsOverride.slice(0);
}
else {
baseList = this.languageSyn.getStandardStopWords();
}
// remove
if (stopWordsToRemove) {
baseList = baseList.filter((word) => {
return !stopWordsToRemove.includes(word);
});
}
// and add
if (stopWordsToAdd) {
baseList = baseList.concat(stopWordsToAdd);
}
return baseList.map((alt) => {
return alt.toLowerCase();
});
}
// this one is really used by RosaeNLG
scoreAlternative(alternative, stopWordsToAdd, stopWordsToRemove, stopWordsOverride, identicals, debugHolder) {
const stopwords = this.getStopWords(stopWordsToAdd, stopWordsToRemove, stopWordsOverride);
const filteredAlt = this.getStemmedWords(alternative, stopwords);
if (debugHolder) {
debugHolder.filteredAlt = filteredAlt;
}
const wordsWithPos = this.getWordsWithPos(filteredAlt, identicals, debugHolder);
if (debugHolder) {
// only keep ones with > 1 for readability
debugHolder.wordsWithPos = {};
Object.keys(wordsWithPos).forEach((word) => {
/* istanbul ignore next */
if (wordsWithPos[word].length > 1) {
debugHolder.wordsWithPos[word] = wordsWithPos[word];
}
});
}
// score
const score = this.getScore(wordsWithPos);
if (debugHolder) {
debugHolder.score = score;
}
return score;
}
getStemmedWords(text, stopwords) {
const res = this.languageSyn
.extractWords(text)
.map((alt) => {
return alt.toLowerCase();
})
.filter((alt) => {
return !stopwords.includes(alt);
})
.map((elt) => {
return this.stemWord(elt);
});
return res;
}
// used only by tests
getBest(alternatives, stopWordsToAdd, stopWordsToRemove, stopWordsOverride, identicals) {
const scores = [];
alternatives.forEach((alt) => {
scores.push(this.scoreAlternative(alt, stopWordsToAdd, stopWordsToRemove, stopWordsOverride, identicals, null));
});
return scores.indexOf(Math.min(...scores));
}
// exported for tests
getScore(wordsWithPos) {
let score = 0;
Object.keys(wordsWithPos).forEach((word) => {
const positions = wordsWithPos[word];
for (let j = 1; j < positions.length; j++) {
score += 1 / (positions[j] - positions[j - 1]);
}
});
return score;
}
stemWord(word) {
if (this.languageSyn.stemmer) {
return this.languageSyn.stemmer.stemWord(word);
}
return word;
}
getWordsWithPos(words, identicals, debugHolder) {
const identicalsMap = {};
if (identicals) {
// check type
if (!Array.isArray(identicals)) {
const err = new Error();
err.name = 'InvalidArgumentError';
err.message = `identicals must be a string[][]`;
throw err;
}
else {
identicals.forEach((identicalList) => {
if (!Array.isArray(identicalList)) {
const err = new Error();
err.name = 'InvalidArgumentError';
err.message = `identicals must be a string[][]`;
throw err;
}
});
}
if (debugHolder) {
debugHolder.identicals = identicals;
}
// do the job
identicals.forEach((identicalList) => {
const mapTo = identicalList.join('_');
identicalList.forEach((identicalElt) => {
identicalsMap[this.stemWord(identicalElt)] = mapTo;
});
});
}
if (debugHolder) {
debugHolder.identicalsMap = identicalsMap;
}
const wordsWithPos = {};
for (let j = 0; j < words.length; j++) {
const word = identicalsMap[words[j]] || words[j];
if (!wordsWithPos[word]) {
wordsWithPos[word] = [];
}
wordsWithPos[word].push(j);
}
return wordsWithPos;
}
}
exports.SynOptimizer = SynOptimizer;
//# sourceMappingURL=SynOptimizer.js.map