ivanakarpuzova

userItemSist

Sep 10th, 2019
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.04 KB | None | 0 0
  1. from math import sqrt
  2.  
  3. oceniPoKorisnici = {
  4. 'Lisa Rose': {'Catch Me If You Can': 3.0, 'Snakes on a Plane': 3.5, 'Superman Returns': 3.5,
  5. 'You, Me and Dupree': 2.5, 'The Night Listener': 3.0, 'Snitch': 3.0},
  6. 'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5, 'Just My Luck': 1.5, 'The Night Listener': 3.0,
  7. 'You, Me and Dupree': 3.5},
  8. 'Michael Phillips': {'Catch Me If You Can': 2.5, 'Lady in the Water': 2.5, 'Superman Returns': 3.5,
  9. 'The Night Listener': 4.0, 'Snitch': 2.0},
  10. 'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0, 'The Night Listener': 4.5, 'Superman Returns': 4.0,
  11. 'You, Me and Dupree': 2.5},
  12. 'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 'Just My Luck': 2.0, 'Superman Returns': 3.0,
  13. 'You, Me and Dupree': 2.0},
  14. 'Jack Matthews': {'Catch Me If You Can': 4.5, 'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,
  15. 'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5, 'Snitch': 4.5},
  16. 'Toby': {'Snakes on a Plane': 4.5, 'Snitch': 5.0},
  17. 'Michelle Nichols': {'Just My Luck': 1.0, 'The Night Listener': 4.5, 'You, Me and Dupree': 3.5,
  18. 'Catch Me If You Can': 2.5, 'Snakes on a Plane': 3.0},
  19. 'Gary Coleman': {'Lady in the Water': 1.0, 'Catch Me If You Can': 1.5, 'Superman Returns': 1.5,
  20. 'You, Me and Dupree': 2.0},
  21. 'Larry': {'Lady in the Water': 3.0, 'Just My Luck': 3.5, 'Snitch': 1.5, 'The Night Listener': 3.5}
  22. }
  23.  
  24.  
  25.  
  26.  
  27.  
  28. movies = {
  29. 'Lady in the Water': {'Gary Coleman': 1.0, 'Larry': 3.0, 'Jack Matthews': 3.0, 'Michael Phillips': 2.5,
  30. 'Gene Seymour': 3.0, 'Mick LaSalle': 3.0, 'Michelle Nichols': 3.0},
  31. 'Snakes on a Plane': {'Jack Matthews': 4.0, 'Mick LaSalle': 4.0, 'Claudia Puig': 3.5, 'Lisa Rose': 3.5, 'Toby': 4.5,
  32. 'Gene Seymour': 3.5},
  33. 'Just My Luck': {'Larry': 3.5, 'Claudia Puig': 3.0, 'Gene Seymour': 1.5, 'Mick LaSalle': 2.0,
  34. 'Michelle Nichols': 1.0},
  35. 'Superman Returns': {'Gary Coleman': 1.5, 'Jack Matthews': 5.0, 'Mick LaSalle': 3.0, 'Claudia Puig': 4.0,
  36. 'Lisa Rose': 3.5, 'Michael Phillips': 3.5},
  37. 'The Night Listener': {'Larry': 3.5, 'Jack Matthews': 3.0, 'Claudia Puig': 4.5, 'Lisa Rose': 3.0,
  38. 'Gene Seymour': 3.0, 'Michael Phillips': 4.0, 'Michelle Nichols': 4.5},
  39. 'You, Me and Dupree': {'Gary Coleman': 2.0, 'Jack Matthews': 3.5, 'Mick LaSalle': 2.0, 'Claudia Puig': 2.5,
  40. 'Lisa Rose': 2.5, 'Gene Seymour': 3.5, 'Michelle Nichols': 3.5},
  41. 'Catch Me If You Can': {'Lisa Rose': 3.0, 'Michael Phillips': 2.5, 'Jack Matthews': 4.5, 'Gary Coleman': 1.5},
  42. 'Snitch': {'Larry': 1.5, 'Toby': 5.0, 'Michael Phillips': 2.0, 'Lisa Rose': 3.0, 'Jack Matthews': 4.5}
  43. }
  44.  
  45. def sim_distance(oceni, person1, person2):
  46. # Se pravi lista na zaednicki predmeti (filmovi)
  47.  
  48. filmovi1=set(oceni[person1].keys())
  49. filmovi2=set(oceni[person2].keys())
  50. zaednicki = filmovi1.intersection(filmovi2)
  51. # print(filmovi1)
  52. # print(filmovi2)
  53. # print(zaednicki)
  54. # for item in oceni[person1].keys():
  55. # if item in oceni[person2]:
  56. # zaednicki.add(item)
  57. # # ako nemaat zaednicki rejtinzi, vrati 0
  58. if len(zaednicki) == 0: return 0
  59. # # Soberi gi kvadratite na zaednickite razliki
  60. suma = 0.0
  61. for item in zaednicki:
  62. ocena1 = oceni[person1][item]
  63. ocena2 = oceni[person2][item]
  64. suma += (ocena1 - ocena2) ** 2
  65. # print(item, person1, ocena1, person2, ocena2)
  66.  
  67. return round(1 / (1 + sqrt(suma)),2)
  68.  
  69.  
  70.  
  71.  
  72. # In[12]:
  73.  
  74.  
  75.  
  76. # Go vrakja koeficientot na Pearsonova korelacija pomegu p1 i p2 (licnost 1 i licnost 2)
  77. # Vrednostite se pomegu -1 i 1
  78. def sim_pearson(oceni, p1, p2):
  79. # Se kreira recnik vo koj ke se cuvaat predmetite (filmovi) koi se oceneti od dvajcata
  80. # Vo recnikot ni se vazni samo klucevite za da gi cuvame iminjata na filmovite koi se zaednicki, a vrednostite ne ni se vazni
  81. zaednicki = set()
  82. for item in oceni[p1]:
  83. if item in oceni[p2]:
  84. zaednicki.add(item)
  85.  
  86. # Se presmetuva brojot na predmeti oceneti od dvajcata
  87. n = len(zaednicki)
  88.  
  89. # Ako nemaat zaednicki predmeti vrati korelacija 0
  90. if n == 0: return 0
  91.  
  92. # Soberi gi zaednickite oceni (rejtinzi) za sekoja licnost posebno
  93. sum1 = 0
  94. sum2 = 0
  95.  
  96. # Soberi gi kvadratite od zaednickite oceni (rejtinzi) za sekoja licnost posebno
  97. sum1Sq = 0
  98. sum2Sq = 0
  99.  
  100. # Soberi gi proizvodite od ocenite na dvete licnosti
  101. pSum = 0
  102. for item in zaednicki:
  103. ocena1 = oceni[p1][item]
  104. ocena2 = oceni[p2][item]
  105. sum1 += ocena1
  106. sum1Sq += ocena1 ** 2
  107. sum2 += ocena2
  108. sum2Sq += ocena2 ** 2
  109. pSum += ocena1 * ocena2
  110.  
  111. # Presmetaj go koeficientot na korelacija
  112. num = pSum - (sum1 * sum2 / n)
  113. den = sqrt((sum1Sq - pow(sum1, 2) / n) * (sum2Sq - pow(sum2, 2) / n))
  114. if den == 0: return 0
  115. r = num / den
  116. return round(r,2)
  117.  
  118.  
  119.  
  120.  
  121. def topMatches_inline(oceni, person, n=5, similarity=sim_pearson):
  122. scores = [(similarity(oceni, person, other), other)
  123. for other in oceni if other != person]
  124. # Se sortira listata vo rastecki redosled
  125. scores.sort()
  126. # Se prevrtuva za najslicnite (so najgolema vrednost) da bidat prvi
  127. scores.reverse()
  128. return scores[0:n]
  129.  
  130.  
  131. def topMatches(oceni, person, n=5, similarity=sim_pearson):
  132. scores = []
  133. for person2 in oceni.keys():
  134. if person != person2:
  135. s = similarity(oceni, person, person2)
  136. scores.append((s, person2))
  137. # Se sortira listata vo rastecki redosled
  138. scores.sort()
  139. # Se prevrtuva za najslicnite (so najgolema vrednost) da bidat prvi
  140. scores.reverse()
  141. if n is None:
  142. return scores
  143. else:
  144. return scores[0:n]
  145.  
  146.  
  147.  
  148.  
  149.  
  150.  
  151.  
  152.  
  153.  
  154.  
  155.  
  156. # In[52]:
  157.  
  158.  
  159. def transformoceni(oceni):
  160. result = {}
  161. for person in oceni.keys():
  162. for item in oceni[person]:
  163. result.setdefault(item, {})
  164. # Zameni gi mestata na licnosta i predmetot
  165. result[item][person] = oceni[person][item]
  166. return result
  167.  
  168. def getRecommendations(oceni, person, similarity=sim_pearson, min_zaednicki=None):
  169. totals = {}
  170. simSums = {}
  171. for person2 in oceni.keys():
  172. # Za da ne se sporeduva so samiot sebe
  173. if person2 == person: continue
  174. filmovi1=set(oceni[person].keys())
  175. filmovi2=set(oceni[person2].keys())
  176. zaednicki = filmovi1.intersection(filmovi2)
  177. # ova e ako se bara minimum zaednicki filmovi
  178. # za da se zemat vo predvid ocenite na drugiot korisnik
  179. if min_zaednicki and len(zaednicki)<min_zaednicki:
  180. #print('So korisnikot', person2, 'imame samo',len(zaednicki),'filmovi, pa go preskoknuvame')
  181. continue
  182. sim = similarity(oceni, person, person2)
  183. # print(person,person2,sim)
  184. # ne se zemaat vo predvid rezultati <= 0
  185. if sim <= 0: continue
  186. #print(person,person2,sim)
  187. for item in oceni[person2].keys():
  188. # print(item, oceni[person].get(item, None), oceni[person2].get(item, None))
  189. # za tekovniot korisnik gi zemame samo filmovite sto gi nemame veke gledano
  190. if item not in oceni[person]: # or oceni[person][item] == 0:
  191. # similarity * Score (Slicnost * Ocena)
  192. #print(item, sim, oceni[person2][item], sim* oceni[person2][item])
  193. totals.setdefault(item, 0)
  194. totals[item] += oceni[person2][item] * sim
  195.  
  196. # Sumuma na slicnosti
  197. simSums.setdefault(item, 0)
  198. simSums[item] += sim
  199. #print()
  200. # return
  201. #print()
  202. # Kreiranje na normalizirana lista so rejtinzi
  203. # rankings = [(total / simSums[item], item) for item, total in totals.items()]
  204. rankings = []
  205. for item, weighted_score in totals.items():
  206. sim_total = simSums[item]
  207. my_score = round(weighted_score / sim_total, 1)
  208. #print(item, weighted_score, sim_total, my_score)
  209. rankings.append((my_score, item))
  210.  
  211. # Sortiranje na listata vo rastecki redosled
  212. rankings.sort(reverse=True)
  213. # Prevrtuvanje na lista za najgolemite vrednosti da bidat napred
  214. # rankings.reverse()
  215. return rankings
  216. # In[77]:
  217.  
  218.  
  219. def item_based(critics, person1, n=3):
  220. oceni_po_film = transformoceni(critics)
  221. similarity_per_item = {}
  222. for item in critics[person1].keys():
  223. similar_items = topMatches(oceni_po_film, item, n=None)
  224. my_rating = critics[person1][item]
  225.  
  226. for similarity, item2 in similar_items:
  227. if item2 in critics[person1] or similarity <= 0:
  228. # print('Slicnost', similarity, 'na', item,'so', item2)
  229. continue
  230. weight= similarity * my_rating
  231. # print('Slicnost', similarity, 'na', item,'so', item2, weight)
  232. similarity_per_item.setdefault(item2, [])
  233. similarity_per_item[item2].append(weight)
  234. # print(item, my_rating, list(similarity_per_item.items()))
  235. similarity_per_item_avg = []
  236. import numpy as np
  237. for item in similarity_per_item:
  238. #print(item, similarity_per_item[item])
  239. avg_sim = np.mean(similarity_per_item[item])
  240. similarity_per_item_avg.append((avg_sim, item))
  241. similarity_per_item_avg.sort(reverse=True)
  242. return similarity_per_item_avg[:n]
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249. if __name__ == "__main__":
  250. korisnik = 'Gary Coleman'
  251.  
  252. preporaki = getRecommendations(oceniPoKorisnici, korisnik)
  253. preporaki = preporaki[:3]
  254. rezultati = [ime for brojka, ime in preporaki]
  255. rezultati.sort()
  256. print('user-based :', rezultati)
  257.  
  258. preporaki2 = item_based(oceniPoKorisnici, korisnik)
  259. preporaki2 = preporaki2[:3]
  260. rezultati2 = [ime for brojka, ime in preporaki2]
  261. rezultati2.sort()
  262. print('item-based :', rezultati2)
Add Comment
Please, Sign In to add comment