Advertisement
Guest User

Untitled

a guest
Dec 15th, 2019
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.38 KB | None | 0 0
  1. from math import sqrt
  2.  
  3.  
  4. def sim_distance(prefs, person1, person2):
  5. """
  6. Враќа мерка за сличност базирана на растојание помеѓу person1 и person2
  7. :param prefs: речник со оцени од корисници
  8. :param person1: име на корисник1
  9. :param person2: име на корисник2
  10. :return: сличност помеѓу корисник1 и корисник2
  11. """
  12. # Се прави листа на заеднички предмети
  13. si = {}
  14. for item in prefs[person1]:
  15. if item in prefs[person2]:
  16. si[item] = 1
  17. # Ако немаат заеднички рејтинзи, врати 0
  18. if len(si) == 0:
  19. return 0
  20. # Собери ги квадратите на сите разлики
  21. sum_of_squares = sum([pow(prefs[person1][item] - prefs[person2][item], 2)
  22. for item in prefs[person1] if item in prefs[person2]])
  23. return 1 / (1 + sqrt(sum_of_squares))
  24.  
  25.  
  26. def sim_pearson(prefs, p1, p2):
  27. """
  28. Го враќа коефициентот на Пирсонова корелација помеѓу p1 и p2 (личност1 и личност 2).
  29. Вредностите се помеѓу -1 и 1
  30. :param prefs: речник со оцени од корисници
  31. :param p1: име на корисник1
  32. :param p2: име на корисник2
  33. :return: сличност помеѓу корисник1 и корисник2
  34. """
  35. # Се креира речник во кој ќе се чуваат предметите кои се оценети од двајцата
  36. # Во речникот ни се важни само клучевите за да ги чуваме имињата на филмовите
  37. # кои се заеднички, а вредностите не ни се важни
  38. si = {}
  39. for item in prefs[p1]:
  40. if item in prefs[p2]:
  41. si[item] = 1
  42.  
  43. # Се пресметува бројот на предмети оценети од двајцата
  44. n = len(si)
  45.  
  46. # Ако немаат заеднички предмети, врати корелација 0
  47. if n == 0:
  48. return 0
  49.  
  50. # Собери ги сите оцени за секоја личност посебно
  51. sum1 = sum([prefs[p1][it] for it in si])
  52. sum2 = sum([prefs[p2][it] for it in si])
  53. # Собери ги квадратите од сите оцени за секоја личност посебно
  54. sum1Sq = sum([pow(prefs[p1][it], 2) for it in si])
  55. sum2Sq = sum([pow(prefs[p2][it], 2) for it in si])
  56. # Собери ги производите од оцените на двете личности
  57. pSum = sum([prefs[p1][it] * prefs[p2][it] for it in si])
  58.  
  59. # Пресметај го коефициентот на корелација
  60. num = pSum - (sum1 * sum2 / n)
  61. den = sqrt((sum1Sq - pow(sum1, 2) / n) * (sum2Sq - pow(sum2, 2) / n))
  62. if den == 0:
  63. return 0
  64. r = num / den
  65. return r
  66.  
  67.  
  68. def top_matches(prefs, person, n=5, similarity=sim_pearson):
  69. """
  70. Ги враќа најсличните n корисници за даден корисник.
  71. :param prefs: речник со оцени од корисници
  72. :param person: име на корисник
  73. :param n: број на слични корисници
  74. :param similarity: метрика за сличност
  75. :return: листа со најслични n корисници
  76. """
  77. scores = [(similarity(prefs, person, other), other)
  78. for other in prefs if other != person]
  79. # Се сортира листата во растечки редослед
  80. scores.sort()
  81. # Се превртува за најсличните (со најголема вредност) да бидат први
  82. scores.reverse()
  83. return scores[0:n]
  84.  
  85.  
  86. def get_recommendations(prefs, person, similarity=sim_pearson):
  87. """
  88. Ги враќа препораките за даден корисник со користење на тежински просек
  89. со оцените од другите корисници
  90. :param prefs: речник со оцени од корисници
  91. :param person: име на корисник
  92. :param similarity: метрика за сличност
  93. :return: препораки за даден корисник
  94. """
  95. totals = {}
  96. simSums = {}
  97. for other in prefs:
  98. # За да не се споредува со самиот себе
  99. if other == person:
  100. continue
  101. sim = similarity(prefs, person, other)
  102. # не се земаат предвид резултати <= 0
  103. if sim <= 0:
  104. continue
  105. for item in prefs[other]:
  106. # за тековниот корисник ги земаме само филмовите што ги нема гледано
  107. if item not in prefs[person] or prefs[person][item] == 0:
  108. # Similarity * Score
  109. totals.setdefault(item, 0)
  110. totals[item] += prefs[other][item] * sim
  111.  
  112. # Сума на сличности
  113. simSums.setdefault(item, 0)
  114. simSums[item] += sim
  115.  
  116. # Креирање на нормализирана листа со рејтинзи
  117. rankings = [(total / simSums[item], item) for item, total in totals.items()]
  118.  
  119. # Сортирање на листата во растечки редослед. Превртување на листата за најголемите вредности да бидат први
  120. rankings.sort(reverse=True)
  121.  
  122. return rankings
  123.  
  124.  
  125. def get_recommendations_item_based(inverted_prefs, person):
  126. """
  127. Ги враќа препораките за даден корисник со користење на тежински просек
  128. со оцените од предметите
  129. :param inverted_prefs: инвертиран речник со оцени од корисници, item-based
  130. :param person: име на корисник
  131. :return: препораки за даден корисник
  132. """
  133. similarity_per_item = {}
  134. person_items = [item for item, values in inverted_prefs.items() if person in values.keys()]
  135. for item in person_items:
  136. similar_items = top_matches(inverted_prefs, item, n=None)
  137. my_rating = inverted_prefs[item][person]
  138. for similarity, item in similar_items:
  139. if person in inverted_prefs[item] or similarity <= 0:
  140. continue
  141. similarity_per_item.setdefault(item, [])
  142. similarity_per_item[item].append(similarity * my_rating)
  143.  
  144. # Креирање на нормализирана листа со рејтинзи
  145. similarity_per_item_avg = [(sum(similarity_per_item[item]) / len(similarity_per_item[item]), item) for item in
  146. similarity_per_item]
  147. similarity_per_item_avg.sort(reverse=True)
  148.  
  149. return similarity_per_item_avg
  150.  
  151.  
  152. def transform_prefs(prefs):
  153. """
  154. Ги трансформира рејтинзите така што клучеви ќе бидат филмовите,
  155. а вредност ќе биде листа со рејтинзи од секој корисник
  156. :param prefs: речник со оцени од корисници
  157. :return: инвертиран речник со оцени од корисници
  158. """
  159. result = {}
  160. for person in prefs:
  161. for item in prefs[person]:
  162. result.setdefault(item, {})
  163. # Замени ги местата на корисникот и предметот
  164. result[item][person] = prefs[person][item]
  165. return result
  166.  
  167.  
  168. ratings = {
  169. 'Lisa Rose': {'Catch Me If You Can': 3.0, 'Snakes on a Plane': 3.5, 'Superman Returns': 3.5,
  170. 'You, Me and Dupree': 2.5, 'The Night Listener': 3.0, 'Snitch': 3.0},
  171. 'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5, 'Just My Luck': 1.5, 'The Night Listener': 3.0,
  172. 'You, Me and Dupree': 3.5},
  173. 'Michael Phillips': {'Catch Me If You Can': 2.5, 'Lady in the Water': 2.5, 'Superman Returns': 3.5,
  174. 'The Night Listener': 4.0, 'Snitch': 2.0},
  175. 'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0, 'The Night Listener': 4.5, 'Superman Returns': 4.0,
  176. 'You, Me and Dupree': 2.5},
  177. 'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 'Just My Luck': 2.0, 'Superman Returns': 3.0,
  178. 'You, Me and Dupree': 2.0},
  179. 'Jack Matthews': {'Catch Me If You Can': 4.5, 'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,
  180. 'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5, 'Snitch': 4.5},
  181. 'Toby': {'Snakes on a Plane': 4.5, 'Snitch': 5.0},
  182. 'Michelle Nichols': {'Just My Luck': 1.0, 'The Night Listener': 4.5, 'You, Me and Dupree': 3.5,
  183. 'Catch Me If You Can': 2.5, 'Snakes on a Plane': 3.0},
  184. 'Gary Coleman': {'Lady in the Water': 1.0, 'Catch Me If You Can': 1.5, 'Superman Returns': 1.5,
  185. 'You, Me and Dupree': 2.0},
  186. 'Larry': {'Lady in the Water': 3.0, 'Just My Luck': 3.5, 'Snitch': 1.5, 'The Night Listener': 3.5}
  187. }
  188.  
  189.  
  190. def najvisoka_sum(inv1):
  191. result = []
  192. # ovde inv imam kako kluc filmot pa vrednost vrednosta mi e sostavena od korsnik pa ocenka, korsnik pa ocenka za toj film
  193.  
  194. for korisnik, rejtings in inv1.items():
  195. pomosna = list(rejtings.values())
  196. suma = sum(pomosna)
  197. result.append((suma, korisnik))
  198. result.sort(reverse=True)
  199. return result[0][1]
  200.  
  201.  
  202. if __name__ == '__main__':
  203. user_name = input()
  204.  
  205. soEvk = get_recommendations(ratings, user_name, similarity=sim_distance)
  206.  
  207. film1 = soEvk[0][1];
  208.  
  209. soPer = get_recommendations(ratings, user_name, similarity=sim_pearson)
  210.  
  211. film2 = soPer[0][1]
  212.  
  213. if film1 == film2:
  214. print(film1)
  215.  
  216. inv1 = transform_prefs(ratings)
  217. inv = get_recommendations_item_based(inv1, user_name)
  218. film3 = inv[0][1]
  219.  
  220. if film1 == film3:
  221. print(film3)
  222. if film2 == film3:
  223. print (film3)
  224.  
  225. elif film1!=film2 and film3!=film1 and film3!=film2:
  226. inv1 = transform_prefs(ratings)
  227. result = najvisoka_sum(inv1)
  228. print(result)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement