ivanakarpuzova

soFormula

Sep 10th, 2019
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.13 KB | None | 0 0
  1. Системи за препораки
  2.  
  3. Да испрограмира функција за косинусна сличност која е дефинирана со следнава формула, каде A е листа со
  4. оцените на едниот корисник или филм, а B е листа со оцените на другиот корисник или филм:
  5.  
  6. enter image description here
  7. http://code.finki.ukim.mk/public/uploads/1453390764510.png
  8. similarity=cos(teta)=(A*b/||A|| ||B||)=(Suma(i do n)Ai*Bi)/sqrt(Suma(i do n)(Ai^2)*sqrt(Suma(i do n)(Bi^2))
  9. Притоа треба да се избегне делење со нула и во тој случај да се смета дека сличноста е -1.
  10.  
  11. Речник со оцени на корисници по филмови треба е веќе даден. Од стандардниот влез се вчитува име на еден
  12. филм. Да се испечати сличноста на прочитаниот филм со секој друг филм (освен самиот со себе) така што ќе
  13. се печати:
  14.  
  15. Филм 2
  16.  
  17. Косинусна сличност, Пеарсонова сличност, Евклидова сличност
  18.  
  19. Празна линија
  20.  
  21. При печатењето филмовите треба да бидат подредени по азбучен редослед. Сите сличности треба да бидат
  22. заокружени на 2 децимали.
  23. Vlez:
  24. 'Catch Me If You Can'
  25. IZlez:
  26. Just My Luck
  27. 1.0 0 0.4
  28.  
  29. Lady in the Water
  30. 0.98 0.89 0.39
  31.  
  32. Snakes on a Plane
  33. 0.99 0.96 0.54
  34.  
  35. Snitch
  36. 1.0 0.99 0.67
  37.  
  38. Superman Returns
  39. 1.0 0.96 0.45
  40.  
  41. The Night Listener
  42. 0.92 -0.73 0.26
  43.  
  44. You, Me and Dupree
  45. 0.97 0.69 0.39
  46.  
  47. from math import sqrt
  48.  
  49. oceniPoKorisnici = {
  50. 'Lisa Rose': {'Catch Me If You Can': 3.0, 'Snakes on a Plane': 3.5, 'Superman Returns': 3.5,
  51. 'You, Me and Dupree': 2.5, 'The Night Listener': 3.0, 'Snitch': 3.0},
  52. 'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5, 'Just My Luck': 1.5, 'The Night Listener': 3.0,
  53. 'You, Me and Dupree': 3.5},
  54. 'Michael Phillips': {'Catch Me If You Can': 2.5, 'Lady in the Water': 2.5, 'Superman Returns': 3.5,
  55. 'The Night Listener': 4.0, 'Snitch': 2.0},
  56. 'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0, 'The Night Listener': 4.5, 'Superman Returns': 4.0,
  57. 'You, Me and Dupree': 2.5},
  58. 'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 'Just My Luck': 2.0, 'Superman Returns': 3.0,
  59. 'You, Me and Dupree': 2.0},
  60. 'Jack Matthews': {'Catch Me If You Can': 4.5, 'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,
  61. 'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5, 'Snitch': 4.5},
  62. 'Toby': {'Snakes on a Plane': 4.5, 'Snitch': 5.0},
  63. 'Michelle Nichols': {'Just My Luck': 1.0, 'The Night Listener': 4.5, 'You, Me and Dupree': 3.5,
  64. 'Catch Me If You Can': 2.5, 'Snakes on a Plane': 3.0},
  65. 'Gary Coleman': {'Lady in the Water': 1.0, 'Catch Me If You Can': 1.5, 'Superman Returns': 1.5,
  66. 'You, Me and Dupree': 2.0},
  67. 'Larry': {'Lady in the Water': 3.0, 'Just My Luck': 3.5, 'Snitch': 1.5, 'The Night Listener': 3.5}
  68. }
  69.  
  70. def sim_distance(oceni, person1, person2):
  71. # Se pravi lista na zaednicki predmeti (filmovi)
  72.  
  73. filmovi1=set(oceni[person1].keys())
  74. filmovi2=set(oceni[person2].keys())
  75. zaednicki = filmovi1.intersection(filmovi2)
  76. # print(filmovi1)
  77. # print(filmovi2)
  78. # print(zaednicki)
  79. # for item in oceni[person1].keys():
  80. # if item in oceni[person2]:
  81. # zaednicki.add(item)
  82. # # ako nemaat zaednicki rejtinzi, vrati 0
  83. if len(zaednicki) == 0: return 0
  84. # # Soberi gi kvadratite na zaednickite razliki
  85. suma = 0.0
  86. for item in zaednicki:
  87. ocena1 = oceni[person1][item]
  88. ocena2 = oceni[person2][item]
  89. suma += (ocena1 - ocena2) ** 2
  90. # print(item, person1, ocena1, person2, ocena2)
  91.  
  92. return round(1 / (1 + sqrt(suma)),2)
  93.  
  94.  
  95.  
  96.  
  97. # In[12]:
  98.  
  99.  
  100.  
  101. # Go vrakja koeficientot na Pearsonova korelacija pomegu p1 i p2 (licnost 1 i licnost 2)
  102. # Vrednostite se pomegu -1 i 1
  103. def sim_pearson(oceni, p1, p2):
  104. # Se kreira recnik vo koj ke se cuvaat predmetite (filmovi) koi se oceneti od dvajcata
  105. # Vo recnikot ni se vazni samo klucevite za da gi cuvame iminjata na filmovite koi se zaednicki, a vrednostite ne ni se vazni
  106. zaednicki = set()
  107. for item in oceni[p1]:
  108. if item in oceni[p2]:
  109. zaednicki.add(item)
  110.  
  111. # Se presmetuva brojot na predmeti oceneti od dvajcata
  112. n = len(zaednicki)
  113.  
  114. # Ako nemaat zaednicki predmeti vrati korelacija 0
  115. if n == 0: return 0
  116.  
  117. # Soberi gi zaednickite oceni (rejtinzi) za sekoja licnost posebno
  118. sum1 = 0
  119. sum2 = 0
  120.  
  121. # Soberi gi kvadratite od zaednickite oceni (rejtinzi) za sekoja licnost posebno
  122. sum1Sq = 0
  123. sum2Sq = 0
  124.  
  125. # Soberi gi proizvodite od ocenite na dvete licnosti
  126. pSum = 0
  127. for item in zaednicki:
  128. ocena1 = oceni[p1][item]
  129. ocena2 = oceni[p2][item]
  130. sum1 += ocena1
  131. sum1Sq += ocena1 ** 2
  132. sum2 += ocena2
  133. sum2Sq += ocena2 ** 2
  134. pSum += ocena1 * ocena2
  135.  
  136. # Presmetaj go koeficientot na korelacija
  137. num = pSum - (sum1 * sum2 / n)
  138. den = sqrt((sum1Sq - pow(sum1, 2) / n) * (sum2Sq - pow(sum2, 2) / n))
  139. if den == 0: return 0
  140. r = num / den
  141. return round(r,2)
  142.  
  143.  
  144.  
  145.  
  146. def topMatches_inline(oceni, person, n=5, similarity=sim_pearson):
  147. scores = [(similarity(oceni, person, other), other)
  148. for other in oceni if other != person]
  149. # Se sortira listata vo rastecki redosled
  150. scores.sort()
  151. # Se prevrtuva za najslicnite (so najgolema vrednost) da bidat prvi
  152. scores.reverse()
  153. return scores[0:n]
  154.  
  155.  
  156. def topMatches(oceni, person, n=5, similarity=sim_pearson):
  157. scores = []
  158. for person2 in oceni.keys():
  159. if person != person2:
  160. s = similarity(oceni, person, person2)
  161. scores.append((s, person2))
  162. # Se sortira listata vo rastecki redosled
  163. scores.sort()
  164. # Se prevrtuva za najslicnite (so najgolema vrednost) da bidat prvi
  165. scores.reverse()
  166. if n is None:
  167. return scores
  168. else:
  169. return scores[0:n]
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181. # In[52]:
  182.  
  183.  
  184. def transformoceni(oceni):
  185. result = {}
  186. for person in oceni.keys():
  187. for item in oceni[person]:
  188. result.setdefault(item, {})
  189. # Zameni gi mestata na licnosta i predmetot
  190. result[item][person] = oceni[person][item]
  191. return result
  192.  
  193.  
  194. # In[77]:
  195.  
  196.  
  197. def item_based(critics, person1, n=3):
  198. oceni_po_film = transformoceni(critics)
  199. similarity_per_item = {}
  200. for item in critics[person1].keys():
  201. similar_items = topMatches(oceni_po_film, item, n=None)
  202. my_rating = critics[person1][item]
  203.  
  204. for similarity, item2 in similar_items:
  205. if item2 in critics[person1] or similarity <= 0:
  206. # print('Slicnost', similarity, 'na', item,'so', item2)
  207. continue
  208. weight= similarity * my_rating
  209. # print('Slicnost', similarity, 'na', item,'so', item2, weight)
  210. similarity_per_item.setdefault(item2, [])
  211. similarity_per_item[item2].append(weight)
  212. # print(item, my_rating, list(similarity_per_item.items()))
  213. similarity_per_item_avg = []
  214. import numpy as np
  215. for item in similarity_per_item:
  216. print(item, similarity_per_item[item])
  217. avg_sim = np.mean(similarity_per_item[item])
  218. similarity_per_item_avg.append((avg_sim, item))
  219. similarity_per_item_avg.sort(reverse=True)
  220. return similarity_per_item_avg[:n]
  221.  
  222.  
  223.  
  224. def sim_cos(oceni, p1, p2):
  225. zaednicki = set()
  226. for item in oceni[p1]:
  227. if item in oceni[p2]:
  228. zaednicki.add(item)
  229.  
  230. n = len(zaednicki)
  231. if n == 0: return 0
  232. sum1 = 0
  233. sum2 = 0
  234. sum1Sq = 0
  235. sum2Sq = 0
  236. pSum = 0
  237.  
  238. for item in zaednicki:
  239. ocena1 = oceni[p1][item]
  240. ocena2 = oceni[p2][item]
  241. sum1 += ocena1
  242. sum1Sq += ocena1 ** 2
  243. sum2 += ocena2
  244. sum2Sq += ocena2 ** 2
  245. pSum += ocena1 * ocena2
  246.  
  247. num = pSum
  248. den = sqrt(sum1Sq) * sqrt(sum2Sq)
  249. if den == 0: return -1
  250. r = num / den
  251. return round(r, 2)
  252.  
  253.  
  254. def transformoceni(oceni):
  255. result = {}
  256. for person in oceni.keys():
  257. for item in oceni[person]:
  258. result.setdefault(item, {})
  259. # Zameni gi mestata na licnosta i predmetot
  260. result[item][person] = oceni[person][item]
  261. return result
  262.  
  263.  
  264. if __name__ == "__main__":
  265. film = 'Catch Me If You Can'
  266. movie_base = transformoceni(oceniPoKorisnici)
  267.  
  268. for k in sorted(movie_base.keys()):
  269. if film != k:
  270. print(k)
  271. print(sim_cos(movie_base, film, k), sim_pearson(movie_base, film, k), sim_distance(movie_base, film, k))
  272. print
Add Comment
Please, Sign In to add comment