Skip to content

Instantly share code, notes, and snippets.

@bhelx
Created December 25, 2012 05:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bhelx/4371793 to your computer and use it in GitHub Desktop.
Save bhelx/4371793 to your computer and use it in GitHub Desktop.
/**
* A little code from Collective Intelligence translated to javascript
*/
var critics = {
"Lisa Rose": {
"Lady in the Water" : 2.5
, "Snakes on a Plane" : 3.5
, "Just My Luck" : 3.0
, "Superman Returns" : 3.5
, "You, Me and Dupree" : 2.5
, "The Night Listener" : 3.0
},
"Gene Seymour": {
"Lady in the Water" : 3.0
, "Snakes on a Plane" : 3.5
, "Just My Luck" : 1.5
, "Superman Returns" : 5.0
, "The Night Listener" : 3.0
, "You, Me and Dupree" : 3.5
},
"Michael Phillips": {
"Lady in the Water" : 2.5
, "Snakes on a Plane" : 3.0
, "Superman Returns" : 3.5
, "The Night Listener" : 4.0
},
"Claudia Puig": {
"Snakes on a Plane" : 3.5
, "Just My Luck" : 3.0
, "The Night Listener" : 4.5
, "Superman Returns" : 4.0
, "You, Me and Dupree" : 2.5
},
"Mick LaSalle": {
"Lady in the Water" : 3.0
, "Snakes on a Plane" : 4.0
, "Just My Luck" : 2.0
, "Superman Returns" : 3.0
, "The Night Listener" : 3.0
, "You, Me and Dupree" : 2.0
},
"Jack Matthews": {
"Lady in the Water" : 3.0
, "Snakes on a Plane" : 4.0
, "The Night Listener" : 3.0
, "Superman Returns" : 5.0
, "You, Me and Dupree" : 3.5
},
"Toby": {
"Snakes on a Plane" : 4.5
, "You, Me and Dupree" : 1.0
, "Superman Returns" : 4.0
}
};
function simDistance (prefs, person1, person2) {
var si = {} //shared items
, p1Prefs = prefs[person1]
, p2Prefs = prefs[person2]
;
for (var item in p1Prefs)
if (p2Prefs[item])
si[item] = 1;
if (Object.keys(si).length == 0)
return 0;
var sumOfSquares = 0;
for (var sharedItem in si)
sumOfSquares += Math.pow(p1Prefs[sharedItem] - p2Prefs[sharedItem], 2);
return 1 / (1 + Math.sqrt(sumOfSquares));
}
function simPearson (prefs, person1, person2) {
var si = {} //shared items
, p1Prefs = prefs[person1]
, p2Prefs = prefs[person2]
;
for (var item in p1Prefs)
if (p2Prefs[item]) si[item] = 1;
var n = Object.keys(si).length;
if (n == 0) return 0;
var sum1 = 0, sum2 = 0, sum1Sq = 0, sum2Sq = 0, pSum = 0;
for (var it in si) {
var p1 = p1Prefs[it], p2 = p2Prefs[it];
sum1 += p1;
sum2 += p2;
sum1Sq += Math.pow(p1, 2);
sum2Sq += Math.pow(p2, 2);
pSum += p1 * p2;
}
var num = pSum - (sum1 * sum2 / n);
var den = Math.sqrt((sum1Sq - Math.pow(sum1, 2) / n) * (sum2Sq - Math.pow(sum2, 2) / n));
if (den == 0) return 0;
return num / den;
}
function topMatches (prefs, person, n, similarity) {
n = n || 5;
similarity = similarity || simPearson;
var results = [];
for (var other in prefs)
if (other != person)
results.push([other, similarity(prefs, person, other)]);
results.sort(function (a, b) { return b[1] - a[1] });
results = results.splice(0, n);
return results;
}
function getRecommendations (prefs, person, similarity) {
similarity = similarity || simPearson;
var totals = {}, simSums = {};
for (var other in prefs) {
if (person == other) continue;
var sim = similarity(prefs, person, other);
if (sim <= 0) continue;
for (var item in prefs[other]) {
if (!prefs[person][item] || prefs[person][item] == 0) {
if (!totals[item]) totals[item] = 0;
if (!simSums[item]) simSums[item] = 0;
totals[item] += prefs[other][item] * sim;
simSums[item] += sim;
}
}
}
var rankings = [];
for (var item in totals) {
var total = totals[item];
rankings.push([item, total/simSums[item]]);
}
rankings.sort(function (a, b) { return b[1] - a[1] });
return rankings;
}
function transformPrefs (prefs) {
var results = {};
for (var person in prefs) {
for (var item in prefs[person]) {
if (!results[item]) results[item] = {};
results[item][person] = prefs[person][item];
}
}
return results;
}
function calculateSimilarItems (prefs, n) {
n = n || 10;
var result = {};
var itemPrefs = transformPrefs(prefs);
var c = 0;
for (var item in itemPrefs) {
c += 1;
if (c % 100 == 0) console.log(c, ' / ', Object.keys(itemPrefs).length);
var scores = topMatches(itemPrefs, item, n);
result[item] = scores;
}
return result;
}
module.exports.critics = critics;
module.exports.simDistance = simDistance;
module.exports.simPearson = simPearson;
module.exports.topMatches = topMatches;
module.exports.getRecommendations = getRecommendations;
module.exports.transformPrefs = transformPrefs;
module.exports.calculateSimilarItems = calculateSimilarItems;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment