UNPKG

comparative-judgement

Version:

Comparative Judgement Algorithms

160 lines (150 loc) 4.59 kB
/*jshint -W083 */ var _ = require('underscore'); var statutils = require('./statutils'); var rasch = statutils.rasch; var average = statutils.average; var resInfo = statutils.resInfo; var wms = statutils.wms; var math = require('mathjs'); var probabilities = function (players, decisions) { //Look up the true score of each player, and calculate the probabliity of the decision var probs = _.map(decisions, function (num, key) { return (rasch(_.find(players, function (pl) { return pl._id == num.chosen; }).trueScore, _.find(players, function (pl) { return pl._id == num.notChosen; }).trueScore)); }); return probs; }; var playerProbs = function (player, probs, decisions) { //Return the probabilities for the decisions the script was involved in var pprobs = []; for (var i = 0; i < decisions.length; i++) { if (decisions[i].chosen == player._id | decisions[i].notChosen == player._id) { pprobs.push(probs[i]); } } return pprobs; }; var getPlayerStats = function (players, probs, decisions) { // Loop through players var infit = []; for (var i = 0; i < players.length; i++) { // Get probs var pprobs = playerProbs(players[i], probs, decisions); // Get wms infit.push(wms(pprobs)); } return infit; }; var judgeProbs = function (judge, probs, decisions) { //Return the probabilities for the decisions the judge was involved in var jprobs = []; for (var i = 0; i < decisions.length; i++) { if (decisions[i].judge == judge._id) { jprobs.push(probs[i]); } } return jprobs; }; var getJudgeStats = function (judges, probs, decisions) { // Loop through judges var infit = []; for (var i = 0; i < judges.length; i++) { // Get probs var jprobs = judgeProbs(judges[i], probs, decisions); // Get wms infit.push(wms(jprobs)); } return infit; }; var estimateReliability = function (players) { var alpha; var mle; if (players.length > 1) { //get the true score error var tse = _.map(players, function (num, key) { return num.seTrueScore; }); var rms = _.reduce(tse, function (memo, num) { return memo + Math.pow(num, 2); }, 0); var rmse = Math.pow((rms / tse.length), 0.5); var tss = _.map(players, function (num, key) { return num.trueScore; }); var G = average(tss).deviation / rmse; alpha = (Math.pow(G, 2) - 1) / Math.pow(G, 2); //mle = 1 - average( SE^2 ( theta) ) / Var ( theta ) mle = _.reduce(players, function (memo, num) { return memo + Math.pow(num.seTrueScore, 2); }, 0); mle = mle / players.length; mle = 1 - (mle / math.var(tss)); } else { alpha = 0; mle = 0; } return {alpha:alpha, mle:mle}; }; var estimateCJ = function (task, players, iters, controller) { players.forEach(function (player) { if(!player.anchorScore){ player.trueScore = 0; player.seTrueScore = 0; } else { //console.log(player, 'setting anchor score to', player.anchorScore); player.trueScore = player.anchorScore; player.seTrueScore = 0; } }); if(!iters) iters=4; for (var i = iters; i >= 0; i--) { cjEstimation(players, players.slice(0), i); } controller(task, players); }; var cjEstimation = function (plyrs, players, iters) { for (var i = 0; i < plyrs.length; i++) { if(!plyrs[i].hasOwnProperty("anchorScore")){ var plyr = plyrs[i]; var myDec = plyr.decisions; var myTrueScore = plyr.trueScore; var myObs = plyr.observedScore; if (plyr.comparisons > 0) { var opps = _.map(myDec, function (id) { return _.find(players, function (pl) { return (pl._id == id); }); }); var myExp = _.reduce(opps, function (memo, num) { return memo + rasch(myTrueScore, num.trueScore); }, 0); //Calculate info var info = _.reduce(opps, function (memo, num) { return memo + rasch(myTrueScore, num.trueScore) * (1 - (rasch(myTrueScore, num.trueScore))); }, 0); if (iters > 0) { plyr.trueScore += ((plyr.observedScore - myExp) / info); } else { plyr.seTrueScore = 1 / Math.sqrt(info); } } } } }; module.exports = { rasch: rasch, average: average, estimateReliability: estimateReliability, resInfo: resInfo, estimateCJ: estimateCJ, cjEstimation: cjEstimation, probabilities: probabilities, judgeProbs: judgeProbs, getJudgeStats: getJudgeStats, playerProbs: playerProbs, getPlayerStats: getPlayerStats };