def get_normalized_scores(entries, args):
"""Generate smoothed scores based on mean, stdev of that days times. """
times_by_date = defaultdict(dict)
for e in entries:
x = e.seconds
# if x > 0:
# x = np.log(x)
times_by_date[e.date][e.userid] = x
sorted_dates = sorted(times_by_date.keys())
# failures come with a heaver ranking penalty
MAX_SCORE = 1.5
FAILURE_PENALTY = -2
def mk_score(mean, t, stdev):
if t < 0:
return FAILURE_PENALTY
if stdev == 0:
return 0
score = (mean - t) / stdev
return np.clip(score, -MAX_SCORE, MAX_SCORE)
# scores are the stdev away from mean of that day
scores = {}
for date, user_times in times_by_date.items():
times = [t for t in user_times.values() if t is not None]
# make failures 1 minute worse than the worst time
times = [t if t >= 0 else max(times) + 60 for t in times]
q1, q3 = np.percentile(times, [25,75])
stdev = statistics.pstdev(times)
o1, o3 = q1 - stdev, q3 + stdev
times = [t for t in times if o1 <= t <= o3]
mean = statistics.mean(times)
stdev = statistics.pstdev(times, mean)
scores[date] = {
userid: mk_score(mean, t, stdev)
for userid, t in user_times.items()
if t is not None
}
new_score_weight = 1 - args.smooth
running = defaultdict(list)
weighted_scores = defaultdict(dict)
for date in sorted_dates:
for user, score in scores[date].items():
old_score = running.get(user)
new_score = score * new_score_weight + old_score * (1 - new_score_weight) \
if old_score is not None else score
weighted_scores[user][date] = running[user] = new_score
ticker = matplotlib.ticker.MultipleLocator(base=0.25)
formatter = matplotlib.ticker.ScalarFormatter(useOffset=False)
return weighted_scores, ticker, formatter
评论列表
文章目录