def get_ranks(self, times): ### If we don't have reputations yet, we return empty array. We start with empty dictionary if there are no reputations. if self.all_reputations == {}: result = {} else: ### If there were previous reputations, we look if date we are looking for has reputations. If so, we save them ### in result object. if times['date'] in list(self.all_reputations.keys()): result = dict(self.all_reputations[times['date']]) else: ### If there are no reputations for that date, we work with empty dictionary. result = {} all_results = [] ### In the end we only round up the ranks when we return them. for k in result.keys(): all_results.append({'id': k, 'rank': my_round(result[k] * 100, 0)}) #logging.debug("network get ranks: ",str(all_results)) logging.info("network get ranks: {0}".format(all_results)) ### Now, if we have spending, we only return those that are sellers; #if self.spendings>0: # my_results = dict() # for k in all_results.keys(): # if k in self.sellers: # my_results[k] = all_results[k] # all_results=my_results return (0, all_results)
def get_ranks_dict(self, times): if self.all_reputations == {}: result = {} else: if times['date'] in list(self.all_reputations.keys()): result = dict(self.all_reputations[times['date']]) else: result = {} for k in result.keys(): result[k] = my_round(result[k] * 100, 0) ### Everything is similar to get_ranks, but we only return result, not really 0 beside result. #logging.debug("network get ranks: " , str(result)) logging.info("network get ranks: {0}".format(result)) return (result)
def update_ranks(self, mydate): if not "rater_ranks_special" in dir(self): self.rater_ranks_special = dict() self.non_rounded_rep = dict() text = "period " + str(self.update_period) logging.debug(text) ### And then we iterate through functions. First we prepare arrays and basic computations. since = mydate - timedelta(days=self.update_period) if self.rating_bias: if 'rater_biases' in dir(self): pass else: self.rater_biases = dict() self.rater_biases[since] = dict() if self.predictiveness > 0: if 'predictive_data' in dir(self): pass else: self.predictive_data = dict() self.pred_values = dict() self.count_values = dict() self.current_ratings = [] ### Sellect data which we will use. self.select_data(mydate) i = 0 problem = False while i < len(self.current_ratings): ### If we do not have values, then we have a problem. Even if only one rating is missing, ### there is a problem. if (self.use_ratings == True and (not 'value' in self.current_ratings[i].keys())): problem = True i += 1 if problem: ### Well, if we have a problem, we just set ratings to false. Code will still work. logging.warning( "Ratings is set to True, but no ratings were given. Changing the setting to False" ) self.use_ratings = False problem = False ### if we have some ratings, we can check; if len(self.current_ratings) > 0: ### If we have payments and downratings to true, there is a small error. if (self.current_ratings[0]['type'] == "payment" and self.downrating == True): ### raising error message. warnings.warn( "if we only have payments, we have no ratings. Therefore downratings cannot be True. Setting them to False" ) self.downrating = False ### we set up arrays; this is the set of data where we have ratings, values, weights ### in predictable way, so we can iterate them later on. if self.rating_bias: if 'average_ratings' in dir(self): pass else: self.average_ratings = dict() self.rater_biases[mydate] = dict() array1, dates_array, to_array, rater_biases1, avgs = reputation_calc_p1( self.current_ratings, self.conservatism, self.precision, self.temporal_aggregation, False, self.logratings, self.downrating, self.weighting, self.rater_biases[since], self.average_ratings) self.average_ratings[mydate] = avgs self.rater_biases[mydate] = dict(rater_biases1) else: array1, dates_array, to_array, rater_biases1 = reputation_calc_p1( self.current_ratings, self.conservatism, self.precision, self.temporal_aggregation, False, self.logratings, self.downrating, self.weighting, None) ### In this case, we don't need rater_biases ### Now we update the reputation. Here, old ranings are inseter and then new ones are calculated as output. self.reputation = update_reputation(self.reputation, array1, self.default, self.spendings) ### If we have spendings-based reputation, we go in the loop below. if self.spendings > 0: spendings_dict = spending_based(array1, dict(), self.logratings, self.precision, self.weighting) ### We normalize differential that is spendings-based. spendings_dict = normalized_differential( spendings_dict, normalizedRanks=self.fullnorm, our_default=self.default, spendings=self.spendings, log=self.logranks) ### Then we calculate differential the normal way. if self.predictiveness > 0: new_reputation, self.rater_ranks_special = calculate_new_reputation( logging=logging, new_array=array1, to_array=to_array, reputation=self.reputation, rating=self.use_ratings, precision=self.precision, previous_rep=self.rater_ranks_special, default=self.default, unrated=self.unrated, normalizedRanks=self.fullnorm, weighting=self.weighting, denomination=self.denomination, liquid=self.liquid, logratings=self.logratings, logranks=self.logranks, predictiveness=self.predictiveness, predictive_data=self.pred_values) else: new_reputation, self.rater_ranks_special = calculate_new_reputation( logging=logging, new_array=array1, to_array=to_array, reputation=self.reputation, rating=self.use_ratings, precision=self.precision, previous_rep=self.rater_ranks_special, default=self.default, unrated=self.unrated, normalizedRanks=self.fullnorm, weighting=self.weighting, denomination=self.denomination, liquid=self.liquid, logratings=self.logratings, logranks=self.logranks, predictiveness=self.predictiveness) ### And then we normalize the differential: new_reputation = normalized_differential(new_reputation, normalizedRanks=self.fullnorm, our_default=self.default, spendings=self.spendings, log=False) text = "Normalized differential: " + str(new_reputation) logging.debug(text) ### Again only starting this loop if we have spendings. ### we take data from date-update_period. ### For spendings-based system. We store all agents' reputations and then we only show reputations of ### sellers when get_ranks() is called. This is not in line with Java implementation, which only returns ### sellers. To circumvent that, we make an object in which we store only sellers and we then return only sellers. ### We still need all ranks, so they are still stored in self.all_reputations if "sellers" in dir(self): pass else: self.sellers = [] for k in new_reputation.keys(): if k not in self.sellers: self.sellers.append(k) if (self.spendings > 0 and self.predictiveness == 0): updated_differential = dict() unique_keys = list(new_reputation.keys()) ### each 'from' is added to unique_keys list. We add it to what is already in differential. for k in spendings_dict.keys(): if not k in unique_keys: unique_keys.append(k) for k in unique_keys: ### Then we have different cases of what happens depending on where we have a certain key. if (k in new_reputation.keys()) and (k in spendings_dict.keys()): ### Note, everything is already nomalized. The rest are just the equations to make sure everything is correct. updated_differential[k] = ( self.ratings_param * new_reputation[k] + self.spendings * spendings_dict[k]) / ( self.spendings + self.ratings_param) if (k in new_reputation.keys()) and ( k not in spendings_dict.keys()): updated_differential[k] = ( self.ratings_param * new_reputation[k]) / ( self.spendings + self.ratings_param) if (k not in new_reputation.keys()) and ( k in spendings_dict.keys()): updated_differential[k] = ( self.spendings * spendings_dict[k]) / ( self.spendings + self.ratings_param) ### Differential is then from both spendings and usual differential. new_reputation = updated_differential # THen we blend the reputation with differential. self.reputation = update_reputation_approach_d(self.first_occurance, self.reputation, new_reputation, since, self.date, self.decayed, self.conservatism) ### Apply normalizedRanks=True AKA "full normalization" to prevent negative ratings on "downrating" ### See line 360 in https://github.com/aigents/aigents-java/blob/master/src/main/java/net/webstructor/peer/Reputationer.java ### and line 94 in https://github.com/aigents/aigents-java/blob/master/src/main/java/net/webstructor/data/Summator.java ### Downratings seem to pass, so I assume this comment is resolved. text = "Blended differential with reputation: " + str(self.reputation) logging.debug(text) self.reputation = normalize_reputation(self.reputation, array1, self.unrated, self.default, self.decayed, self.conservatism, self.downrating) self.non_rounded_rep = dict(self.reputation) ### round reputations: for k in self.reputation.keys(): self.reputation[k] = my_round(self.reputation[k], 2) # Make sure we use my_round. ### This might be changed in the future, but now rounding is done in order to be the same as in Java rs. ## We have all_reputations dictionary where we have all history of reputations with dates as keys. text = "Normalized reputation: " + str(self.reputation) logging.debug(text) self.all_reputations[mydate] = dict(self.reputation) if self.predictiveness > 0: avg_ind_rat_byperiod, self.count_values[ mydate] = calculate_average_individual_rating_by_period( array1, True) text = "Average individual rating by period: " + str( avg_ind_rat_byperiod) logging.debug(text) #self.predictive_data, ids = update_predictiveness_data(self.predictive_data,mydate,self.reputation,avg_ind_rat_byperiod,self.conservatism) self.predictive_data, ids = update_predictiveness_data( self.predictive_data, mydate, self.reputation, avg_ind_rat_byperiod, self.conservatism) self.calculate_indrating(ids, mydate) text = "Individual rating: " + str( self.predictive_data ) + ", and rating used for rater reputation: " + str( self.pred_values) logging.debug(text) return (0)