Esempio n. 1
0
def main(args: Namespace):
    load_teams(args.database)
    league = league_register[get_unique_league(args)]
    load_league(args.database, league)

    seasons = Season.seasons(league)
    if not seasons:
        messages.error_message("No season data found")

    for season in seasons:
        show_results(league, season, args.results)
Esempio n. 2
0
def main(args: Namespace):
    load_teams(args.database)
    league = league_register[get_unique_league(args)]
    load_league(args.database, league)

    seasons = Season.seasons(league)
    if args.history:
        seasons = seasons[-args.history:]

    this_season = seasons.pop()
    (row, ) = extract_picked_team(args.database, args.team, league)
    team = Team.inventory[row[0]]

    events = [win, loss]
    colors = ['dodgerblue', 'salmon']
    data = []
    for i, func in enumerate(events):
        title = '{} margin (Seasons:{}-{})'.format(Event.name(func, False),
                                                   seasons[0].year,
                                                   seasons[-1].year)
        container_a = BarContainer(colors[i], title)
        for season in seasons:
            populate(season, team, args.venue, args.half, container_a.data,
                     func)

        title = '{} margin (Season:{})'.format(Event.name(func, False),
                                               this_season.year)
        container_b = BarContainer(colors[i], title)
        populate(this_season, team, args.venue, args.half, container_b.data,
                 func)
        data.append([container_a, container_b])

    fig, axs = plt.subplots(nrows=2,
                            ncols=2,
                            figsize=(10, 10),
                            squeeze=False,
                            constrained_layout=True)
    for row in range(len(events)):
        containers = data[row]
        for col, container in enumerate(containers):
            ax = axs[row, col]
            add_bar_chart(ax, container)

    title = '{} {}: {}'.format(league.country, league.name, team.name)
    if args.venue == Venue.any:
        title = '{} ({} or {})'.format(title, Venue.home.name, Venue.away.name)
    else:
        title = '{} ({} only)'.format(title, args.venue.name)

    if args.half != Half.both:
        title = '{} ({} half)'.format(title, args.half.name)

    fig.suptitle(title, fontweight='bold', fontsize=14)
    plt.show(block=args.block)
Esempio n. 3
0
def main(args: Namespace):
    load_teams(args.database)
    league = league_register[get_unique_league(args)]
    load_league(args.database, league)

    seasons = Season.seasons(league)
    if not seasons:
        messages.error_message("No season data found")

    if args.history:
        seasons = seasons[-args.history:]

    selected_team = None
    if args.team:
        (row, ) = extract_picked_team(args.database, get_unique_team(args),
                                      league)
        selected_team = Team.inventory[row[0]]

    intervals = []
    create_intervals(intervals, args.intervals, 0)
    create_intervals(intervals, args.intervals, 45)

    season_to_summary = OrderedDict()
    with ThreadPoolExecutor(max_workers=8) as executor:
        future_to_data = {
            executor.submit(compute_summaries, args.database, season,
                            intervals, selected_team, args.venue): season
            for season in seasons
        }
        for future in as_completed(future_to_data):
            season = future_to_data[future]
            overall, for_team, against_team = future.result()
            if overall:
                season_to_summary[season] = (overall, for_team, against_team)

    title = 'Goal times: {} {}'.format(league.country, league.name)
    if selected_team:
        title = '{} and {}'.format(title, selected_team.name)
        if args.venue == Venue.any:
            title = '{} ({} or {})'.format(title, Venue.home.name,
                                           Venue.away.name)
        else:
            title = '{} ({} only)'.format(title, args.venue.name)

    show(title, season_to_summary, args.block)
Esempio n. 4
0
def main(args: Namespace):
    load_teams(args.database)
    league = league_register[get_unique_league(args)]
    load_league(args.database, league)

    seasons = Season.seasons(league)
    if args.history:
        seasons = seasons[-args.history:]

    head_season = seasons[-1]
    head_table = LeagueTable(head_season, args.half)
    table_map = head_table.group(args.chunks)
    predicates = predicate_table[args.analysis]
    matrix = np.zeros(shape=(table_map.number_of_chunks(),
                             len(predicates.functions)),
                      dtype=np.int32)

    for season in seasons:
        table = LeagueTable(season, args.half)
        table_map = table.group(args.chunks)
        fill_matrix(matrix, table_map, table, predicates, args.half)

    datum = pd.DataFrame(matrix)
    datum.columns = [
        Event.name(func, negate=False, short=True)
        for func in predicates.functions
    ]
    datum.index = create_chunk_labels(table_map)

    fig, ax = plt.subplots(nrows=1,
                           ncols=1,
                           figsize=(10, 10),
                           constrained_layout=True)
    heatmap(datum, cmap='coolwarm', linewidth=0.5, annot=True, fmt='d', ax=ax)
    ax.set_ylabel('Positions')
    ax.set_xlabel(args.analysis.name.capitalize())

    sublists = split_into_contiguous_groups(
        [season.year for season in seasons])
    title = '{} {} Seasons:{}'.format(league.country, league.name,
                                      to_string(sublists))
    if args.half != Half.both:
        title = '{} ({} half)'.format(title, args.half.name)
    fig.suptitle(title, fontweight='bold', fontsize=14)
    plt.show(block=args.block)
Esempio n. 5
0
def get_current_season(db: Database, league: League):
    country_constraint = "{}='{}' {} {}".format(ColumnNames.Country.name,
                                                league.country,
                                                Keywords.COLLATE.name,
                                                Keywords.NOCASE.name)

    name_constraint = "{}='{}' {} {}".format(ColumnNames.Code.name,
                                             league.name,
                                             Keywords.COLLATE.name,
                                             Keywords.NOCASE.name)

    current_constraint = "{}={}".format(ColumnNames.Current.name,
                                        Characters.TRUE.value)
    constraints = [country_constraint, name_constraint, current_constraint]
    season_rows = db.fetch_all_rows(Season.sql_table(), constraints)
    if season_rows:
        (season, ) = season_rows
        return season
Esempio n. 6
0
def update_all(database: str, past: bool, force: bool):
    codes = []
    with Database(database) as db:
        team_rows = db.fetch_all_rows(Team.sql_table())
        for row in team_rows:
            create_team_from_row(row)

        for code, league in league_register.items():
            constraints = [
                "{}='{}'".format(ColumnNames.Country.name, league.country),
                "{}='{}'".format(ColumnNames.Code.name, league.name)
            ]
            season_rows = db.fetch_all_rows(Season.sql_table(), constraints)
            for season_row in season_rows:
                season = create_season_from_row(season_row)
                if season.current:
                    if force or fixtures_played(database, season):
                        codes.append(code)

    update_leagues(database, codes, past, force or codes)
Esempio n. 7
0
def show_results(league: League, season: Season, results: List[str]):
    matched = []
    for fixture in season.fixtures():
        result = fixture.full_time()
        if result:
            for given_result in results:
                left, right = map(int, given_result.split('-'))
                if left == result.left and right == result.right:
                    matched.append(fixture)
        else:
            messages.warning_message('Ignoring {}'.format(fixture))

    if matched:
        table = LeagueTable(season, Half.both)
        print('>' * 40, season.year, '<' * 40)
        for fixture in matched:
            print('{:<2} vs {:<2}: {}'.format(
                table.team_position(fixture.home_team) + 1,
                table.team_position(fixture.away_team) + 1, fixture))
        print()
