Created
December 6, 2020 20:47
-
-
Save edipretoro/0f6794246630a8ff012f7b6ad74cdfa1 to your computer and use it in GitHub Desktop.
A basic recommendation system based on loans data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from math import sqrt | |
import json | |
import pathlib | |
import pprint | |
def fill_resources(patrons): | |
all_resources = {} | |
for patron in patrons: | |
for resource, rating in patrons[patron].items(): | |
all_resources[resource] = 1 | |
for ratings in patrons.values(): | |
for item in all_resources: | |
if item not in ratings: | |
ratings[item] = 0.0 | |
def sim_pearson(loans, p1, p2): | |
si = {} | |
for item in loans[p1]: | |
if item in loans[p2]: | |
si[item] = 1 | |
n = len(si) | |
if n == 0: | |
return 0 | |
sum1 = sum([loans[p1][it] for it in si]) | |
sum2 = sum([loans[p2][it] for it in si]) | |
sum1Sq = sum([pow(loans[p1][it], 2) for it in si]) | |
sum2Sq = sum([pow(loans[p2][it], 2) for it in si]) | |
pSum = sum([loans[p1][it] * loans[p2][it] for it in si]) | |
num = pSum - (sum1 * sum2 / n) | |
den = sqrt((sum1Sq - pow(sum1, 2) / n) * (sum2Sq - pow(sum2, 2) / n)) | |
if den == 0: | |
return 0 | |
r = num / den | |
return r | |
def getRecommendations(loans, patron, similarity=sim_pearson): | |
totals = {} | |
simSums = {} | |
for other in loans: | |
if other == patron: | |
continue | |
sim = similarity(loans, patron, other) | |
if sim <= 0: | |
continue | |
for item in loans[other]: | |
if item not in loans[patron] or loans[patron][item] == 0: | |
totals.setdefault(item, 0) | |
totals[item] += loans[other][item] * sim | |
simSums.setdefault(item, 0) | |
simSums[item] += sim | |
rankings = [(total / simSums[item], item) for item, total in totals.items()] | |
rankings.sort() | |
rankings.reverse() | |
return rankings | |
if __name__ == "__main__": | |
patrons = json.loads(pathlib.Path("dataset.json").read_text()) | |
fill_resources(patrons) | |
user = "DI PRETORO, Emmanuel" | |
pprint.pprint(getRecommendations(patrons, user)[0:10]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment