Beispiel #1
0
def get_player_list(team, pos):
    """
    Return a list of all players in that team and/or position
    """
    player_list = [{"id": p.player_id, "name": p.name} \
        for p in list_players(position=pos,team=team)]
    return create_response(player_list)
def fit_save_points(
    gameweek=NEXT_GAMEWEEK,
    season=CURRENT_SEASON,
    min_matches=10,
    min_minutes=90,
    dbsession=session,
):
    """Calculate the average save points scored by each goalkeeper for matches they
    played at least min_minutes in.
    Mean is calculated as sum of all save points divided by either the number of
    matches the player has played in or min_matches, whichever is greater.

    Returns pandas series index by player ID, values average save points.
    """
    df = get_player_scores(
        season, gameweek, min_minutes=min_minutes, dbsession=dbsession
    )

    goalkeepers = list_players(
        position="GK", gameweek=gameweek, season=season, dbsession=dbsession
    )
    goalkeepers = [gk.player_id for gk in goalkeepers]
    df = df[df["player_id"].isin(goalkeepers)]

    #  1pt per 3 saves
    df["save_pts"] = (df["saves"] / saves_for_point).astype(int)

    return mean_group_min_count(df, "player_id", "save_pts", min_count=min_matches)
Beispiel #3
0
def list_players_teams_prices(position="all", team="all", dbsession=DBSESSION):
    """
    Return a list of players, each with their current team and price
    """
    return [
        "{} ({}): {}".format(p.name, p.team(CURRENT_SEASON),
                             p.current_price(CURRENT_SEASON)) for p in
        list_players(position=position, team=team, dbsession=dbsession)
    ]
Beispiel #4
0
def calc_predicted_points_for_pos(pos, gw_range, team_model, player_model,
                                  season, tag, session):
    """
    Calculate points predictions for all players in a given position and
    put into the DB
    """
    predictions = {}
    df_player = None
    if pos != "GK":  # don't calculate attacking points for keepers.
        df_player = get_fitted_player_model(player_model, pos, season, session)
    for player in list_players(position=pos, dbsession=session):
        predictions[player.player_id] = calc_predicted_points(
            player, team_model, df_player, season, tag, session, gw_range)

    return predictions
Beispiel #5
0
def list_players_teams_prices(position="all",
                              team="all",
                              dbsession=DBSESSION,
                              gameweek=NEXT_GAMEWEEK):
    """
    Return a list of players, each with their current team and price
    """
    return [
        "{} ({}): {}".format(
            p.name,
            p.team(CURRENT_SEASON, NEXT_GAMEWEEK),
            p.price(CURRENT_SEASON, NEXT_GAMEWEEK),
        ) for p in list_players(position=position,
                                team=team,
                                dbsession=dbsession,
                                gameweek=gameweek)
    ]
Beispiel #6
0
def update_players(season, dbsession):
    """
    See if any new players have been added to FPL since we last filled the 'player'
    table in the db.  If so, add them.
    """
    players_from_db = list_players(
        position="all", team="all", season=season, dbsession=dbsession
    )
    player_data_from_api = fetcher.get_player_summary_data()
    players_from_api = list(player_data_from_api.keys())

    if len(players_from_db) == len(players_from_api):
        print("Player table already up-to-date.")
        return 0
    elif len(players_from_db) > len(players_from_api):
        raise RuntimeError(
            "Something strange has happened - more players in DB than API"
        )
    else:
        print("Updating player table...")
        # find the new player(s) from the API
        api_ids_from_db = [p.fpl_api_id for p in players_from_db]
        new_players = [p for p in players_from_api if p not in api_ids_from_db]
        for player_api_id in new_players:
            first_name = player_data_from_api[player_api_id]["first_name"]
            second_name = player_data_from_api[player_api_id]["second_name"]
            name = "{} {}".format(first_name, second_name)
            # check whether we alreeady have this player in the database -
            # if yes update that player's data, if no create a new player
            p = get_player(name, dbsession=dbsession)
            if p is None:
                print("Adding player {}".format(name))
                p = Player()
                update = False
            elif p.fpl_api_id is None:
                print("Updating player {}".format(name))
                update = True
            else:
                update = True
            p.fpl_api_id = player_api_id
            p.name = name
            if not update:
                dbsession.add(p)
        dbsession.commit()
        return len(new_players)
    def _get_player_list(self):
        """Get list of active players at the start of the gameweek range,
        and the id range of players for each position.
        """
        players = []
        change_idx = [0]
        # build players list by position (i.e. all GK, then all DEF etc.)
        for pos in self.positions:
            players += list_players(
                position=pos, season=self.season, gameweek=self.start_gw
            )
            change_idx.append(len(players))

        # min and max idx of players for each position
        position_idx = {
            self.positions[i - 1]: (change_idx[i - 1], change_idx[i] - 1)
            for i in range(1, len(change_idx))
        }
        return players, position_idx
Beispiel #8
0
def update_players(season, dbsession):
    """
    See if any new players have been added to FPL since we last filled the 'player'
    table in the db.  If so, add them.
    """
    players_from_db = list_players(position="all",
                                   team="all",
                                   season=season,
                                   dbsession=dbsession)
    player_data_from_api = fetcher.get_player_summary_data()
    players_from_api = list(player_data_from_api.keys())

    if len(players_from_db) == len(players_from_api):
        print("Player table already up-to-date.")
        return 0
    elif len(players_from_db) > len(players_from_api):
        raise RuntimeError(
            "Something strange has happened - more players in DB than API")
    else:
        return add_players_to_db(players_from_db, players_from_api,
                                 player_data_from_api, dbsession)
def calc_predicted_points_for_pos(
    pos,
    team_model,
    player_model,
    df_bonus,
    df_saves,
    df_cards,
    season,
    gw_range,
    tag,
    dbsession=session,
):
    """
    Calculate points predictions for all players in a given position and
    put into the DB
    """
    predictions = {}
    df_player = None
    if pos != "GK":  # don't calculate attacking points for keepers.
        df_player = get_fitted_player_model(
            player_model, pos, season, min(gw_range), dbsession
        )
    for player in list_players(
        position=pos, season=season, gameweek=min(gw_range), dbsession=dbsession
    ):
        predictions[player.player_id] = calc_predicted_points_for_player(
            player=player,
            team_model=team_model,
            df_player=df_player,
            df_bonus=df_bonus,
            df_saves=df_saves,
            df_cards=df_cards,
            season=season,
            gw_range=gw_range,
            tag=tag,
            dbsession=dbsession,
        )

    return predictions
def calc_predicted_points_for_pos(
        pos,
        fixture_goal_probs,
        df_bonus,
        df_saves,
        df_cards,
        season,
        gw_range,
        tag,
        model=ConjugatePlayerModel(),
        dbsession=session,
):
    """
    Calculate points predictions for all players in a given position and
    put into the DB
    """
    df_player = None
    if pos != "GK":  # don't calculate attacking points for keepers.
        df_player = fit_player_data(pos, season, min(gw_range), model,
                                    dbsession)
    return {
        player.player_id: calc_predicted_points_for_player(
            player=player,
            fixture_goal_probs=fixture_goal_probs,
            df_player=df_player,
            df_bonus=df_bonus,
            df_saves=df_saves,
            df_cards=df_cards,
            season=season,
            gw_range=gw_range,
            tag=tag,
            dbsession=dbsession,
        )
        for player in list_players(position=pos,
                                   season=season,
                                   gameweek=min(gw_range),
                                   dbsession=dbsession)
    }
