Skip to content

Instantly share code, notes, and snippets.

@mattpodwysocki
Created March 28, 2009 07:21
Show Gist options
  • Save mattpodwysocki/87048 to your computer and use it in GitHub Desktop.
Save mattpodwysocki/87048 to your computer and use it in GitHub Desktop.
#light
let critics =
Map.of_list [("Lisa Rose",
Map.of_list [("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",
Map.of_list [("Lady in the Water", 3.0);("Snakes on a Plane", 3.5);
("Just My Luck", 1.5);("Superman Returns", 5.0);
("You, Me and Dupree", 3.5);("The Night Listener", 3.0)];);
("Michael Phillips",
Map.of_list [("Lady in the Water", 2.5);("Snakes on a Plane", 3.0);
("Superman Returns", 3.5);("The Night Listener", 4.0)];);
("Claudia Puig",
Map.of_list [("Snakes on a Plane", 3.5);("Just My Luck", 2.0);
("Superman Returns", 4.0);("You, Me and Dupree", 2.5);
("The Night Listener", 4.0)];);
("Mick LaSalle",
Map.of_list [("Lady in the Water", 3.0);("Snakes on a Plane", 4.0);
("Just My Luck", 2.0);("Superman Returns", 3.0);
("You, Me and Dupree", 2.0);("The Night Listener", 3.0)];);
("Jack Matthews",
Map.of_list [("Lady in the Water", 3.0);("Snakes on a Plane", 4.0);
("Superman Returns", 5.0);("You, Me and Dupree", 3.5);
("The Night Listener", 3.0)];);
("Matt",
Map.of_list [("Snakes on a Plane", 4.5);("Superman Returns", 4.0);
("You, Me and Dupree", 1.0)];);]
// Returns the Pearson correlation coefficient for p1 and p2
let sim_pearson (prefs:Map<string, Map<string, float>>) (p1:string) (p2:string) : float =
// Get the list of mutually rated items
let si = Map.fold_right (fun k v acc ->
if prefs.[p2].ContainsKey k then
Map.add k 1 acc
else acc) prefs.[p1] Map.empty
// if they are no ratings in common, return 0
let n = float si.Count
if n = 0. then 0.
else
// Sums of all the preferences
let sum1 = Map.fold_left (fun acc key _ -> acc + prefs.[p1].[key]) 0. si
let sum2 = Map.fold_left (fun acc key _ -> acc + prefs.[p2].[key]) 0. si
// Sums of the squares
let sum1Sq = Map.fold_left (fun acc key _ -> acc + (pown prefs.[p1].[key] 2)) 0. si
let sum2Sq = Map.fold_left (fun acc key _ -> acc + (pown prefs.[p2].[key] 2)) 0. si
// Sum of the products
let pSum = Map.fold_left (fun acc key _ -> acc + (prefs.[p1].[key] * prefs.[p2].[key])) 0. si
// Calculate r (Pearson score)
let num = pSum - (sum1 * sum2 / n)
let den = sqrt ((sum1Sq - (pown sum1 2) / n) * (sum2Sq - (pown sum2 2) / n ))
if den = 0. then 0.
else
num / den
// Returns the best matches for person from the prefs dictionary
let topMatches
(prefs:Map<string, Map<string, float>>)
(person:string) (n:int)
(similarity:Map<string, Map<string, float>> -> string -> string -> float)
: seq<(float * string)> =
Map.fold_right
(fun k v acc -> if k <> person then
(similarity prefs person k, k) :: acc
else
acc) prefs []
|> List.sort_by fst
|> List.rev
|> Seq.take n
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment