Beispiel #1
0
 def _log(substatistic, which):
     if which is None:
         get_logger().debug('%s', substatistic.to_string(index=False))
     else:
         log_columns = ['date', 'home', 'away'] + wrap(which)
         get_logger().debug(
             '%s', substatistic[log_columns].to_string(index=False))
    def _fit(self, **kwargs):
        get_logger('prediction').info('Условие для получения заголовков: %s',
                                      str(self.sample_condition))
        self.match_headers = get_match_headers(self.sample_condition)
        get_logger('prediction').info('Получены заголовки матчей: %u штук',
                                      self.match_headers.shape[0])

        # TODO: Решить, что с этим делать
        self.statistic = self.match_headers.copy()
    def _fit(self, match_header, **kwargs):
        statistic = self.previous_fitter.statistic.copy()
        if statistic.shape[0] == 0:
            self.statistic = statistic
            return

        self.match_date = match_header['date']
        self.last_datetime = eve_datetime(self.match_date)
        transformed_statistic = statistic[
            statistic['date'] <= self.last_datetime]

        self.statistic = transformed_statistic.copy()
        get_logger('prediction').info(
            'Отобраны заголовки матчей, доступные на %s: %u штук',
            self.last_datetime.strftime('%Y-%m-%d %H:%M:%S'),
            self.statistic.shape[0])
    def _fit(self, match_header, **kwargs):
        statistic = self.previous_fitter.statistic.copy()
        if statistic.shape[0] == 0:
            self.statistic = statistic
            return

        self.tournament_id = match_header['tournamentId']

        transformed_statistic = statistic[statistic['tournament_id'] ==
                                          self.tournament_id]

        self.statistic = transformed_statistic.copy()
        get_logger('prediction').info(
            'Отобраны заголовки матчей, произошедших в рамках турнира %s (%u): %u штук',
            get_value(tournaments_data, 'whoscoredTournamentId',
                      self.tournament_id, 'whoscoredTournamentName'),
            self.tournament_id, self.statistic.shape[0])
Beispiel #5
0
    def _fit(self, match_header, **kwargs):
        statistic = self.previous_fitter.statistic.copy()
        if statistic.shape[0] == 0:
            self.statistic = statistic
            return

        self.match_date = match_header['date']
        self.first_datetime = eve_datetime(self.match_date - self.delta)
        self.last_datetime = eve_datetime(self.match_date)

        transformed_statistic = statistic[
            (statistic['date'] >= self.first_datetime)
            & (statistic['date'] <= self.last_datetime)]

        self.statistic = transformed_statistic.copy()
        get_logger('prediction').info(
            'Отобраны заголовки матчей, произошедших не более чем за %s до матча (с %s по %s): %u штук',
            str(self.delta), self.first_datetime.strftime('%Y-%m-%d'),
            self.last_datetime.strftime('%Y-%m-%d'), self.statistic.shape[0])
    def _get_match_value(match_uuid, crosses_first_period_statistic,
                         shots_first_period_statistic):
        crosses_first_period_home_count = crosses_first_period_statistic.at[
            match_uuid, 'events_home_count']
        crosses_first_period_away_count = crosses_first_period_statistic.at[
            match_uuid, 'events_away_count']
        get_logger('betting').debug('Количество кроссов в 1-м тайме: %u : %u',
                                    crosses_first_period_home_count,
                                    crosses_first_period_away_count)

        shots_first_period_home_count = shots_first_period_statistic.at[
            match_uuid, 'events_home_count']
        shots_first_period_away_count = shots_first_period_statistic.at[
            match_uuid, 'events_away_count']
        get_logger('betting').debug('Количество ударов в 1-м тайме: %u : %u',
                                    shots_first_period_home_count,
                                    shots_first_period_away_count)

        match_value = ((crosses_first_period_home_count -
                        crosses_first_period_away_count) +
                       (shots_first_period_home_count -
                        shots_first_period_away_count)) / 2
        get_logger('betting').debug('"Значение" предыдущего матча: %f',
                                    match_value)

        return match_value
Beispiel #7
0
    def _fit(self, match_header, **kwargs):
        statistic = self.previous_fitter.statistic.copy()
        if statistic.shape[0] == 0:
            self.statistic = statistic
            return

        self.home = match_header['home']
        self.away = match_header['away']

        last_home_uuids = statistic[(statistic['home'] == self.home) | (
            statistic['away'] == self.home)].index.values[:self.n]
        last_away_uuids = statistic[(statistic['away'] == self.away) | (
            statistic['home'] == self.away)].index.values[:self.n]
        last_uuids = np.unique(
            np.concatenate([last_home_uuids, last_away_uuids]))

        transformed_statistic = statistic.loc[last_uuids]

        self.statistic = transformed_statistic.copy()
        get_logger('prediction').info(
            'Отобраны последние %u заголовков матчей, где команда %s также была хозяйкой, и последние %u заголовков матчей, где команда %s также была гостей: %u штук',
            self.n, match_header['home'], self.n, match_header['away'],
            self.statistic.shape[0])
Beispiel #8
0
    def _predict(self, fitteds, match_header, **kwargs):
        [corners_diffs_diff_fitted] = fitteds

        get_logger('prediction').info('Предсказываем разницу угловых...')
        corners_diffs_diff_prediction = self._corners_diffs_diff_predictor._predict(
            [corners_diffs_diff_fitted], match_header, **kwargs)
        if corners_diffs_diff_prediction is None:
            get_logger('prediction').info('Алгоритм не выдал предсказание')
            return None
        get_logger('prediction').info('Предсказание разницы угловых: %.1f',
                                      corners_diffs_diff_prediction)

        return corners_diffs_diff_prediction
    def _predict(self, fitteds, match_header, **kwargs):
        [corners_results_fitted] = fitteds

        get_logger('prediction').info('Предсказываем угловые...')
        corners_result_prediction = self._corners_results_result_predictor._predict(
            [corners_results_fitted], match_header, **kwargs)
        if corners_result_prediction is None:
            get_logger('prediction').info('Алгоритм не выдал предсказание')
            return None
        get_logger('prediction').info('Предсказание угловых: %.1f:%.1f',
                                      corners_result_prediction[0],
                                      corners_result_prediction[1])

        return corners_result_prediction
Beispiel #10
0
    def _predict(self, fitteds, match_header, **kwargs):
        [statistic_fitted] = fitteds

        statistic = statistic_fitted.statistic
        get_logger('prediction').info('В собранной статистике %u матчей',
                                      statistic.shape[0])

        if statistic.shape[0] == 0:
            get_logger('prediction').info(
                'В собранной статистике нет матчей, не могу сделать предсказание'
            )
            return None

        additional_info = get_additional_info(match_header['uuid'])
        if additional_info is None:
            return None
        if 'homePlayers' not in additional_info or 'awayPlayers' not in additional_info:
            get_logger('prediction').info(
                'В матче не известен состав игроков, не могу сделать предсказание'
            )
            return None

        home_player_names = [
            player['playerName'] for player in additional_info['homePlayers']
            if player['isFirstEleven']
        ]
        get_logger('prediction').info('Игроки хозяев: %s',
                                      str(home_player_names))
        away_player_names = [
            player['playerName'] for player in additional_info['awayPlayers']
            if player['isFirstEleven']
        ]
        get_logger('prediction').info('Игроки гостей: %s',
                                      str(away_player_names))
        if len(home_player_names) != 11 or len(away_player_names) != 11:
            print('Bad players count in match %s' %
                  (get_match_title(match_header, show_uuid=True), ))
            get_logger('prediction').info(
                'В матче неверное количество игроков (известны не все игроки?), не могу сделать предсказание'
            )
            return None

        events_home_counts = []
        get_logger('prediction').info('Рассчитаем среднее по игрокам хозяев')
        for player_name in frozenset(
                statistic.columns.values) & frozenset(home_player_names):
            if self.n is not None:
                get_logger('prediction').info(
                    'Выберем %u последних матчей из статистики игрока %s',
                    self.n, player_name)
            else:
                get_logger('prediction').info(
                    'Выберем всю статистику игрока %s', player_name)
            events_player_counts = get_substatistic(statistic,
                                                    n=self.n,
                                                    min_n=self.min_n,
                                                    sort_by='date',
                                                    ascending=False,
                                                    which=player_name,
                                                    notnull=player_name)
            if events_player_counts is None:
                get_logger('prediction').info(
                    'Матчей оказалось меньше порога в %u матча', self.min_n)
                continue

            weights_full = get_weights_array(events_player_counts.shape[0],
                                             self.weights)
            get_logger('prediction').info('Веса: %s', str(weights_full))
            events_player_counts_mean = np.sum(events_player_counts *
                                               weights_full)
            get_logger('prediction').info('Взвешанное среднее: %s',
                                          str(events_player_counts_mean))

            events_home_counts.append(events_player_counts_mean)

        get_logger('prediction').info(
            'Получили следующие средние для игроков хозяев (%u значений): %s',
            len(events_home_counts), events_home_counts)
        if len(events_home_counts) < self.min_real_players:
            get_logger('prediction').info(
                'Значений оказалось меньше порога в %u матча',
                self.min_real_players)
            return None
        events_home_counts_mean = np.sum(events_home_counts)
        get_logger('prediction').info('Среднее для хозяев: %f',
                                      events_home_counts_mean)

        events_away_counts = []
        get_logger('prediction').info('Рассчитаем среднее по игрокам гостей')
        for player_name in frozenset(
                statistic.columns.values) & frozenset(away_player_names):
            if self.n is not None:
                get_logger('prediction').info(
                    'Выберем %u последних матчей из статистики игрока %s',
                    self.n, player_name)
            else:
                get_logger('prediction').info(
                    'Выберем всю статистику игрока %s', player_name)
            events_player_counts = get_substatistic(statistic,
                                                    n=self.n,
                                                    min_n=self.min_n,
                                                    sort_by='date',
                                                    ascending=False,
                                                    which=player_name,
                                                    notnull=player_name)
            if events_player_counts is None:
                get_logger('prediction').info(
                    'Матчей оказалось меньше порога в %u матча', self.min_n)
                continue

            weights_full = get_weights_array(events_player_counts.shape[0],
                                             self.weights)
            get_logger('prediction').info('Веса: %s', str(weights_full))
            events_player_counts_mean = np.sum(events_player_counts *
                                               weights_full)
            get_logger('prediction').info('Взвешанное среднее: %s',
                                          str(events_player_counts_mean))

            events_away_counts.append(events_player_counts_mean)

        get_logger('prediction').info(
            'Получили следующие средние для игроков гостей (%u значений): %s',
            len(events_away_counts), events_away_counts)
        if len(events_away_counts) < self.min_real_players:
            get_logger('prediction').info(
                'Значений оказалось меньше порога в %u матча',
                self.min_real_players)
            return None
        events_away_counts_mean = np.sum(events_away_counts)
        get_logger('prediction').info('Среднее для гостей: %f',
                                      events_away_counts_mean)

        result_prediction = (events_home_counts_mean, events_away_counts_mean)
        get_logger('prediction').info('Итого, предсказание: %.1f:%.1f',
                                      result_prediction[0],
                                      result_prediction[1])

        return result_prediction
    def _fit(self, **kwargs):
        super()._fit(**kwargs)

        get_logger('prediction').info(
            'Добавлена информация (по каждой команде) о количестве событий "красная карточка" (матч)'
        )
    def _fit(self, **kwargs):
        super()._fit(**kwargs)

        get_logger('prediction').info(
            'Добавлена информация (по каждой команде) о количестве событий "кросс" (2-й тайм)'
        )
    def _predict(self, fitteds, match_header, **kwargs):
        [
            crosses_first_period_statistic_fitted,
            shots_first_period_statistic_fitted
        ] = fitteds

        crosses_first_period_statistic = crosses_first_period_statistic_fitted.statistic
        shots_first_period_statistic = shots_first_period_statistic_fitted.statistic

        crosses_first_period_match_uuids = set(
            crosses_first_period_statistic['uuid'].values)
        shots_first_period_match_uuids = set(
            shots_first_period_statistic['uuid'].values)
        if crosses_first_period_match_uuids != shots_first_period_match_uuids:
            get_logger('betting').info(
                'В собранных статистиках (кроссы, 1-й тайм; удары, 1-й тайм) - различные матчи!'
            )
            raise RuntimeError('different matches in statistics!')

        statistic_match_headers = crosses_first_period_statistic[[
            'date', 'home', 'away'
        ]].copy()

        get_logger('betting').info('В собранной статистике - %u матчей',
                                   statistic_match_headers.shape[0])
        if statistic_match_headers.shape[0] == 0:
            get_logger('betting').info(
                'В собранной статистике нет матчей, не могу сделать предсказание'
            )
            return None

        if not self._match_same_location_only:
            get_logger('betting').info(
                'Выберем последний матч из статистики, где играла команда %s',
                match_header['home'])
            home_matches = statistic_match_headers[
                (statistic_match_headers['home'] == match_header['home']) |
                (statistic_match_headers['away'] == match_header['home'])]
        else:
            get_logger('betting').info(
                'Выберем последний матч из статистики, где играла команда %s, причем так же дома',
                match_header['home'])
            home_matches = statistic_match_headers[
                statistic_match_headers['home'] == match_header['home']]
        if home_matches.shape[0] == 0:
            get_logger('betting').info(
                'Такого матча нет, не могу сделать предсказание')
            return None
        last_home_match_uuid = home_matches['date'].argmax()
        last_home_match = home_matches.loc[last_home_match_uuid]
        get_logger('betting').info('Предыдущий матч хозяев: %s',
                                   get_match_title(last_home_match))

        was_last_home_match_home = match_header['home'] == last_home_match[
            'home']
        if was_last_home_match_home:
            get_logger('betting').info(
                'Хозяева так же играли дома в последнем матче')
            last_home_match_competitor = last_home_match['away']
        else:
            get_logger('betting').info(
                'Хозяева играли в гостях в последнем матче')
            last_home_match_competitor = last_home_match['home']

        last_home_match_value = self._get_match_value(
            last_home_match_uuid, crosses_first_period_statistic,
            shots_first_period_statistic)
        get_logger('betting').info('"Значение" предыдущего матча хозяев: %f',
                                   last_home_match_value)
        home_number = last_home_match_value if was_last_home_match_home else -last_home_match_value
        get_logger('betting').info('"Число для хозяев": %f', home_number)

        corrected_home_number = home_number
        if not was_last_home_match_home:
            get_logger('betting').info(
                'Последний матч хозяева играли в гостях, поэтому прибавляем 3')
            corrected_home_number += 3
        get_logger('betting').info(
            'Ограничиваем "число для хозяев" отрезком [-7, 7]')
        corrected_home_number = np.clip(corrected_home_number, -7, 7)

        if last_home_match_competitor in self._favorites:
            return None

            # Версия отказа при "проигрыше" сопернику-фавориту:
            """
            if home_number < -1:
                get_logger('betting').info('Соперники хозяев в их предыдущем матче - фавориты, и они "проиграли", исходя из значения матча; отказываюсь от предсказания')
                return None
            else:
                get_logger('betting').info('Соперники хозяев в их предыдущем матче - фавориты, но они "выиграли", исходя из значения матча; будем делать предсказание, но поставим только на хозяев')
                propose_away_bets = False
            """

        get_logger('betting').info('"Число для хозяев", скорректированное: %f',
                                   corrected_home_number)

        if not self._match_same_location_only:
            get_logger('betting').info(
                'Выберем последний матч из статистики, где играла команда %s',
                match_header['away'])
            away_matches = statistic_match_headers[
                (statistic_match_headers['home'] == match_header['away']) |
                (statistic_match_headers['away'] == match_header['away'])]
        else:
            get_logger('betting').info(
                'Выберем последний матч из статистики, где играла команда %s, причем так же в гостях',
                match_header['away'])
            away_matches = statistic_match_headers[
                statistic_match_headers['away'] == match_header['away']]
        if away_matches.shape[0] == 0:
            get_logger('betting').info(
                'Такого матча нет, не могу сделать предсказание')
            return None
        last_away_match_uuid = away_matches['date'].argmax()
        last_away_match = away_matches.loc[last_away_match_uuid]
        get_logger('betting').info('Предыдущий матч гостей: %s',
                                   get_match_title(last_away_match))

        was_last_away_match_away = match_header['away'] == last_away_match[
            'away']
        if was_last_away_match_away:
            get_logger('betting').info(
                'Гости так же играли в гостях в последнем матче')
            last_away_match_competitor = last_away_match['home']
        else:
            get_logger('betting').info('Гости играли дома в последнем матче')
            last_away_match_competitor = last_away_match['away']

        last_away_match_value = self._get_match_value(
            last_away_match_uuid, crosses_first_period_statistic,
            shots_first_period_statistic)
        get_logger('betting').info('"Значение" предыдущего матча гостей: %f',
                                   last_away_match_value)
        away_number = -last_away_match_value if was_last_away_match_away else last_away_match_value
        get_logger('betting').info('"Число для гостей": %f', away_number)

        corrected_away_number = away_number
        if not was_last_away_match_away:
            get_logger('betting').info(
                'Последний матч гостей играли дома, поэтому отнимаем 3')
            corrected_away_number -= 3
        get_logger('betting').info(
            'Ограничиваем "число для гостей" отрезком [-7, 7]')
        corrected_away_number = np.clip(corrected_away_number, -7, 7)

        if last_away_match_competitor in self._favorites:
            return None

            # Версия отказа при "проигрыше" сопернику-фавориту:
            """
            if away_number > 1:
                get_logger('betting').info('Соперники гостей в их предыдущем матче - фавориты, и они "проиграли", исходя из значения матча; отказываюсь от предсказания')
                return None
            else:
                get_logger('betting').info('Соперники гостей в их предыдущем матче - фавориты, но они "выиграли", исходя из значения матча; будем делать предсказание, но поставим только на гостей')
                propose_home_bets = False
            """

        get_logger('betting').info('"Число для хозяев", скорректированное: %f',
                                   corrected_away_number)

        return (corrected_home_number, corrected_away_number)
    def _predict(self, fitteds, match_header, **kwargs):
        [statistic_fitted] = fitteds

        statistic = statistic_fitted.statistic
        get_logger('prediction').info('В собранной статистике %u матчей',
                                      statistic.shape[0])

        if statistic.shape[0] == 0:
            get_logger('prediction').info(
                'В собранной статистике нет матчей, не могу сделать предсказание'
            )
            return None

        get_logger('prediction').info(
            'Выберем %u последних матчей из статистики, где команда %s тоже была хозяйкой',
            self.n, match_header['home'])
        # Статистика матчей, где match_header['home'] тоже была хозяйкой
        events_home_counts = get_substatistic(statistic,
                                              notnull='events_home_count',
                                              by='home',
                                              value=match_header['home'],
                                              n=self.n,
                                              min_n=self.min_n,
                                              sort_by='date',
                                              ascending=False,
                                              which='events_home_count')

        if events_home_counts is None:
            get_logger('prediction').info(
                'Матчей оказалось меньше порога в %u матча', self.min_n)
            return None
        get_logger('prediction').info('Количество событий: %s',
                                      str(events_home_counts))

        home_weights_full = get_weights_array(events_home_counts.size,
                                              self.home_weights)
        get_logger('prediction').info('Веса: %s', str(home_weights_full))
        events_home_counts_mean = np.sum(events_home_counts *
                                         home_weights_full)
        get_logger('prediction').info('Взвешанное среднее: %f',
                                      events_home_counts_mean)

        get_logger('prediction').info(
            'Выберем %u последних матчей из статистики, где команда %s тоже была гостьей',
            self.n, match_header['away'])
        # Статистика матчей, где match_header['away'] тоже была гостьей
        events_away_counts = get_substatistic(statistic,
                                              notnull='events_away_count',
                                              by='away',
                                              value=match_header['away'],
                                              n=self.n,
                                              min_n=self.min_n,
                                              sort_by='date',
                                              ascending=False,
                                              which='events_away_count')

        if events_away_counts is None:
            get_logger('prediction').info(
                'Матчей оказалось меньше порога в %u матча', self.min_n)
            return None
        get_logger('prediction').info('Количество событий: %s',
                                      str(events_away_counts))

        away_weights_full = get_weights_array(events_away_counts.size,
                                              self.away_weights)
        get_logger('prediction').info('Веса: %s', str(away_weights_full))
        events_away_counts_mean = np.sum(events_away_counts *
                                         away_weights_full)
        get_logger('prediction').info('Взвешанное среднее: %f',
                                      events_away_counts_mean)

        result_prediction = (events_home_counts_mean, events_away_counts_mean)
        get_logger('prediction').info('Итого, предсказание: %.1f:%.1f',
                                      result_prediction[0],
                                      result_prediction[1])

        return result_prediction
    def _fit(self, **kwargs):
        super()._fit(**kwargs)

        get_logger('prediction').info(
            'Добавлена информация (по каждому игроку) о количестве событий "угловой" (2-й тайм)'
        )