def get_player_history_table(position="all"):
    """
    Query the player_score table.
    """
    with open("player_history_{}.csv".format(position), "w") as output_file:
        output_file.write(
            "player_id,player_name,match_id,goals,assists,minutes,team_goals\n"
        )
        player_ids = list_players(position)
        for pid in player_ids:
            player_name = get_player_name(pid)
            results = session.query(PlayerScore).filter_by(player_id=pid).all()
            row_count = 0
            for row in results:
                minutes = row.minutes
                match_id = row.match_id
                goals = row.goals
                assists = row.assists
                # find the match, in order to get team goals
                Match = None  # TODO: Placeholder for missing (deprecated?) Match class
                match = session.query(Match).filter_by(
                    match_id=row.match_id).first()
                if match.home_team == row.opponent:
                    team_goals = match.away_score
                elif match.away_team == row.opponent:
                    team_goals = match.home_score
                else:
                    print("Unknown opponent!")
                    team_goals = -1
                output_file.write("{},{},{},{},{},{},{}\n".format(
                    pid, player_name, match_id, goals, assists, minutes,
                    team_goals))
                row_count += 1
            if row_count < 38 * 3:
                for _ in range(row_count, 38 * 3):
                    output_file.write("{},{},0,0,0,0,0\n".format(
                        pid, player_name))
def calc_all_predicted_points(
    gw_range,
    season,
    include_bonus=True,
    include_cards=True,
    include_saves=True,
    num_thread=4,
    tag="",
    dbsession=None,
):
    """
    Do the full prediction for players.
    """
    model_team = get_fitted_team_model(season,
                                       gameweek=min(gw_range),
                                       dbsession=dbsession)
    model_file = pkg_resources.resource_filename(
        "airsenal", "stan_model/player_forecasts.pkl")
    print("Loading pre-compiled player model from {}".format(model_file))
    with open(model_file, "rb") as f:
        model_player = pickle.load(f)

    df_player = get_all_fitted_player_models(model_player, season, gw_range[0])

    if include_bonus:
        df_bonus = fit_bonus_points(gameweek=gw_range[0], season=season)
    else:
        df_bonus = None
    if include_saves:
        df_saves = fit_save_points(gameweek=gw_range[0], season=season)
    else:
        df_saves = None
    if include_cards:
        df_cards = fit_card_points(gameweek=gw_range[0], season=season)
    else:
        df_cards = None

    players = list_players(season=season,
                           gameweek=gw_range[0],
                           dbsession=dbsession)

    if num_thread is not None and num_thread > 1:
        queue = Queue()
        procs = []
        for _ in range(num_thread):
            processor = Process(
                target=allocate_predictions,
                args=(
                    queue,
                    gw_range,
                    model_team,
                    df_player,
                    df_bonus,
                    df_saves,
                    df_cards,
                    season,
                    tag,
                    dbsession,
                ),
            )
            processor.daemon = True
            processor.start()
            procs.append(processor)

        for p in players:
            queue.put(p.player_id)
        for _ in range(num_thread):
            queue.put("DONE")

        for _, p in enumerate(procs):
            p.join()
    else:
        # single threaded
        for player in players:
            predictions = calc_predicted_points_for_player(
                player,
                model_team,
                df_player,
                df_bonus,
                df_saves,
                df_cards,
                season,
                gw_range=gw_range,
                tag=tag,
                dbsession=dbsession,
            )
            for p in predictions:
                dbsession.add(p)
        dbsession.commit()
        print("Finished adding predictions to db")
Beispiel #13
0
def list_players_for_api(team, position, dbsession=DBSESSION):
    """
    List players.  Just pass on to utils.list_players but
    specify the dbsession.
    """
    return list_players(team=team, position=position, dbsession=dbsession)
