Skip to content

Instantly share code, notes, and snippets.

@mattpodwysocki
Created March 28, 2009 19:58
Show Gist options
  • Save mattpodwysocki/87186 to your computer and use it in GitHub Desktop.
Save mattpodwysocki/87186 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 _ acc ->
if prefs.[p2].ContainsKey k then
Set.add k acc
else acc) prefs.[p1] Set.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
// Set.fold_left (fun acc key -> acc + prefs.[p1].[key]) 0. si
let sum1 = List.sum [for it in si -> prefs.[p1].[it]]
let sum2 = List.sum [for it in si -> prefs.[p2].[it]]
// Sums of the squares
// Set.fold_left (fun acc key -> acc + (pown prefs.[p1].[key] 2)) 0. si
let sum1Sq = List.sum [for it in si -> pown prefs.[p1].[it] 2]
let sum2Sq = List.sum [for it in si -> pown prefs.[p2].[it] 2]
// Sum of the products
// Set.fold_left (fun acc key -> acc + (prefs.[p1].[key] * prefs.[p2].[key])) 0. si
let pSum = List.sum [for it in si -> prefs.[p1].[it] * prefs.[p2].[it]]
// 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)> =
prefs
|> Seq.choose (fun kvp -> if kvp.Key <> person then
Some(similarity prefs person kvp.Key, kvp.Key)
else None)
|> List.of_seq
|> 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