def combine_player_info(player_id, dbsession=DBSESSION): """ Get player's name, club, recent scores, upcoming fixtures, and upcoming predictions if available """ info_dict = {"player_id": player_id} p = get_player(player_id, dbsession=dbsession) info_dict["player_name"] = p.name team = p.team(CURRENT_SEASON, NEXT_GAMEWEEK) info_dict["team"] = team # get recent scores for the player rs = get_recent_scores_for_player(p, dbsession=dbsession) recent_scores = [{"gameweek": k, "score": v} for k, v in rs.items()] info_dict["recent_scores"] = recent_scores # get upcoming fixtures fixtures = get_fixtures_for_player(p, dbsession=dbsession)[:3] info_dict["fixtures"] = [] for f in fixtures: home_or_away = "home" if f.home_team == team else "away" opponent = f.away_team if home_or_away == "home" else f.home_team info_dict["fixtures"].append({ "gameweek": f.gameweek, "opponent": opponent, "home_or_away": home_or_away }) try: tag = get_latest_prediction_tag(dbsession=dbsession) predicted_points = get_predicted_points_for_player(p, tag, dbsession=dbsession) info_dict["predictions"] = predicted_points except (RuntimeError): pass return info_dict
def calc_predicted_points_for_player( player, team_model, df_player, df_bonus, df_saves, df_cards, season, gw_range=None, fixtures_behind=3, tag="", dbsession=session, ): """ Use the team-level model to get the probs of scoring or conceding N goals, and player-level model to get the chance of player scoring or assisting given that their team scores. """ message = "Points prediction for player {}".format(player.name) if not gw_range: # by default, go for next three matches gw_range = list( range(NEXT_GAMEWEEK, min(NEXT_GAMEWEEK + 3, 38)) ) # don't go beyond gw 38! team = player.team( season, gw_range[0] ) # assume player stays with same team from first gameweek in range position = player.position(season) fixtures = get_fixtures_for_player( player, season, gw_range=gw_range, dbsession=dbsession ) # use same recent_minutes from previous gameweeks for all predictions recent_minutes = get_recent_minutes_for_player( player, num_match_to_use=fixtures_behind, season=season, last_gw=min(gw_range) - 1, dbsession=dbsession, ) if len(recent_minutes) == 0: # e.g. for gameweek 1 # this should now be dealt with in get_recent_minutes_for_player, so # throw error if not. # recent_minutes = estimate_minutes_from_prev_season( # player, season=season, dbsession=session # ) raise ValueError("Recent minutes is empty.") expected_points = defaultdict(float) # default value is 0. predictions = [] # list that will hold PlayerPrediction objects for fixture in fixtures: gameweek = fixture.gameweek is_home = fixture.home_team == team opponent = fixture.away_team if is_home else fixture.home_team home_or_away = "at home" if is_home else "away" message += "\ngameweek: {} vs {} {}".format(gameweek, opponent, home_or_away) points = 0.0 expected_points[gameweek] = points if sum(recent_minutes) == 0: # 'recent_minutes' contains the number of minutes that player played # for in the past few matches. If these are all zero, we will for sure # predict zero points for this player, so we don't need to call all the # functions to calculate appearance points, defending points, attacking points. points = 0.0 elif is_injured_or_suspended(player.fpl_api_id, gameweek, season, dbsession): # Points for fixture will be zero if suspended or injured points = 0.0 else: # now loop over recent minutes and average points = 0 for mins in recent_minutes: points += ( get_appearance_points(mins) + get_attacking_points( player.player_id, position, team, opponent, is_home, mins, team_model, df_player, ) + get_defending_points( position, team, opponent, is_home, mins, team_model ) ) if df_bonus is not None: points += get_bonus_points(player.player_id, mins, df_bonus) if df_cards is not None: points += get_card_points(player.player_id, mins, df_cards) if df_saves is not None: points += get_save_points( position, player.player_id, mins, df_saves ) points = points / len(recent_minutes) # create the PlayerPrediction for this player+fixture predictions.append(make_prediction(player, fixture, points, tag)) expected_points[gameweek] += points # and return the per-gameweek predictions as a dict message += "\nExpected points: {:.2f}".format(points) print(message) return predictions