Advertisement
TDimovska

[СНЗ] Табела на слични корисници

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