Pearson相关函数返回Nan

时间:2016-02-19 15:08:01

标签: javascript algorithm

我正在进行#34;编程集体智慧"中的练习,但我正在使用JavaScript。我对Pearson Correlation算法有点麻烦。这是功能:

function rec(object1, object2) {
  var sum1 = 0;
  var sum2 = 0;
  var squareSum1 = 0;
  var squareSum2 = 0;
  var productsSum = 0;
  var i;
  var commonKeys = commonProperties(object1, object2);

  for (i = 0; i >= commonKeys.length; i += 1) {
    sum1 += object1[commonKeys[i]];
    sum2 += object2[commonKeys[i]];

    squareSum1 += Math.pow(object1[commonKeys[i]], 2);
    squareSum2 += Math.pow(object2[commonKeys[i]], 2);

    productsSum += object1[commonKeys[i]] * object2[commonKeys[i]];
  }

  var num1 = productsSum - (sum1 * sum2 / commonKeys.length);
  var num2 = Math.sqrt((squareSum1 - (Math.pow(sum1, 2) / commonKeys.length)) * (squareSum2 - (Math.pow(sum2, 2) / commonKeys.length)));

  return num1 / num2;
}

Full JSFiddle是here。我通过JSLint运行它,这就是为什么它可能有点乱。谁知道什么是错的?

2 个答案:

答案 0 :(得分:2)

你在条件上有一点错误"对于",var"我"将永远不会超过commonKeys.length

function rec(object1, object2) {
  var sum1 = 0;
  var sum2 = 0;
  var squareSum1 = 0;
  var squareSum2 = 0;
  var productsSum = 0;
  var i;
  var commonKeys = commonProperties(object1, object2);

  for (i = 0; i < commonKeys.length; i += 1) {
    sum1 += object1[commonKeys[i]];
    sum2 += object2[commonKeys[i]];

    squareSum1 += Math.pow(object1[commonKeys[i]], 2);
    squareSum2 += Math.pow(object2[commonKeys[i]], 2);

    productsSum += object1[commonKeys[i]] * object2[commonKeys[i]];
  }

  var num1 = productsSum - (sum1 * sum2 / commonKeys.length);
  var num2 = Math.sqrt((squareSum1 - (Math.pow(sum1, 2) / commonKeys.length)) * (squareSum2 - (Math.pow(sum2, 2) / commonKeys.length)));

  return num1 / num2;
}

https://jsfiddle.net/98uoy87u/2/

它工作正常,给出&#34; -1&#34;作为答案。

再见。

答案 1 :(得分:1)

根据我的评论,您永远不会以i < commonKeys.length的形式输入for循环。纠正此错误后,您的算法是正确的。我已使用Excel对rec(janeSmith, johnSmith)验证了这一点。与脚本中的0.6507913734559685相比,Excel返回0.650791373。

&#13;
&#13;
	function intersection_destructive(a, b) {
	  var result = [];
	  while (a.length > 0 && b.length > 0) {
		if (a[0] < b[0]) {
		  a.shift();
		} else if (a[0] > b[0]) {
		  b.shift();
		} else /* they're equal */ {
		  result.push(a.shift());
		  b.shift();
		}
	  }

	  return result;
	}

	function commonProperties(object1, object2) {
	  var keys1 = Object.keys(object1);
	  var keys2 = Object.keys(object2);
	  return intersection_destructive(keys1, keys2);
	}

	var johnSmith = {
	  "Zoolander": 2.5,
	  "Batman Begins": 3.5,
	  "Deadpool": 4.5,
	  "Thor": 1.5
	};

	var janeSmith = {
	  "Zoolander": 4.5,
	  "Batman Begins": 3,
	  "Deadpool": 5,
	  "Thor": 2.5,
	  "The Avengers": 4,
	  "The Internship": 2.5
	};

	var johnDoe = {
		"Zoolander": 4,
	  "The Internship": 3,
	  "Batman Begins": 4.5,
	  "Thor": 5
	};

	function rec(object1, object2) {
	  var sum1 = 0;
	  var sum2 = 0;
	  var squareSum1 = 0;
	  var squareSum2 = 0;
	  var productsSum = 0;
	  var i;
	  var commonKeys = commonProperties(object1, object2);

	  for (i = 0; i < commonKeys.length; i += 1) {
		sum1 += object1[commonKeys[i]];
		sum2 += object2[commonKeys[i]];

		squareSum1 += Math.pow(object1[commonKeys[i]], 2);
		squareSum2 += Math.pow(object2[commonKeys[i]], 2);

		productsSum += object1[commonKeys[i]] * object2[commonKeys[i]];
	  }

	  var num1 = productsSum - ((sum1 * sum2) / (commonKeys.length));
	  
	  
	  var num2 = Math.sqrt(((squareSum1 - (Math.pow(sum1, 2)) / commonKeys.length)) * ((squareSum2 - (Math.pow(sum2, 2)) / commonKeys.length)));

	  return num1 / num2;
	}

	var value = rec(janeSmith, johnSmith);

	document.getElementById('value').innerHTML = value;
&#13;
<h1>
Value:
</h1>
<p id="value">

</p>
&#13;
&#13;
&#13;