Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Системи за препораки
- Да испрограмира функција за косинусна сличност која е дефинирана со следнава формула, каде A е листа со
- оцените на едниот корисник или филм, а B е листа со оцените на другиот корисник или филм:
- enter image description here
- http://code.finki.ukim.mk/public/uploads/1453390764510.png
- 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))
- Притоа треба да се избегне делење со нула и во тој случај да се смета дека сличноста е -1.
- Речник со оцени на корисници по филмови треба е веќе даден. Од стандардниот влез се вчитува име на еден
- филм. Да се испечати сличноста на прочитаниот филм со секој друг филм (освен самиот со себе) така што ќе
- се печати:
- Филм 2
- Косинусна сличност, Пеарсонова сличност, Евклидова сличност
- Празна линија
- При печатењето филмовите треба да бидат подредени по азбучен редослед. Сите сличности треба да бидат
- заокружени на 2 децимали.
- Vlez:
- 'Catch Me If You Can'
- IZlez:
- Just My Luck
- 1.0 0 0.4
- Lady in the Water
- 0.98 0.89 0.39
- Snakes on a Plane
- 0.99 0.96 0.54
- Snitch
- 1.0 0.99 0.67
- Superman Returns
- 1.0 0.96 0.45
- The Night Listener
- 0.92 -0.73 0.26
- You, Me and Dupree
- 0.97 0.69 0.39
- from math import sqrt
- oceniPoKorisnici = {
- 'Lisa Rose': {'Catch Me If You Can': 3.0, 'Snakes on a Plane': 3.5, 'Superman Returns': 3.5,
- 'You, Me and Dupree': 2.5, 'The Night Listener': 3.0, 'Snitch': 3.0},
- 'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5, 'Just My Luck': 1.5, 'The Night Listener': 3.0,
- 'You, Me and Dupree': 3.5},
- 'Michael Phillips': {'Catch Me If You Can': 2.5, 'Lady in the Water': 2.5, 'Superman Returns': 3.5,
- 'The Night Listener': 4.0, 'Snitch': 2.0},
- 'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0, 'The Night Listener': 4.5, 'Superman Returns': 4.0,
- 'You, Me and Dupree': 2.5},
- 'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 'Just My Luck': 2.0, 'Superman Returns': 3.0,
- 'You, Me and Dupree': 2.0},
- 'Jack Matthews': {'Catch Me If You Can': 4.5, 'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,
- 'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5, 'Snitch': 4.5},
- 'Toby': {'Snakes on a Plane': 4.5, 'Snitch': 5.0},
- 'Michelle Nichols': {'Just My Luck': 1.0, 'The Night Listener': 4.5, 'You, Me and Dupree': 3.5,
- 'Catch Me If You Can': 2.5, 'Snakes on a Plane': 3.0},
- 'Gary Coleman': {'Lady in the Water': 1.0, 'Catch Me If You Can': 1.5, 'Superman Returns': 1.5,
- 'You, Me and Dupree': 2.0},
- 'Larry': {'Lady in the Water': 3.0, 'Just My Luck': 3.5, 'Snitch': 1.5, 'The Night Listener': 3.5}
- }
- def sim_distance(oceni, person1, person2):
- # Se pravi lista na zaednicki predmeti (filmovi)
- filmovi1=set(oceni[person1].keys())
- filmovi2=set(oceni[person2].keys())
- zaednicki = filmovi1.intersection(filmovi2)
- # print(filmovi1)
- # print(filmovi2)
- # print(zaednicki)
- # for item in oceni[person1].keys():
- # if item in oceni[person2]:
- # zaednicki.add(item)
- # # ako nemaat zaednicki rejtinzi, vrati 0
- if len(zaednicki) == 0: return 0
- # # Soberi gi kvadratite na zaednickite razliki
- suma = 0.0
- for item in zaednicki:
- ocena1 = oceni[person1][item]
- ocena2 = oceni[person2][item]
- suma += (ocena1 - ocena2) ** 2
- # print(item, person1, ocena1, person2, ocena2)
- return round(1 / (1 + sqrt(suma)),2)
- # In[12]:
- # Go vrakja koeficientot na Pearsonova korelacija pomegu p1 i p2 (licnost 1 i licnost 2)
- # Vrednostite se pomegu -1 i 1
- def sim_pearson(oceni, p1, p2):
- # Se kreira recnik vo koj ke se cuvaat predmetite (filmovi) koi se oceneti od dvajcata
- # Vo recnikot ni se vazni samo klucevite za da gi cuvame iminjata na filmovite koi se zaednicki, a vrednostite ne ni se vazni
- zaednicki = set()
- for item in oceni[p1]:
- if item in oceni[p2]:
- zaednicki.add(item)
- # Se presmetuva brojot na predmeti oceneti od dvajcata
- n = len(zaednicki)
- # Ako nemaat zaednicki predmeti vrati korelacija 0
- if n == 0: return 0
- # Soberi gi zaednickite oceni (rejtinzi) za sekoja licnost posebno
- sum1 = 0
- sum2 = 0
- # Soberi gi kvadratite od zaednickite oceni (rejtinzi) za sekoja licnost posebno
- sum1Sq = 0
- sum2Sq = 0
- # Soberi gi proizvodite od ocenite na dvete licnosti
- pSum = 0
- for item in zaednicki:
- ocena1 = oceni[p1][item]
- ocena2 = oceni[p2][item]
- sum1 += ocena1
- sum1Sq += ocena1 ** 2
- sum2 += ocena2
- sum2Sq += ocena2 ** 2
- pSum += ocena1 * ocena2
- # Presmetaj go koeficientot na korelacija
- 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 round(r,2)
- def topMatches_inline(oceni, person, n=5, similarity=sim_pearson):
- scores = [(similarity(oceni, person, other), other)
- for other in oceni if other != person]
- # Se sortira listata vo rastecki redosled
- scores.sort()
- # Se prevrtuva za najslicnite (so najgolema vrednost) da bidat prvi
- scores.reverse()
- return scores[0:n]
- def topMatches(oceni, person, n=5, similarity=sim_pearson):
- scores = []
- for person2 in oceni.keys():
- if person != person2:
- s = similarity(oceni, person, person2)
- scores.append((s, person2))
- # Se sortira listata vo rastecki redosled
- scores.sort()
- # Se prevrtuva za najslicnite (so najgolema vrednost) da bidat prvi
- scores.reverse()
- if n is None:
- return scores
- else:
- return scores[0:n]
- # In[52]:
- def transformoceni(oceni):
- result = {}
- for person in oceni.keys():
- for item in oceni[person]:
- result.setdefault(item, {})
- # Zameni gi mestata na licnosta i predmetot
- result[item][person] = oceni[person][item]
- return result
- # In[77]:
- def item_based(critics, person1, n=3):
- oceni_po_film = transformoceni(critics)
- similarity_per_item = {}
- for item in critics[person1].keys():
- similar_items = topMatches(oceni_po_film, item, n=None)
- my_rating = critics[person1][item]
- for similarity, item2 in similar_items:
- if item2 in critics[person1] or similarity <= 0:
- # print('Slicnost', similarity, 'na', item,'so', item2)
- continue
- weight= similarity * my_rating
- # print('Slicnost', similarity, 'na', item,'so', item2, weight)
- similarity_per_item.setdefault(item2, [])
- similarity_per_item[item2].append(weight)
- # print(item, my_rating, list(similarity_per_item.items()))
- similarity_per_item_avg = []
- import numpy as np
- for item in similarity_per_item:
- print(item, similarity_per_item[item])
- avg_sim = np.mean(similarity_per_item[item])
- similarity_per_item_avg.append((avg_sim, item))
- similarity_per_item_avg.sort(reverse=True)
- return similarity_per_item_avg[:n]
- def sim_cos(oceni, p1, p2):
- zaednicki = set()
- for item in oceni[p1]:
- if item in oceni[p2]:
- zaednicki.add(item)
- n = len(zaednicki)
- if n == 0: return 0
- sum1 = 0
- sum2 = 0
- sum1Sq = 0
- sum2Sq = 0
- pSum = 0
- for item in zaednicki:
- ocena1 = oceni[p1][item]
- ocena2 = oceni[p2][item]
- sum1 += ocena1
- sum1Sq += ocena1 ** 2
- sum2 += ocena2
- sum2Sq += ocena2 ** 2
- pSum += ocena1 * ocena2
- num = pSum
- den = sqrt(sum1Sq) * sqrt(sum2Sq)
- if den == 0: return -1
- r = num / den
- return round(r, 2)
- def transformoceni(oceni):
- result = {}
- for person in oceni.keys():
- for item in oceni[person]:
- result.setdefault(item, {})
- # Zameni gi mestata na licnosta i predmetot
- result[item][person] = oceni[person][item]
- return result
- if __name__ == "__main__":
- film = 'Catch Me If You Can'
- movie_base = transformoceni(oceniPoKorisnici)
- for k in sorted(movie_base.keys()):
- if film != k:
- print(k)
- print(sim_cos(movie_base, film, k), sim_pearson(movie_base, film, k), sim_distance(movie_base, film, k))
- print
Add Comment
Please, Sign In to add comment