Esempio n. 8
0
def compute_statistics(season: Season, team: Team, venue: Venue,
                       game_states: List[str]):
    fixtures = []
    for fixture in season.fixtures():
        if fixture.first_half() is not None and fixture.second_half(
        ) is not None:
            if venue == Venue.any:
                if fixture.home_team == team or fixture.away_team == team:
                    fixtures.append(fixture)
            elif venue == Venue.away:
                if fixture.away_team == team:
                    fixtures.append(fixture)
            elif venue == Venue.home:
                if fixture.home_team == team:
                    fixtures.append(fixture)

    stats = MatchStatistics()
    for fixture in fixtures:
        if fixture.home_team == team:
            first_half = fixture.first_half()
            second_half = fixture.second_half()
            full_time = fixture.full_time()
        else:
            first_half = fixture.first_half().reverse()
            second_half = fixture.second_half().reverse()
            full_time = fixture.full_time().reverse()

        analyse = True
        if game_states:
            analyse = False
            for state in game_states:
                left, right = map(int, state.split('-'))
                if not analyse:
                    analyse = left == first_half.left and right == first_half.right

        if analyse:
            update_stats(stats.first_half, first_half)
            update_stats(stats.second_half, second_half)
            update_stats(stats.both_halves, full_time)

    return stats
Esempio n. 9
0
def main(args: Namespace):
    load_teams(args.database)
    league = league_register[get_unique_league(args)]
    load_league(args.database, league)
    seasons = Season.seasons(league)

    if args.history:
        seasons = seasons[-args.history:]

    if args.relative:
        team_names = get_multiple_teams(args)
        table = LeagueTable(seasons[-1], args.half)
        lower, upper = table.positions(Position.from_string(args.relative))
        positions = [i for i in range(lower, upper)]
        compute_relative_performance(args, league, seasons, team_names, positions)
    elif args.position:
        team_names = get_multiple_teams(args)
        compute_relative_performance(args, league, seasons, team_names, args.position)
    elif args.average:
        team_name = get_unique_team(args)
        compute_average_performance(args, league, seasons, team_name)
    else:
        compute_individual_performance(args, league, seasons)
Esempio n. 10
0
def main(args: Namespace):
    load_teams(args.database)
    league = league_register[get_unique_league(args)]
    load_league(args.database, league)

    seasons = Season.seasons(league)
    if not seasons:
        messages.error_message("No season data found")

    season_to_summary = OrderedDict()
    ylim = 0
    for season in seasons:
        summary = compute_summary(season, args.half)
        if summary:
            season_to_summary[season] = summary
            ylim = max(ylim, season_to_summary[season].home_goals,
                       season_to_summary[season].away_goals)
    ylim += 25

    title = '{} {}'.format(league.country, league.name)
    if args.half != Half.both:
        title += ' ({} half)'.format(args.half.name)

    show(title, season_to_summary, ylim, args.block)
