Skip to content

Instantly share code, notes, and snippets.

@mattpodwysocki
Created March 30, 2009 00:28
Show Gist options
  • Save mattpodwysocki/87582 to your computer and use it in GitHub Desktop.
Save mattpodwysocki/87582 to your computer and use it in GitHub Desktop.
#light
module Map =
let insertWith (f:'a -> 'a -> 'a) (k:'tkey) (v:'a) (m:Map<'tkey, 'a>) =
match Map.tryfind k m with
| None -> Map.add k v m
| Some x -> let res = f v x
Map.add k res m
// Gets recommendations for a person by using a weighted average
let getRecommendations
(prefs:Map<string, Map<string, float>>)
(person:string)
(similarity:Map<string, Map<string, float>> -> string -> string -> float) =
let totals, simSums =
Map.fold_right (fun other _ acc -> if other <> person then
let sim = similarity prefs person other
if sim > 0. then
Map.fold_right (fun item _ acc' ->
if not (prefs.[person].ContainsKey item) || prefs.[person].[item] = 0. then
let totals = Map.insertWith (+) item (prefs.[other].[item] * sim) (fst acc')
let simSums = Map.insertWith (+) item sim (snd acc')
(totals, simSums)
else
acc'
) prefs.[other] acc
else acc
else acc) prefs (Map.empty, Map.empty)
[for kvp in totals -> (kvp.Value / simSums.[kvp.Key], kvp.Key)]
|> List.sort_by fst
|> List.rev
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment