Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- """
- По изработка на задачите од претходната вежба веќе ќе имате две тренинг множества претставени во Python како речник од речници. Искористете ги за изработка на систем за препораки така што да може на секој од тест корисниците да им предложи по 3 филмови, еднаш користејќи item-based, а еднаш user-based препораки. При item-based пристапот се предлагаат фимови кои ги нема гледано корисникот кои се со позитивна сличност со некои од филмовите кои ги има гледано. На излез треба да се печатат две листи кои ги содржат само имињата на предложените филмови во растечки (азбучен) редослед. Првата листа е според user-based, а втората според item-based пристап.
- """
- critics={
- '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
- def sim_distance(oceni, person1, person2):
- 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)
- if len(zaednicki) == 0: return 0
- 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 1 / (1 + sqrt(suma))
- def sim_pearson(oceni, p1, p2):
- 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 r
- def transformPrefs(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
- 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]
- def getRecommendations(oceni, person, similarity=sim_pearson, min_zaednicki=None):
- totals = {}
- simSums = {}
- for person2 in oceni.keys():
- filmovi1 = set(oceni[person].keys())
- filmovi2 = set(oceni[person2].keys())
- zaednicki = filmovi1.intersection(filmovi2)
- # ova e ako se bara minimum zaednicki filmovi
- # za da se zemat vo predvid ocenite na drugiot korisnik
- if min_zaednicki and len(zaednicki) < min_zaednicki:
- print('So korisnikot', person2, 'imame samo', len(zaednicki), 'filmovi, pa go preskoknuvame')
- continue
- if person2 == person:
- continue
- sim = similarity(oceni, person, person2)
- if sim <= 0:
- continue
- for item in oceni[person2]:
- if item not in oceni[person] or oceni[person][item] == 0:
- # similarity * Score (Slicnost * Ocena)
- #print(item, sim, oceni[person2][item], sim* oceni[person2][item])
- totals.setdefault(item, 0)
- totals[item] += oceni[person2][item] * sim
- # Sumuma na slicnosti
- simSums.setdefault(item, 0)
- simSums[item] += sim
- rankings = [(total / simSums[item], item) for item, total in totals.items()]
- #rankings = [item for item,v in totals.items()]
- rankings.sort(reverse=True)
- a = []
- for i in rankings:
- a.append(i[1])
- a = a[:3]
- a.sort()
- return a#sorted(rankings[0:3])
- def getItemBasedRecomendations(oceni,korisnik,similarity=sim_pearson):
- rankings = []
- filmovi = oceni.keys()
- gledani = [item for item in filmovi if critics[korisnik].has_key(item)]
- negledani = [item for item in filmovi if not critics[korisnik].has_key(item)]
- #print gledani
- #print negledani
- slicnosti = {}
- for film in negledani:
- for drug in gledani:
- sim = similarity(oceni, film, drug)
- slicnosti.setdefault(film, 0);
- if slicnosti[film] < sim:
- slicnosti[film] = sim
- stvari = slicnosti.items()
- #print stvari
- stvari.sort(key=lambda tup: tup[1], reverse=True)
- novi = [item[0] for item in stvari if item[1] > 0][0:3]
- novi.sort()
- return novi
- def item_based(critics, person1, n=3):
- 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, 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)
- a = []
- for i in similarity_per_item_avg:
- a.append(i[1])
- a = a[:n]
- a.sort()
- return a #similarity_per_item_avg[:n]
- if __name__ == "__main__":
- korisnik = input()
- print "user-based: " + str(getRecommendations(critics, korisnik))
- print "item-based: " + str(item_based(critics=critics, person1=korisnik))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement