Ejemplo n.º 1
0
    def _load_settings(self):
        file_data_handler = FileDataHandler()
        settings_spec = file_data_handler.load_spec(os.path.join(""),
                                                    self.settings_spec_name)

        if settings_spec is None:
            sys.exit("Can't load experiment spec")

        self.save_history = settings_spec["save_history"]
        self.print_simulator_output = settings_spec["print_simulator_output"]
        self.processing = settings_spec["processing"]
        self.num_cores = settings_spec["num_cores"]
        self.master_seed = settings_spec["master_seed"]
        self.n_experiment_reps = settings_spec["n_experiment_reps"]

        # Initialize state set
        self.date_from = settings_spec.get("date_from", None)
        self.date_to = settings_spec.get("date_to", None)

        self.time_steps_df, self.dates_list = \
            self._get_time_steps_data(self.date_from, self.date_to)

        self.state_set = StateSet(
            ["date", "how"], ["discrete", "discrete"],
            [self.dates_list, list(range(168))])

        # Initialize attribute set
        names = settings_spec["attributes"]["names"]
        vals = settings_spec["attributes"]["vals"]
        self.attr_set = AttrSet(names, vals)

        # Initialize action set
        self.action_set = ActionSet(self.attr_set,
                                    max_bid=9.99,
                                    min_bid=0.01,
                                    max_mod=9.0,
                                    min_mod=0.1)

        return settings_spec
Ejemplo n.º 2
0
def test_01_setup():
    """
    sample init init attr, state, action space
    :return:
    """
    names = ['gender', 'age']
    vals = {'gender': ['M', 'F', 'U'],
            'age': ['0-19', '20-29', '30-39', '40-49', '50-59', '60-69', '70-*']}
    attr_set = AttrSet(names, vals)

    state_set = StateSet(['date', 'how'], ['discrete', 'discrete'],
                         [['2018-01-01', '2018-01-02'], list(range(168))])

    act_set = ActionSet(attr_set, max_bid=9.99, min_bid=0.01, max_mod=9.0, min_mod=0.1)

    return attr_set, state_set, act_set