def calc_all_predicted_points(
        gw_range,
        season,
        include_bonus=True,
        include_cards=True,
        include_saves=True,
        num_thread=4,
        tag="",
        player_model=ConjugatePlayerModel(),
        dbsession=None,
):
    """
    Do the full prediction for players.
    """
    model_team = get_fitted_team_model(season,
                                       gameweek=min(gw_range),
                                       dbsession=dbsession)
    print("Calculating fixture score probabilities...")
    fixtures = get_fixtures_for_gameweek(gw_range,
                                         season=season,
                                         dbsession=dbsession)
    fixture_goal_probs = get_goal_probabilities_for_fixtures(
        fixtures, model_team, max_goals=MAX_GOALS)

    df_player = get_all_fitted_player_data(season,
                                           gw_range[0],
                                           model=player_model,
                                           dbsession=dbsession)

    if include_bonus:
        df_bonus = fit_bonus_points(gameweek=gw_range[0], season=season)
    else:
        df_bonus = None
    if include_saves:
        df_saves = fit_save_points(gameweek=gw_range[0], season=season)
    else:
        df_saves = None
    if include_cards:
        df_cards = fit_card_points(gameweek=gw_range[0], season=season)
    else:
        df_cards = None

    players = list_players(season=season,
                           gameweek=gw_range[0],
                           dbsession=dbsession)

    if num_thread is not None and num_thread > 1:
        queue = Queue()
        procs = []
        for _ in range(num_thread):
            processor = Process(
                target=allocate_predictions,
                args=(
                    queue,
                    gw_range,
                    fixture_goal_probs,
                    df_player,
                    df_bonus,
                    df_saves,
                    df_cards,
                    season,
                    tag,
                    dbsession,
                ),
            )
            processor.daemon = True
            processor.start()
            procs.append(processor)

        for p in players:
            queue.put(p.player_id)
        for _ in range(num_thread):
            queue.put("DONE")

        for _, p in enumerate(procs):
            p.join()
    else:
        # single threaded
        for player in players:
            predictions = calc_predicted_points_for_player(
                player,
                fixture_goal_probs,
                df_player,
                df_bonus,
                df_saves,
                df_cards,
                season,
                gw_range=gw_range,
                tag=tag,
                dbsession=dbsession,
            )
            for p in predictions:
                dbsession.add(p)
        dbsession.commit()
        print("Finished adding predictions to db")
Beispiel #15
0
def get_player_history_df(
    position="all", season=CURRENT_SEASON, gameweek=NEXT_GAMEWEEK, dbsession=session
):
    """
    Query the player_score table to get goals/assists/minutes, and then
    get the team_goals from the match table.
    The 'season' argument defined the set of players that will be considered, but
    for those players, all results will be used.
    """

    col_names = [
        "player_id",
        "player_name",
        "match_id",
        "date",
        "goals",
        "assists",
        "minutes",
        "team_goals",
    ]
    player_data = []
    players = list_players(
        position=position, season=season, gameweek=gameweek, dbsession=dbsession
    )
    max_matches_per_player = get_max_matches_per_player(
        position, season=season, gameweek=gameweek, dbsession=dbsession
    )
    for counter, player in enumerate(players):
        print(
            "Filling history dataframe for {}: {}/{} done".format(
                player.name, counter, len(players)
            )
        )
        results = player.scores
        row_count = 0
        for row in results:
            if is_future_gameweek(
                row.fixture.season,
                row.fixture.gameweek,
                current_season=season,
                next_gameweek=gameweek,
            ):
                continue

            match_id = row.result_id
            if not match_id:
                print(
                    " Couldn't find result for {} {} {}".format(
                        row.fixture.home_team, row.fixture.away_team, row.fixture.date
                    )
                )
                continue
            minutes = row.minutes
            opponent = row.opponent
            goals = row.goals
            assists = row.assists
            # find the match, in order to get team goals
            match_result = row.result
            match_date = row.fixture.date
            if row.fixture.home_team == row.opponent:
                team_goals = match_result.away_score
            elif row.fixture.away_team == row.opponent:
                team_goals = match_result.home_score
            else:
                print("Unknown opponent!")
                team_goals = -1
            player_data.append(
                [
                    player.player_id,
                    player.name,
                    match_id,
                    match_date,
                    goals,
                    assists,
                    minutes,
                    team_goals,
                ]
            )
            row_count += 1

        ## fill blank rows so they are all the same size
        if row_count < max_matches_per_player:
            player_data += [[player.player_id, player.name, 0, 0, 0, 0, 0, 0]] * (
                max_matches_per_player - row_count
            )

    df = pd.DataFrame(player_data, columns=col_names)
    df["date"] = pd.to_datetime(df["date"], errors="coerce")
    df.reset_index(drop=True, inplace=True)

    return df