Esempio n. 11
0
def main(args: Namespace):
    load_teams(args.database)
    league = league_register[get_unique_league(args)]
    load_league(args.database, league)

    seasons = Season.seasons(league)
    if not seasons:
        messages.error_message("No season data found")

    if args.history:
        seasons = seasons[-args.history:]

    if args.team:
        (row, ) = extract_picked_team(args.database, args.team, league)
        selected_team = Team.inventory[row[0]]
    else:
        selected_team = None

    func = Event.get(get_unique_event(args))
    if args.chunks:
        data = compute_chunked_data(seasons, func, args.negate, args.venue,
                                    args.half, args.chunks)

        nrows = len(data)
        if selected_team is not None:
            ncols = 3
        else:
            ncols = 1

        fig, axes = plt.subplots(nrows=len(data),
                                 ncols=ncols,
                                 figsize=(20, 13),
                                 squeeze=False,
                                 constrained_layout=True)

        x_limit, _ = find_limits(data)
        for i, datum in enumerate(data):
            ax = axes[i, 0]
            plot(ax, datum, x_limit, args.lines)

        if selected_team is not None:
            golden_season = seasons[-1]
            golden_table = LeagueTable(golden_season, args.half)
            golden_map = golden_table.group(args.chunks)

            chunk_to_seasons = OrderedDict()
            for chunk_id in range(golden_map.number_of_chunks()):
                if chunk_id not in chunk_to_seasons:
                    chunk_to_seasons[chunk_id] = []

            for season in seasons:
                if season != golden_season:
                    table = LeagueTable(season, args.half)
                    table_map = table.group(args.chunks)
                    if selected_team in season.teams():
                        position = table.team_position(selected_team)
                        chunk_id = table_map.get_chunk(position)
                        chunk_to_seasons[chunk_id].append(season)

            chunk_to_datum = OrderedDict()
            for chunk_id, chunk_seasons in chunk_to_seasons.items():
                if chunk_seasons:
                    datum = DataUnit(Counter(),
                                     chunk_seasons,
                                     team=selected_team,
                                     positions=golden_map.get_rows(chunk_id))
                    chunk_to_datum[chunk_id] = datum

            for season in seasons:
                if season == golden_season:
                    position = golden_table.team_position(selected_team)
                    datum = DataUnit(Counter(), [golden_season],
                                     team=selected_team,
                                     positions=[position],
                                     highlight=True)
                    golden_datum = datum
                else:
                    if selected_team in season.teams():
                        table = LeagueTable(season, args.half)
                        table_map = table.group(args.chunks)
                        position = table.team_position(selected_team)
                        chunk_id = table_map.get_chunk(position)
                        datum = chunk_to_datum[chunk_id]

                count_events(season, selected_team, args.venue, args.half,
                             func, args.negate, datum)

            position = golden_table.team_position(selected_team)
            chunk_id = golden_map.get_chunk(position)
            ax = axes[chunk_id, 1]
            plot(ax, golden_datum, x_limit, args.lines)
            used = {(chunk_id, 1)}

            for chunk_id, datum in chunk_to_datum.items():
                ax = axes[chunk_id, 2]
                plot(ax, datum, x_limit, args.lines)
                used.add((chunk_id, 2))

            for i in range(0, nrows):
                for j in range(1, 3):
                    if (i, j) not in used:
                        fig.delaxes(axes[i, j])
    else:
        data = compute_aggregated_data(seasons, selected_team, func,
                                       args.negate, args.venue, args.half)
        x_limit, _ = find_limits(data)
        display = DisplayGrid(len(data), 2)
        fig, axes = plt.subplots(nrows=display.nrows,
                                 ncols=display.ncols,
                                 figsize=(20, 10),
                                 squeeze=False)
        for i, datum in enumerate(data):
            cell_x, cell_y = display.index(i)
            ax = axes[cell_x, cell_y]
            plot(ax, datum, x_limit, args.lines)

    title = construct_title(league, func, args.negate, args.venue, args.half)
    fig.suptitle(title, fontweight='bold', fontsize=14)
    plt.show(block=args.block)
Esempio n. 12
0
def main(args: Namespace):
    league = league_register[get_unique_league(args)]
    load_database(args.database, league)

    seasons = Season.seasons(league)
    this_season = seasons.pop()
    assert this_season.current

    func = Event.get(get_unique_event(args))
    for i in range(1, 38):
        prediction = Prediction(func, i)
        penalties = Counter()
        for season in seasons:
            table = LeagueTable(season, Half.both)
            states = {team: TeamState() for team in season.teams()}
            season.sort_fixtures()

            fixture: Fixture
            for fixture in season.fixtures():
                if args.half == Half.both:
                    result = fixture.full_time()
                elif args.half == Half.first:
                    result = fixture.first_half()
                elif args.half == Half.second:
                    result = fixture.second_half()

                if result:
                    home_result = fixture.canonicalise_result(
                        fixture.home_team, result)
                    home_outcome = prediction.func(home_result)
                    home_state = states[fixture.home_team]

                    if not home_outcome:
                        home_state.fixtures.append(fixture)
                    else:
                        if home_state.alive:
                            index = len(
                                home_state.fixtures) - prediction.minimum + 1
                            penalties[index] += 1
                        states[fixture.home_team] = TeamState()

                    if len(home_state.fixtures) == prediction.minimum:
                        final_position = table.team_position(fixture.home_team)
                        if final_position not in [
                                0, 1, len(table) - 2,
                                len(table) - 1
                        ]:
                            home_state.alive = True

                    away_result = fixture.canonicalise_result(
                        fixture.away_team, result)
                    away_outcome = prediction.func(away_result)
                    away_state = states[fixture.away_team]
                    if not away_outcome:
                        away_state.fixtures.append(fixture)
                    else:
                        if away_state.alive:
                            index = len(
                                away_state.fixtures) - prediction.minimum + 1
                            penalties[index] += 1
                        states[fixture.away_team] = TeamState()

                        away_state.fixtures.append(fixture)

                    if len(away_state.fixtures) == prediction.minimum:
                        final_position = table.team_position(fixture.away_team)
                        if final_position not in [
                                0, 1, len(table) - 2,
                                len(table) - 1
                        ]:
                            away_state.alive = True

        total_penalty = 0
        total_correct = 0
        for distance, correct in penalties.items():
            exponent = distance
            this_penalty = 2**exponent - 1
            total_penalty += this_penalty * correct
            total_correct += correct
        if total_penalty:
            print(
                'Betting from sequences of {} returns {} right with a penalty of {}'
                .format(i, total_correct, total_penalty))