Ejemplo n.º 3
0
        def setUp(self):
            from ssa_sim_v2.simulator.modules.auctions.auctions_base_module import AuctionsPoissonModule
            from ssa_sim_v2.simulator.modules.auction_attributes.auction_attributes_base_module import AuctionAttributesModule
            from ssa_sim_v2.simulator.modules.vickrey_auction.vickrey_auction_module import VickreyAuctionModule
            from ssa_sim_v2.simulator.modules.competitive_click_probability.competitive_click_probability_base_module import CompetitiveClickProbabilityTwoClassGeometricModule
            from ssa_sim_v2.simulator.modules.competitive_clicks.competitive_clicks_base_module import CompetitiveClicksBinomialModule
            from ssa_sim_v2.simulator.modules.conversion_rate.conversion_rate_base_module import ConversionRateFlatModule
            from ssa_sim_v2.simulator.modules.conversions.conversions_base_module import ConversionsBinomialModule
            from ssa_sim_v2.simulator.modules.revenue.revenue_base_module import RevenueGammaNoiseModule
            from ssa_sim_v2.simulator.modules.competitive_cpc.competitive_cpc_base_module import CompetitiveCPCVickreyModule

            from ssa_sim_v2.simulator.modules.auctions.auctions_date_how_module import AuctionsDateHoWModule
            from ssa_sim_v2.simulator.modules.auction_attributes.auction_attributes_date_how_module import AuctionAttributesDateHoWModule
            from ssa_sim_v2.simulator.modules.vickrey_auction.vickrey_auction_date_how_module import VickreyAuctionDateHoWModule
            from ssa_sim_v2.simulator.modules.competitive_click_probability.competitive_click_probability_date_how_module import CompetitiveClickProbabilityDateHoWModule
            from ssa_sim_v2.simulator.modules.competitive_clicks.competitive_clicks_date_how_module import CompetitiveClicksDateHoWModule
            from ssa_sim_v2.simulator.modules.conversion_rate.conversion_rate_date_how_module import ConversionRateDateHoWModule
            from ssa_sim_v2.simulator.modules.conversions.conversions_date_how_module import ConversionsDateHoWModule
            from ssa_sim_v2.simulator.modules.revenue.revenue_date_how_module import RevenueDateHoWModule
            from ssa_sim_v2.simulator.modules.competitive_cpc.competitive_cpc_date_how_module import CompetitiveCpcDateHoWModule

            self.seed = 1111

            self.date_from = "2018-01-01"
            self.date_to = "2018-01-02"

            self.tmp_df = pd.DataFrame(np.array(range(24)),
                                       columns=["hour_of_day"])
            self.tmp_df["key"] = 1
            self.dates = pd.DataFrame(pd.date_range(self.date_from,
                                                    self.date_to),
                                      columns=["date"])
            dates_list = self.dates["date"].tolist()
            self.dates["key"] = 1
            self.dates = pd.merge(
                self.dates, self.tmp_df, on=["key"],
                how="left")  # columns: ['date', 'hour_of_day']

            self.dates["hour_of_week"] = pd.to_datetime(self.dates[
                "date"]).dt.dayofweek * 24 + self.dates["hour_of_day"]
            self.dates["date"] = self.dates["date"].dt.strftime("%Y-%m-%d")
            self.dates = self.dates[["date", "hour_of_week"]]

            # Initialize state set
            self.state_set = StateSet(
                ["date", "how"], ["discrete", "discrete"],
                [dates_list, list(range(168))])

            # Initialize attribute set
            names = ['gender', 'age']
            vals = {
                'gender': ['M', 'F', 'U'],
                'age':
                ['0-19', '20-29', '30-39', '40-49', '50-59', '60-69', '70-*']
            }
            self.attr_set = AttrSet(names, vals)

            attr_combinations = self.attr_set.get_all_attr_tuples()

            # Initialize action set
            self.action_set = ActionSet(self.attr_set,
                                        max_bid=9.99,
                                        min_bid=0.01,
                                        max_mod=9.0,
                                        min_mod=0.1)

            def initialize_priors(params, base_class):
                attr_combinations = list(self.attr_set.get_all_attr_tuples())
                priors = self.dates.copy()
                priors.loc[:, "prior"] = pd.Series(
                    [dict.fromkeys(attr_combinations, params)] * len(priors))

                base_classes = self.dates.copy()
                base_classes.loc[:, "base_class"] = base_class

                return priors, base_classes

            # Initialize auctions priors
            module_class = AuctionsPoissonModule
            Params = module_class.Params
            params = Params(auctions=100)
            priors = self.dates.copy()
            priors.loc[:, "prior"] = [{(): params}] * len(priors)
            base_classes = self.dates.copy()
            base_classes.loc[:, "base_class"] = module_class
            self.auctions_priors = priors
            self.auctions_base_classes = base_classes

            # Initialize auction_attributes priors
            module_class = AuctionAttributesModule
            Params = module_class.Params
            params = Params(p=1.0)  # Probabilities are normalized
            self.auction_attributes_priors, self.auction_attributes_base_classes \
                = initialize_priors(params, module_class)

            # Initialize vickrey_auction priors
            module_class = VickreyAuctionModule
            Params = module_class.Params
            params = Params()
            self.vickrey_auction_priors, self.vickrey_auction_base_classes \
                = initialize_priors(params, module_class)

            # Initialize competitive_click_probability priors
            module_class = CompetitiveClickProbabilityTwoClassGeometricModule
            Params = module_class.Params
            params = Params(n_pos=8, p=0.5, q=0.5, r_11=0.6, r_12=0.4, r_2=0.5)
            self.competitive_click_probability_priors, self.competitive_click_probability_base_classes \
                = initialize_priors(params, module_class)

            # Initialize competitive_clicks priors
            module_class = CompetitiveClicksBinomialModule
            Params = module_class.Params
            params = Params(noise_level=0.0, noise_type="multiplicative")
            self.competitive_clicks_priors, self.competitive_clicks_base_classes \
                = initialize_priors(params, module_class)

            # Initialize conversion_rate priors
            module_class = ConversionRateFlatModule
            Params = module_class.Params
            params = Params(cvr=0.02,
                            noise_level=0.0,
                            noise_type="multiplicative")
            self.conversion_rate_priors, self.conversion_rate_base_classes \
                = initialize_priors(params, module_class)

            # Initialize conversions priors
            module_class = ConversionsBinomialModule
            Params = module_class.Params
            params = Params(noise_level=0.0, noise_type="multiplicative")
            self.conversions_priors, self.conversions_base_classes \
                = initialize_priors(params, module_class)

            # Initialize revenue priors
            module_class = RevenueGammaNoiseModule
            Params = module_class.Params
            params = Params(avg_rpv=300.0, noise_level=100.0)
            self.revenue_priors, self.revenue_base_classes = initialize_priors(
                params, module_class)

            # Initialize competitive_cpc priors
            module_class = CompetitiveCPCVickreyModule
            Params = module_class.Params
            params = Params(n_pos=8, fee=0.01)
            self.competitive_cpc_priors, self.competitive_cpc_base_classes = \
                initialize_priors(params, module_class)

            # Module setup for the simulator
            self.mods = \
                {"auctions": AuctionsDateHoWModule(self.auctions_priors,
                                                   self.auctions_base_classes,
                                                   self.seed),
                 "auction_attributes": AuctionAttributesDateHoWModule(self.auction_attributes_priors,
                                                                      self.auction_attributes_base_classes,
                                                                      self.seed),
                 "vickrey_auction": VickreyAuctionDateHoWModule(self.vickrey_auction_priors,
                                                                self.vickrey_auction_base_classes,
                                                                self.seed),
                 "competitive_click_probability": CompetitiveClickProbabilityDateHoWModule(self.competitive_click_probability_priors,
                                                                                           self.competitive_click_probability_base_classes,
                                                                                           self.seed),
                 "competitive_clicks": CompetitiveClicksDateHoWModule(self.competitive_clicks_priors,
                                                                      self.competitive_clicks_base_classes,
                                                                      self.seed),
                 "conversion_rate": ConversionRateDateHoWModule(self.conversion_rate_priors,
                                                                self.conversion_rate_base_classes,
                                                                self.seed),
                 "conversions": ConversionsDateHoWModule(self.conversions_priors,
                                                         self.conversions_base_classes,
                                                         self.seed),
                 "revenue": RevenueDateHoWModule(self.revenue_priors,
                                                 self.revenue_base_classes,
                                                 self.seed),
                 "competitive_cpc": CompetitiveCpcDateHoWModule(self.competitive_cpc_priors,
                                                                self.competitive_cpc_base_classes,
                                                                self.seed)
                 }

            self.simulator = CompetitiveDateHowSimulator(self.state_set,
                                                         self.action_set,
                                                         self.attr_set,
                                                         self.mods,
                                                         self.date_from,
                                                         self.date_to,
                                                         income_share=1.0)
Ejemplo n.º 4
0
class SimpleCompetition(Competition):
    """
    Competition class performing a predefined number of runs on a stationary
    flat scenario for a given set of policies.
    """
    def __init__(self):
        super().__init__()
        self.save_history = True
        self.print_simulator_output = False
        self.processing = "parallel"
        self.num_cores = 4
        self.master_seed = 4444
        self.n_experiment_reps = 3

        self.date_from = None
        self.date_to = None
        self.time_steps_df = pd.DataFrame()
        self.dates_list = []

        self.simulator = None  # type: CompetitiveDateHowSimulator
        self.experiment_specs = []
        self.policy_infos = []

        self.state_set = None
        self.action_set = None
        self.attr_set = None

    def run_competition(self):
        competition_start_dt = datetime.now().strftime("%Y%m%d_%H%M")
        file_data_handler = FileDataHandler()
        root_directory = file_data_handler.get_output_full_path(
            os.path.join(competition_start_dt))

        settings_spec = self._load_settings()
        experiment_specs = self._load_experiment_specs(settings_spec)
        policy_infos = self._load_policies(settings_spec)

        # Initialize seeds

        seed_min = 100000
        seed_max = 999999

        rng = np.random.RandomState(seed=self.master_seed)

        seeds = [{}] * self.n_experiment_reps
        for rep in range(self.n_experiment_reps):
            seeds[rep] = {
                "mod": rng.randint(low=seed_min, high=seed_max),
                "pol": rng.randint(low=seed_min, high=seed_max)
            }

        # Define simulations

        batches = list(product(seeds, experiment_specs))

        # Run simulations

        if self.processing == "serial":

            # Run batch serially
            start_time = timer()
            res_ser = []
            print(
                "Starting to run {} reps of {} simulations with {} time steps serially"
                .format(self.n_experiment_reps, len(experiment_specs),
                        len(self.time_steps_df)))
            # Run batch
            for b in batches:
                temp = self._run_simulation(b, policy_infos,
                                            competition_start_dt)

                res_ser.append(temp)
            results = res_ser

        elif self.processing == "parallel":

            # Run batch in parallel
            import pathos.multiprocessing as mp

            pool = mp.Pool(processes=self.num_cores)
            start_time = timer()
            print(
                "Starting to run {} reps of {} simulations with {} time steps in parallel"
                .format(self.n_experiment_reps, len(experiment_specs),
                        len(self.time_steps_df)))
            res_par = pool.starmap(self._run_simulation,
                                   [(b, policy_infos, competition_start_dt)
                                    for b in batches])
            pool.close()
            pool.join()
            results = res_par

        print(
            "Done running {} reps of {} simulations with {} time steps in {:.2f} minutes"
            .format(self.n_experiment_reps, len(experiment_specs),
                    len(self.time_steps_df), (timer() - start_time) / 60))

        aggregator = ExperimentResultAggregator(root_directory)
        processed_result = aggregator.aggregate_resampled_experiment_result(
            result_list=results,
            rule="1D",
            policy_order=[p["name"] for p in policy_infos],
            agg_save=True)

        visualizer = SummaryExperimentPlotVisualizer(
            root_directory=os.path.join(root_directory, "resampled_1D"),
            chart_directory=os.path.join(root_directory, "charts"),
            experiment_name="competition",
            state_type="hourly")
        visualizer.generate_summary_profit_bar_plots(processed_result,
                                                     save=True)
        visualizer.generate_summary_profit_series_plots(processed_result,
                                                        save=True)

    def _load_settings(self):
        file_data_handler = FileDataHandler()
        settings_spec = file_data_handler.load_spec(os.path.join(""),
                                                    self.settings_spec_name)

        if settings_spec is None:
            sys.exit("Can't load experiment spec")

        self.save_history = settings_spec["save_history"]
        self.print_simulator_output = settings_spec["print_simulator_output"]
        self.processing = settings_spec["processing"]
        self.num_cores = settings_spec["num_cores"]
        self.master_seed = settings_spec["master_seed"]
        self.n_experiment_reps = settings_spec["n_experiment_reps"]

        # Initialize state set
        self.date_from = settings_spec.get("date_from", None)
        self.date_to = settings_spec.get("date_to", None)

        self.time_steps_df, self.dates_list = \
            self._get_time_steps_data(self.date_from, self.date_to)

        self.state_set = StateSet(
            ["date", "how"], ["discrete", "discrete"],
            [self.dates_list, list(range(168))])

        # Initialize attribute set
        names = settings_spec["attributes"]["names"]
        vals = settings_spec["attributes"]["vals"]
        self.attr_set = AttrSet(names, vals)

        # Initialize action set
        self.action_set = ActionSet(self.attr_set,
                                    max_bid=9.99,
                                    min_bid=0.01,
                                    max_mod=9.0,
                                    min_mod=0.1)

        return settings_spec

    def _load_experiment_specs(self, settings_spec):
        experiment_spec_names = settings_spec["experiment_specs"]
        file_data_handler = FileDataHandler()
        for experiment_spec_name in experiment_spec_names:
            experiment_spec = file_data_handler.load_spec(
                os.path.join("ssa_sim_v2", "experiment_specs"),
                "{}".format(experiment_spec_name))

            if experiment_spec is None:
                sys.exit("Can't load experiment spec")

            self.experiment_specs.append({
                "name": experiment_spec_name,
                "spec": experiment_spec
            })

        return self.experiment_specs

    def _load_policies(self, settings_spec):
        self.policy_infos = settings_spec["policies"]
        return self.policy_infos

    def _run_simulation(self, batch, policy_infos, competition_start_dt):
        seed, experiment_spec = batch
        experiment_spec_name = experiment_spec["name"]
        experiment_spec = experiment_spec["spec"]

        file_data_handler = FileDataHandler()
        root_directory = file_data_handler.get_output_full_path(
            os.path.join(competition_start_dt, experiment_spec_name))

        simulator = self._initialize_simulator(experiment_spec, seed["mod"])
        policies = self._initialize_policies(policy_infos, experiment_spec,
                                             seed["pol"])

        saver = ExperimentHistorySaver(root_directory=root_directory,
                                       seed=seed,
                                       experiment_spec=experiment_spec,
                                       policy_infos=policy_infos)

        state = deepcopy(simulator.state)

        while state is not None:

            # Act

            actions = []  # type: List[Action]
            for policy in policies:
                original_state = deepcopy(simulator.state)
                actions.append(policy.act(original_state))
            original_state = deepcopy(simulator.state)

            # Simulator step

            step_results = simulator.step(actions)
            state = simulator.state

            # Learn

            for i in range(len(policies)):
                original_state_copy = deepcopy(original_state)
                policies[i].learn(original_state_copy, step_results[i])

            # Store results

            for i in range(len(policies)):
                saver.save_experiment_iteration(
                    policy_name=policy_infos[i]["name"],
                    policy=policies[i],
                    profit=step_results[i]["info"]["profit_is"],
                    state=original_state.values,
                    action=step_results[i]["action"],
                    effective_action=step_results[i]["effective_action"],
                    info=step_results[i]["info"],
                    attr_info=step_results[i]["attr_info"])

        results = saver.generate_experiment_results(save=self.save_history,
                                                    csv=True)

        return results

    def _initialize_simulator(self, experiment_spec, seed):
        def initialize_priors(params, base_class):
            attr_combinations = list(self.attr_set.get_all_attr_tuples())
            priors = self.time_steps_df.copy()
            priors.loc[:, "prior"] = pd.Series(
                [dict.fromkeys(attr_combinations, params)] * len(priors))

            base_classes = self.time_steps_df.copy()
            base_classes.loc[:, "base_class"] = base_class

            return priors, base_classes

        # Initialize auctions priors
        module_class = AuctionsPoissonModule
        Params = module_class.Params
        params = Params(auctions=1000)
        priors = self.time_steps_df.copy()
        priors.loc[:, "prior"] = [{(): params}] * len(priors)
        base_classes = self.time_steps_df.copy()
        base_classes.loc[:, "base_class"] = module_class
        auctions_priors = priors
        auctions_base_classes = base_classes

        # Initialize auction_attributes priors
        module_class = AuctionAttributesModule
        Params = module_class.Params
        params = Params(p=1.0)  # Probabilities are normalized
        auction_attributes_priors, auction_attributes_base_classes \
            = initialize_priors(params, module_class)

        # Initialize vickrey_auction priors
        module_class = VickreyAuctionModule
        Params = module_class.Params
        params = Params()
        vickrey_auction_priors, vickrey_auction_base_classes \
            = initialize_priors(params, module_class)

        # Initialize competitive_click_probability priors
        module_class = CompetitiveClickProbabilityTwoClassGeometricModule
        Params = module_class.Params
        params = Params(n_pos=8, p=0.5, q=0.5, r_11=0.6, r_12=0.4, r_2=0.5)
        competitive_click_probability_priors, competitive_click_probability_base_classes \
            = initialize_priors(params, module_class)

        # Initialize competitive_clicks priors
        module_class = CompetitiveClicksBinomialModule
        Params = module_class.Params
        params = Params(noise_level=0.0, noise_type="multiplicative")
        competitive_clicks_priors, competitive_clicks_base_classes \
            = initialize_priors(params, module_class)

        # Initialize conversion_rate priors
        module_class = ConversionRateFlatModule
        Params = module_class.Params
        params = Params(cvr=0.02, noise_level=0.0, noise_type="multiplicative")
        conversion_rate_priors, conversion_rate_base_classes \
            = initialize_priors(params, module_class)

        # Initialize conversions priors
        module_class = ConversionsBinomialModule
        Params = module_class.Params
        params = Params(noise_level=0.0, noise_type="multiplicative")
        conversions_priors, conversions_base_classes \
            = initialize_priors(params, module_class)

        # Initialize revenue priors
        module_class = RevenueGammaNoiseModule
        Params = module_class.Params
        params = Params(avg_rpv=300.0, noise_level=100.0)
        revenue_priors, revenue_base_classes = initialize_priors(
            params, module_class)

        # Initialize competitive_cpc priors
        module_class = CompetitiveCPCVickreyModule
        Params = module_class.Params
        params = Params(n_pos=8, fee=0.01)
        competitive_cpc_priors, competitive_cpc_base_classes = \
            initialize_priors(params, module_class)

        # Module setup for the simulator
        modules = \
            {"auctions": AuctionsDateHoWModule(auctions_priors,
                                               auctions_base_classes,
                                               seed),
             "auction_attributes": AuctionAttributesDateHoWModule(auction_attributes_priors,
                                                                  auction_attributes_base_classes,
                                                                  seed),
             "vickrey_auction": VickreyAuctionDateHoWModule(vickrey_auction_priors,
                                                            vickrey_auction_base_classes,
                                                            seed),
             "competitive_click_probability": CompetitiveClickProbabilityDateHoWModule(competitive_click_probability_priors,
                                                                                       competitive_click_probability_base_classes,
                                                                                       seed),
             "competitive_clicks": CompetitiveClicksDateHoWModule(competitive_clicks_priors,
                                                                  competitive_clicks_base_classes,
                                                                  seed),
             "conversion_rate": ConversionRateDateHoWModule(conversion_rate_priors,
                                                            conversion_rate_base_classes,
                                                            seed),
             "conversions": ConversionsDateHoWModule(conversions_priors,
                                                     conversions_base_classes,
                                                     seed),
             "revenue": RevenueDateHoWModule(revenue_priors,
                                             revenue_base_classes,
                                             seed),
             "competitive_cpc": CompetitiveCpcDateHoWModule(competitive_cpc_priors,
                                                            competitive_cpc_base_classes,
                                                            seed)
             }

        simulator = CompetitiveDateHowSimulator(
            self.state_set,
            self.action_set,
            self.attr_set,
            modules,
            self.date_from,
            self.date_to,
            income_share=experiment_spec.get("policy_defaults", {
                "udp": {
                    "income_share": 1.0
                }
            }).get("udp", {
                "income_share": 1.0
            }).get("income_share", 1.0),
            print_trace=self.print_simulator_output)

        return simulator

    def _initialize_policies(self, policy_infos, experiment_spec, seed):
        param_defaults = experiment_spec.get("policy_defaults", {})
        policies = []
        for policy_info in policy_infos:
            params = deepcopy(param_defaults)
            params.update(policy_info["params"])
            policy_class = globals()[policy_info["policy"]]
            if "seed" in params.keys():
                this_seed = params["seed"]
            else:
                this_seed = seed
            policy = policy_class(
                self.state_set,
                self.action_set,
                self.attr_set,
                seed=this_seed,
                save_history=self.save_history)  # type: Policy
            policy.initialize(params)
            policies.append(policy)

        return policies

    def _store_simulation_results(self):
        pass

    def _store_competition_results(self):
        pass

    def _get_time_steps_data(self, date_from, date_to):
        tmp_df = pd.DataFrame(np.array(range(24)), columns=["hour_of_day"])
        tmp_df["key"] = 1
        time_steps_df = pd.DataFrame(pd.date_range(date_from, date_to),
                                     columns=["date"])
        dates_list = time_steps_df["date"].tolist()
        time_steps_df["key"] = 1
        time_steps_df = pd.merge(
            time_steps_df, tmp_df, on=["key"],
            how="left")  # columns: ['date', 'hour_of_day']
        time_steps_df["hour_of_week"] = pd.to_datetime(time_steps_df[
            "date"]).dt.dayofweek * 24 + time_steps_df["hour_of_day"]
        time_steps_df["date"] = time_steps_df["date"].dt.strftime("%Y-%m-%d")
        time_steps_df = time_steps_df[["date", "hour_of_week"]]
        return time_steps_df, dates_list