Beispiel #16
0
    def handle(self,
               match_uuid,
               fit_kwargs=None,
               predict_kwargs=None,
               handle_kwargs=None,
               **kwargs):
        if fit_kwargs is None:
            fit_kwargs = {}
        if predict_kwargs is None:
            predict_kwargs = {}
        if handle_kwargs is None:
            handle_kwargs = {}

        match_header = get_match_header(match_uuid)
        if match_header is None:
            return

        log_capture_string = io.StringIO()
        ch = logging.StreamHandler(log_capture_string)
        ch.setLevel(logging.DEBUG)
        get_logger().addHandler(ch)

        # get_logger('prediction').debug('Провайдер: %s', str(self))
        get_logger('prediction').info('Описание провайдера: %s',
                                      self.description)
        get_logger('prediction').info(
            'Предсказание для матча %s',
            get_match_title(match_header, show_uuid=True))

        fitters_for_predictor = []
        for fitters_set in self.fitters_sets:
            if len(fitters_set) == 0:
                continue

            fitters_set[0].fit(match_header=match_header, **fit_kwargs)
            for j in range(1, len(fitters_set)):
                fitters_set[j].fit(match_header=match_header, **fit_kwargs)
            fitters_for_predictor.append(fitters_set[-1])

        prediction = self.predictor.predict(fitters_for_predictor,
                                            match_header, **predict_kwargs)

        get_logger().removeHandler(ch)
        log_contents = log_capture_string.getvalue()
        log_capture_string.close()

        prediction_info_uuid = get_identifier()
        prediction_info = {
            'uuid': prediction_info_uuid,
            'match_uuid': match_uuid,
            'provider_class_name': self.__class__.__name__,
            'provider_description': self.description,
            'provider_uuid': self.uuid,
            'prediction': prediction,
            'log': log_contents
        }

        prediction_infos_collection = db['prediction_infos']
        prediction_infos_collection.insert_one(prediction_info)

        for proposer in self.proposers:
            proposer.handle(match_header,
                            prediction_info=prediction_info,
                            **handle_kwargs)

        self.attempt_matches.add(match_header['uuid'])
Beispiel #17
0
    def _predict(self, fitteds, match_header, **kwargs):
        [statistic_fitted, tournament_event_counts_means_fitted] = fitteds

        statistic = statistic_fitted.statistic
        get_logger('prediction').info('В собранной статистике %u матчей',
                                      statistic.shape[0])

        if statistic.shape[0] == 0:
            get_logger('prediction').info(
                'В собранной статистике нет матчей, не могу сделать предсказание'
            )
            return None

        tournament_id = match_header['tournamentId']

        # Среднее количество голов, забиваемых хозяевами матчей в турнире
        tournament_events_home_counts_mean = tournament_event_counts_means_fitted.tournament_event_home_counts_means[
            tournament_id]
        # Среднее количество голов, забиваемых гостями матчей в турнире
        tournament_events_away_counts_mean = tournament_event_counts_means_fitted.tournament_event_away_counts_means[
            tournament_id]

        if tournament_events_home_counts_mean == 0 or tournament_events_away_counts_mean == 0:
            return None

        get_logger('prediction').info(
            'Выберем %u последних матчей из статистики, где команда %s тоже была хозяйкой',
            self.n, match_header['home'])
        # Статистика матчей, где match_header['home'] тоже была хозяйкой
        home_events_counts = get_substatistic(statistic,
                                              notnull='events_home_count',
                                              by='home',
                                              value=match_header['home'],
                                              n=self.n,
                                              min_n=self.min_n,
                                              sort_by='date',
                                              ascending=False,
                                              which='events_home_count')

        if home_events_counts is None:
            get_logger('prediction').info(
                'Матчей оказалось меньше порога в %u матча', self.min_n)
            return None
        get_logger('prediction').info('Количество событий: %s',
                                      str(home_events_counts))

        home_weights_full = get_weights_array(home_events_counts.size,
                                              self.home_weights)
        get_logger('prediction').info('Веса: %s', str(home_weights_full))

        get_logger('prediction').info(
            'Выберем %u последних матчей из статистики, где команда %s тоже была гостьей',
            self.n, match_header['away'])
        # Статистика матчей, где match_header['away'] тоже была гостьей
        away_events_counts = get_substatistic(statistic,
                                              notnull='events_away_count',
                                              by='away',
                                              value=match_header['away'],
                                              n=self.n,
                                              min_n=self.min_n,
                                              sort_by='date',
                                              ascending=False,
                                              which='events_away_count')

        if away_events_counts is None:
            get_logger('prediction').info(
                'Матчей оказалось меньше порога в %u матча', self.min_n)
            return None
        get_logger('prediction').info('Количество событий: %s',
                                      str(away_events_counts))

        away_weights_full = get_weights_array(away_events_counts.size,
                                              self.away_weights)
        get_logger('prediction').info('Веса: %s', str(away_weights_full))

        # Во сколько раз превышает среднее по турниру число голов, забитых match_header['home'] в домашних матчах?
        home_attack = np.sum(
            home_events_counts *
            home_weights_full) / tournament_events_home_counts_mean
        # Во сколько раз превышает среднее по турниру число голов, пропущенных match_header['away'] в гостевых матчах?
        away_defense = np.sum(
            home_events_counts *
            home_weights_full) / tournament_events_home_counts_mean
        # Во сколько раз превышает среднее по турниру число голов, пропущенных match_header['home'] в домашних матчах?
        home_defense = np.sum(
            away_events_counts *
            away_weights_full) / tournament_events_away_counts_mean
        # Во сколько раз превышает среднее по турниру число голов, забитых match_header['away'] в гостевых матчах?
        away_attack = np.sum(
            away_events_counts *
            away_weights_full) / tournament_events_away_counts_mean

        home_events_count_prediction = home_attack * away_defense * tournament_events_home_counts_mean
        away_events_count_prediction = away_attack * home_defense * tournament_events_away_counts_mean

        result_prediction = (home_events_count_prediction,
                             away_events_count_prediction)
        get_logger('prediction').info('Итого, предсказание: %.1f:%.1f',
                                      result_prediction[0],
                                      result_prediction[1])

        return result_prediction
    def _fit(self, **kwargs):
        super()._fit(**kwargs)

        get_logger('prediction').info(
            'Добавлена информация (по каждому игроку) о количестве событий "кросс" (матч)'
        )
    def _fit(self, **kwargs):
        super()._fit(**kwargs)

        get_logger('prediction').info('Добавлена информация (по каждой команде) о количестве событий "угловой" (матч, только периоды, пока хозяева побеждают)')
    def _fit(self, **kwargs):
        super()._fit(**kwargs)

        get_logger('prediction').info('Добавлена информация (по каждой команде) о количестве событий "угловой" (1-й тайм, пока гости побеждают)')
    def _fit(self, **kwargs):
        super()._fit(**kwargs)

        get_logger('prediction').info(
            'Добавлена информация о продолжительности игровых ситуаций по голам (матч)'
        )