Esempio n. 13
0
def main(args: Namespace):
    load_teams(args.database)

    func = Event.get(get_unique_event(args))
    train_data = []
    train_history = []
    for code in args.league:
        league = league_register[code]
        load_league(args.database, league)

        seasons = Season.seasons(league)
        *seasons, _ = seasons
        collect_data(seasons, func, train_data, train_history)

    dependent_variable = Event.name(func, False)
    df = pd.DataFrame.from_records(train_data)
    cols = []
    for x in HistorySummary.__slots__:
        cols.extend(['H({})'.format(x), 'A({})'.format(x)])
    cols.append(dependent_variable)
    df.columns = cols

    plt.figure()

    y_train = df[dependent_variable]
    x_train = df.drop([dependent_variable], axis=1)

    rf = RandomForestClassifier()
    rf.fit(x_train, y_train)
    print("Features sorted by their score:")
    print(
        sorted(zip(map(lambda x: round(x, 4), rf.feature_importances_),
                   x_train),
               reverse=True))

    model = RandomForestClassifier()
    # Fit the model
    model.fit(x_train, y_train)
    # Accuracy
    score = model.score(x_train, y_train)
    print(score)

    test_data = []
    test_history = []
    for code in args.league:
        league = league_register[code]
        load_league(args.database, league)

        seasons = Season.seasons(league)
        *_, this_season = seasons
        collect_data([this_season], func, test_data, test_history)

    df = pd.DataFrame.from_records(test_data)
    cols = []
    for x in HistorySummary.__slots__:
        cols.extend(['H({})'.format(x), 'A({})'.format(x)])
    cols.append(dependent_variable)
    df.columns = cols

    y_test = df[dependent_variable]
    x_test = df.drop([dependent_variable], axis=1)

    predicted = list(model.predict(x_test))

    true_positives = []
    true_negatives = []
    false_positives = []
    false_negatives = []
    for i in range(len(y_test)):
        if y_test[i] and predicted[i]:
            true_positives.append(test_history[i])
        elif not y_test[i] and not predicted[i]:
            true_negatives.append(test_history[i])
        elif not y_test[i] and predicted[i]:
            false_positives.append(test_history[i])
        elif y_test[i] and not predicted[i]:
            false_negatives.append(test_history[i])

    print()

    print('>>>>>>>>>>>>>>>>>>> True positives')
    for fixture in true_positives:
        print(fixture)

    print()

    print('>>>>>>>>>>>>>>>>>>> True negatives')
    for fixture in true_negatives:
        print(fixture)

    print()

    print('>>>>>>>>>>>>>>>>>>> False positives')
    for fixture in false_positives:
        print(fixture)

    print()

    print('>>>>>>>>>>>>>>>>>>> False negatives')
    for fixture in false_negatives:
        print(fixture)

    print('TP={}  TN={}  FP={}  FN={}'.format(len(true_positives),
                                              len(true_negatives),
                                              len(false_positives),
                                              len(false_negatives)))
