Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Задача 1 Problem 1 (1 / 3)
- По изработка на задачите од претходната вежба веќе ќе имате две тренинг множества претставени во Python како речник од речници. Искористете ги за изработка на систем за препораки така што да може на секој од тест корисниците да им предложи по 3 филмови, еднаш користејќи item-based, а еднаш user-based препораки. При item-based пристапот се предлагаат фимови кои ги нема гледано корисникот кои се со позитивна сличност со некои од филмовите кои ги има гледано. На излез треба да се печатат две листи кои ги содржат само имињата на предложените филмови во растечки (азбучен) редослед. Првата листа е според user-based, а втората според item-based пристап.
- 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}
- }
- from math import sqrt
- import json
- # Vrakja merka za slicnost bazirana na rastojanieto za person1 i person2
- def sim_distance(oceni, person1, person2):
- # Se pravi lista na zaednicki predmeti (filmovi)
- zaednicki = {}
- for item in oceni[person1].keys():
- if item in oceni[person2]:
- zaednicki[item] = 1
- # ako nemaat zaednicki rejtinzi, vrati 0
- if len(zaednicki) == 0: return 0
- # Soberi gi kvadratite na zaednickite razliki
- sum_of_squares = sum([pow(oceni[person1][item] - oceni[person2][item], 2)
- for item in oceni[person1] if item in oceni[person2]])
- return 1 / (1 + sqrt(sum_of_squares))
- # return 1/(1+(sum_of_squares))
- # 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={}
- for item in oceni[p1]:
- if item in oceni[p2]: zaednicki[item]=1
- # 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=sum([oceni[p1][it] for it in zaednicki])
- sum2=sum([oceni[p2][it] for it in zaednicki])
- # Soberi gi kvadratite od zaednickite oceni (rejtinzi) za sekoja licnost posebno
- sum1Sq=sum([pow(oceni[p1][it],2) for it in zaednicki])
- sum2Sq=sum([pow(oceni[p2][it],2) for it in zaednicki])
- # Soberi gi proizvodite od ocenite na dvete licnosti
- pSum=sum([oceni[p1][it]*oceni[p2][it] for it in zaednicki])
- # 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 r
- # Gi transformira rejtinzite taka sto klucevi ke bidat filmovite a vrednost lista od rejtinzi od sekoj korisnik
- def transformPrefs(oceni):
- result={}
- for person in oceni:
- for item in oceni[person]:
- result.setdefault(item,{})
- # Zameni gi mestata na licnosta i predmetot
- result[item][person]=oceni[person][item]
- return result
- # Gi vrakja najslicnite n korisnici na daden korisnik
- # Brojot na rezultati (n) i funkcijata za slicnost se opcionalni parametri
- def topMatches(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]
- # Gi vrakja preporakite za daden korisnik person so
- # koristenje na tezinski prosek na ocenite od drugite korisnici
- def getUserBasedRecomendations(oceni, person, similarity=sim_pearson):
- totals = {}
- simSums = {}
- for other in oceni:
- # Za da ne se sporeduva so samiot sebe
- if other == person: continue
- sim = similarity(oceni, person, other)
- # ne se zemaat vo predvid rezultati <= 0
- if sim <= 0: continue
- for item in oceni[other]:
- # za tekovniot korisnik gi zemame samo filmovite sto gi nemame veke gledano
- if item not in oceni[person] or oceni[person][item] == 0:
- # similarity * Score (Slicnost * Ocena)
- totals.setdefault(item, 0)
- totals[item] += oceni[other][item] * sim
- # Sumuma na slicnosti
- simSums.setdefault(item, 0)
- simSums[item] += sim
- # Kreiranje na normalizirana lista so rejtinzi
- rankings = [(total / simSums[item], item) for item, total in totals.items()]
- # Sortiranje na listata vo rastecki redosled
- rankings.sort()
- # Prevrtuvanje na lista za najgolemite vrednosti da bidat napred
- rankings.reverse()
- return rankings
- def getItemBasedRecomendations(critics, person1, n=None):
- oceni_po_film = transformPrefs(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, item in similar_items:
- if item in critics[person1] or similarity <= 0:
- continue
- similarity_per_item.setdefault(item, [])
- # similarity_per_item[item].append(similarity)
- similarity_per_item[item].append(similarity*my_rating)
- similarity_per_item_avg = []
- for item in similarity_per_item:
- avg_sim = 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
- def do_user_recomendation(korisnik):
- recomended_user_based = getUserBasedRecomendations(oceniPoKorisnici, korisnik)
- recomended_three = []
- minimum = len(recomended_user_based);
- if minimum > 3:
- minimum = 3
- for x in range(0, minimum):
- recomended_three.append(recomended_user_based[x][1])
- recomended_three.sort()
- print "user-based:", recomended_three
- def do_item_recomendation(korisnik):
- # print json.dumps(oceni_po_filmovi, indent=2)
- recomended_item_based = getItemBasedRecomendations(oceniPoKorisnici, korisnik)
- recomended_three = []
- minimum = len(recomended_item_based);
- if minimum > 3:
- minimum = 3
- for x in range(0, minimum):
- recomended_three.append(recomended_item_based[x][1])
- recomended_three.sort()
- print "item-based:", recomended_three
- def mean(x):
- if len(x)==0: return 0.0
- return sum(x)/len(x)
- if __name__ == "__main__":
- korisnik = input()
- # korisnik = 'Gary Coleman'
- do_user_recomendation(korisnik)
- do_item_recomendation(korisnik)
- Sample input
- 'Gary Coleman'
- Sample output
- user-based: ['Snakes on a Plane', 'Snitch', 'The Night Listener']
- item-based: ['Just My Luck', 'Snakes on a Plane', 'Snitch']
Advertisement
Add Comment
Please, Sign In to add comment