JavaScript 余弦相似度函数

10

我正在尝试创建一个余弦相似度函数,并将结果显示在HTML元素中。我已经写了以下代码:

function cosinesim(A,B){
        var dotproduct=0;
        var mA=0;
        var mB=0;
        for(i = 0; i < A.length;){
            dotproduct += (A[i] * B[i]);
            mA += (A[i]*A[i]);
            mB += (B[i]*B[i]);
        }
        mA = Math.sqrt(mA);
        mB = Math.sqrt(mB);
        var similarity = (dotproduct)/(mA)*(mB)
        return similarity;
    }

//.....

var array1 = [1,0,0,1];
var array2 = [1,0,0,0];

var p = cosinesim(array1,array2);
document.getElementById("sim").innerHTML = String(p);

我已经测试过,输入的两个数组长度相同,然而当我的代码执行到这里时就崩溃了,我找不出问题所在。
任何帮助都将不胜感激,谢谢。

5
请在你的代码中添加array1和array2的定义。 - Fabien Greard
4个回答

10
function cosinesim(A, B) {
    var dotproduct = 0;
    var mA = 0;
    var mB = 0;

    for(var i = 0; i < A.length; i++) {
        dotproduct += A[i] * B[i];
        mA += A[i] * A[i];
        mB += B[i] * B[i];
    }

    mA = Math.sqrt(mA);
    mB = Math.sqrt(mB);
    var similarity = dotproduct / (mA * mB);

    return similarity;
}


var array1 = [1, 0, 0, 1];
var array2 = [1, 0, 0, 0];

var p = cosinesim(array1, array2);

console.log(p);

这应该给出实际的余弦相似度。

  1. 你之前提到过,在你的 for 循环中缺少了 var ii++
  2. 在这一行代码中,加上括号以包围 (mA * mB)var similarity = dotproduct / (mA * mB); 如果没有括号,除法会先于乘法执行。

4

使用 JavaScript 的 map 和 reduce 功能

function dotp(x, y) {
  function dotp_sum(a, b) {
    return a + b;
  }
  function dotp_times(a, i) {
    return x[i] * y[i];
  }
  return x.map(dotp_times).reduce(dotp_sum, 0);
}

function cosineSimilarity(A,B){
  var similarity = dotp(A, B) / (Math.sqrt(dotp(A,A)) * Math.sqrt(dotp(B,B)));
  return similarity;
}


var array1 = [1,2,2,1];
var array2 = [1,3,2,0];

var p = cosineSimilarity(array1,array2);

console.log(p);

希望这能帮助到您!愉快编码!!

3

你的循环中错过了i++,导致进入无限循环。

for(i = 0; i < A.length;)替换为for(i = 0; i < A.length;i++)即可解决问题。


1
严重的错误也在这里:(dotproduct)/(mA)*(mB)是错误的,因为运算符优先级不正确。请改用(dotproduct)/(mA * mB),否则得分将不在[0,1]之间。 - hymloth

0

function cosinesim(A,B){
        var dotproduct=0;
        var mA=0;
        var mB=0;
        for(i = 0; i < A.length; i++){
            dotproduct += (A[i] * B[i]);
            mA += (A[i]*A[i]);
            mB += (B[i]*B[i]);
        }
        mA = Math.sqrt(mA);
        mB = Math.sqrt(mB);
        var similarity = (dotproduct)/(mA)*(mB)
        return similarity;
    }


var array1 = [1,0,0,1];
var array2 = [1,0,0,0];

var p = cosinesim(array1,array2);

console.log(p);


1
它可以超过1,但我认为它应该在-11之间。例如,如果我比较[1,1,0,0][1,1,0,0],它会给出2 - gazdagergo
1
@gazdagergo n@HardikShah 在JS中存在浮点数和数学问题,这可能是为什么它不像Python那样工作得好的原因吗? - leeand00

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接