Skip to content

Instantly share code, notes, and snippets.

@bltavares
Forked from renanreismartins/manhattan-distance.clj
Created December 23, 2014 15:22
Show Gist options
  • Save bltavares/a6e665f6183390df0ea7 to your computer and use it in GitHub Desktop.
Save bltavares/a6e665f6183390df0ea7 to your computer and use it in GitHub Desktop.
(use 'clojure.set)
(def data
{:Hailey {"Broken Bells" 4,
"Deadmau5" 1,
"Norah Jones" 4,
"The Strokes" 4,
"Vampire Weekend" 1}
:Veronica {"Blues Traveler" 3,
"Norah Jones" 5,
"Phoenix" 4,
"Slightly Stoopid" 2.5,
"The Strokes" 3}
:Jordyn {"Broken Bells" 4.5,
"Deadmau5" 4,
"Norah Jones" 5,
"Phoenix" 5,
"Slightly Stoopid" 4.5,
"The Strokes" 4,
"Vampire Weekend" 4.0}}
)
(defn common-singer-ratings-pairs [user-1 user-2]
(let [user-1-data (user-1 data)
user-2-data (user-2 data)
singers-1 (set (keys user-1-data))
singers-2 (set (keys user-2-data))
singers-in-common (intersection singers-1 singers-2)
ratings-for-both-users (fn [singer]
[(user-1-data singer) (user-2-data singer)])]
(map ratings-for-both-users singers-in-common)))
(defn abs [n] (max n (- n)))
(defn manhattan-distance [rating-pairs]
(->> rating-pairs
(map (fn [[a b]] (- a b)))
(map abs)
(reduce + 0)))
(defn nearest-neighbor [user]
(let [other-users (keys (dissoc data user))]
(->> other-users
(map (fn [neighbor]
[neighbor (manhattan-distance (common-singer-ratings-pairs user neighbor))]))
(sort-by last))))
(defn recommend [user]
(let [nearest (ffirst (nearest-neighbor user))
nearest-bands-lookup (nearest data)
nearest-bands (set (keys nearest-bands-lookup))
user-bands (set (keys (user data)))
possible-recomendations (difference nearest-bands user-bands)]
(->> possible-recomendations
(map (fn [band] [band (nearest-bands-lookup band)]))
(sort-by last >))))
(recommend :Hailey)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment