1
\$\begingroup\$

I am looking for the fastest way to find document distance. How can I improve this?

Split each document into words. replaceAll() is faster than replace()

String.prototype.replaceAll = function(search, replacement) {
    return this.replace(new RegExp(search, 'g'), replacement);
};

Creating word array here:

const wordsFromDocument = doc => {
    //we care only about alphanumeric characters and space
    return doc.replaceAll(/[^a-zA-Z0-9 ]/g, ``).split(` `);
};

count word frequencies (document vectors)

const wordFrequencies = words => {
    const wordFrequencyMap = new Map();
    for (const word of words) {
        const lowerCaseWord = word.toLowerCase(); //We don't care about case sensitivity. What is faster way to achieve this?
        if (!wordFrequencyMap.has(lowerCaseWord)) {
            wordFrequencyMap.set(lowerCaseWord, 1);
        } else {
            wordFrequencyMap.set(lowerCaseWord, wordFrequencyMap.get(lowerCaseWord) + 1);
        }
    }
    return wordFrequencyMap;
};

Compute dot product (& divide).

const dotProduct = (wordFrequencyMapOne, wordFrequencyMapTwo) => {
    let sum = 0;
    const wordOneSize = wordFrequencyMapOne.size;
    const wordTwoSize = wordFrequenciesTwo.size;

    if (wordOneSize < wordTwoSize) {
        for (let key of wordFrequencyMapOne.keys()) {
            if (wordFrequencyMapTwo.has(key)) {
                sum = sum + wordFrequencyMapOne.get(key) *
                    wordFrequencyMapTwo.get(key);
            }
        }
    } else {
        for (let key of wordFrequenciesTwo.keys()) {
            if (wordFrequenciesOne.has(key)) {
                sum = sum + wordFrequencyMapOne.get(key) *
                    wordFrequencyMapTwo.get(key);
            }
        }
    }
    return sum;
};

vector angle = (dot(1, 2)) / Sqrt (dot(1, 1) * dot(2, 2))

const vectorAngle = (wordFrequencyMapOne, wordFrequencyMapTwo) => {
    const numerator = dotProduct(wordFrequencyMapOne, wordFrequencyMapTwo);
    const denominator = Math.sqrt(dotProduct(wordFrequencyMapOne, wordFrequencyMapOne) * (dotProduct(wordFrequenciesTwo, wordFrequenciesTwo)))
    return numerator / denominator;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.