Esempio n. 14
0
def count_events(season: Season,
                 team: Team,
                 venue: Venue,
                 half: Half,
                 func: Callable,
                 negate: bool,
                 data: DataUnit):
    fixtures = []
    for fixture in season.fixtures():
        if venue == Venue.any:
            if fixture.home_team == team or fixture.away_team == team:
                fixtures.append(fixture)
        elif venue == Venue.away:
            if fixture.away_team == team:
                fixtures.append(fixture)
        elif venue == Venue.home:
            if fixture.home_team == team:
                fixtures.append(fixture)

    sequence = []
    for fixture in fixtures:
        results = []
        if half == Half.both:
            if fixture.full_time() is not None:
                results.append(fixture.full_time())
        elif half == Half.first:
            if fixture.first_half() is not None:
                results.append(fixture.first_half())
            else:
                warning_message('No 1st half result for fixture {}'.format(fixture))
        elif half == Half.second:
            if fixture.second_half() is not None:
                results.append(fixture.second_half())
            else:
                warning_message('No 2nd half result for fixture {}'.format(fixture))
        elif half == Half.separate:
            if fixture.first_half() is not None:
                results.append(fixture.first_half())
            if fixture.second_half() is not None:
                results.append(fixture.second_half())
        else:
            assert False

        if results:
            for result in results:
                if fixture.home_team != team:
                    result = result.reverse()

                if negate:
                    outcome = not func(result)
                else:
                    outcome = func(result)

                if outcome:
                    sequence.append(fixture)
                else:
                    data.last = len(sequence)
                    data.counter[len(sequence)] += 1
                    sequence = []

    if sequence:
        data.last = len(sequence)
        data.counter[len(sequence)] += 1
    else:
        data.last = None
Esempio n. 15
0
def main(args: Namespace):
    load_teams(args.database)
    league = league_register[get_unique_league(args)]
    load_league(args.database, league)

    seasons = Season.seasons(league)
    if args.history:
        seasons = seasons[-args.history:]

    event = Event.get(get_unique_event(args))

    head_season = seasons[-1]
    head_table = LeagueTable(head_season, args.half)
    if head_table.played() == 0:
        head_season = seasons[-2]
        head_table = LeagueTable(head_season, args.half)
        nrows = 1
    else:
        nrows = 2

    head_map = head_table.group(args.chunks)
    shape = (head_map.number_of_chunks(), head_map.number_of_chunks())

    historical_matrix = np.zeros(shape=shape, dtype=np.int32)
    historical_seasons = seasons[:-1]
    for season in historical_seasons:
        table = LeagueTable(season, args.half)
        fill_matrix(event, args.symmetry, historical_matrix, head_map, table,
                    args.half)

    display = DisplayGrid(nrows, 1)
    fig, axs = plt.subplots(nrows=display.nrows,
                            ncols=display.ncols,
                            figsize=(15, 12),
                            squeeze=False,
                            constrained_layout=True)

    datum = pd.DataFrame(historical_matrix)
    sublists = split_into_contiguous_groups(
        [season.year for season in historical_seasons])
    title = 'Seasons:{}'.format(to_string(sublists))
    cell_x, cell_y = display.index(0)
    ax = axs[cell_x, cell_y]
    populate_axis(head_map, datum, ax, title)

    if nrows == 2:
        now_matrix = np.zeros(shape=shape, dtype=np.int32)
        fill_matrix(event, args.symmetry, now_matrix, head_map, head_table,
                    args.half)
        datum = pd.DataFrame(now_matrix)
        title = 'Season:{}'.format(head_season.year)
        cell_x, cell_y = display.index(1)
        ax = axs[cell_x, cell_y]
        populate_axis(head_map, datum, ax, title)

    title = '{} {}: {}'.format(league.country, league.name,
                               Event.name(event, args.negate))
    if args.half != Half.both:
        title = '{} ({} half)'.format(title, args.half.name)
    fig.suptitle(title, fontweight='bold', fontsize=14)
    plt.show(block=args.block)