{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Time-series API Emulator for MLB\nThis script emulates the time-series API of this competition to allow debugging in a local environment.\n\nYou can also emulate the public LB locally instead of submitting your code, since train_updated.csv also contains data for the public LB period.\n\nThis script is inspired by a great notebook by @its7171 at the Riiid competition.\nhttps://www.kaggle.com/its7171/time-series-api-iter-test-emulator","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-07-23T13:20:15.383034Z","iopub.execute_input":"2021-07-23T13:20:15.383365Z","iopub.status.idle":"2021-07-23T13:20:15.399748Z","shell.execute_reply.started":"2021-07-23T13:20:15.383293Z","shell.execute_reply":"2021-07-23T13:20:15.398899Z"}}},{"cell_type":"markdown","source":"## The emulator","metadata":{}},{"cell_type":"code","source":"import os\nimport warnings\nfrom typing import Optional, Tuple\n\nimport pandas as pd\n\n\nclass Environment:\n    def __init__(self,\n                 data_dir: str,\n                 eval_start_day: int,\n                 eval_end_day: Optional[int],\n                 use_updated: bool,\n                 multiple_days_per_iter: bool):\n        warnings.warn('this is mock module for mlb')\n\n        postfix = '_updated' if use_updated else ''\n        \n        # recommend to replace this with pickle, feather etc to speedup preparing data\n        df_train = pd.read_csv(os.path.join(data_dir, f'train{postfix}.csv'))\n\n        players = pd.read_csv(os.path.join(data_dir, 'players.csv'))\n\n        self.players = players[players['playerForTestSetAndFuturePreds'] == True]['playerId'].astype(str)\n        if eval_end_day is not None:\n            self.df_train = df_train.set_index('date').loc[eval_start_day:eval_end_day]\n        else:\n            self.df_train = df_train.set_index('date').loc[eval_start_day:]\n        self.date = self.df_train.index.values\n        self.n_rows = len(self.df_train)\n        self.multiple_days_per_iter = multiple_days_per_iter\n\n        assert self.n_rows > 0, 'no data to emulate'\n\n    def predict(self, df: pd.DataFrame) -> None:\n        # if you want to emulate public LB, store your prediction here and calculate MAE\n        pass\n\n    def iter_test(self) -> Tuple[pd.DataFrame, pd.DataFrame]:\n        if self.multiple_days_per_iter:\n            for i in range(self.n_rows // 2):\n                date1 = self.date[2 * i]\n                date2 = self.date[2 * i + 1]\n                sample_sub1 = self._make_sample_sub(date1)\n                sample_sub2 = self._make_sample_sub(date2)\n                sample_sub = pd.concat([sample_sub1, sample_sub2]).reset_index(drop=True)\n                df = self.df_train.loc[date1:date2]\n\n                yield df, sample_sub.set_index('date')\n        else:\n            for i in range(self.n_rows):\n                date = self.date[i]\n                sample_sub = self._make_sample_sub(date)\n                df = self.df_train.loc[date:date]\n\n                yield df, sample_sub.set_index('date')\n\n    def _make_sample_sub(self, date: int) -> pd.DataFrame:\n        next_day = (pd.to_datetime(date, format='%Y%m%d') + pd.to_timedelta(1, 'd')).strftime('%Y%m%d')\n        sample_sub = pd.DataFrame()\n        sample_sub['date_playerId'] = next_day + '_' + self.players\n        sample_sub['target1'] = 0\n        sample_sub['target2'] = 0\n        sample_sub['target3'] = 0\n        sample_sub['target4'] = 0\n        sample_sub['date'] = date\n        return sample_sub\n\n\nclass MLBEmulator:\n    def __init__(self,\n                 data_dir: str = '../input/mlb-player-digital-engagement-forecasting',\n                 eval_start_day: int = 20210401,\n                 eval_end_day: Optional[int] = 20210430,\n                 use_updated: bool = True,\n                 multiple_days_per_iter: bool = False):\n        self.data_dir = data_dir\n        self.eval_start_day = eval_start_day\n        self.eval_end_day = eval_end_day\n        self.use_updated = use_updated\n        self.multiple_days_per_iter = multiple_days_per_iter\n\n    def make_env(self) -> Environment:\n        return Environment(self.data_dir,\n                           self.eval_start_day,\n                           self.eval_end_day,\n                           self.use_updated,\n                           self.multiple_days_per_iter)\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## How to use\nAll you need to do is to replace importing the `mlb` module with an instance of `MLBEmulator`.","metadata":{}},{"cell_type":"code","source":"emulation_mode = True\n\nif emulation_mode:\n    mlb = MLBEmulator(eval_start_day=20210701, eval_end_day=20210730)\nelse:\n    import mlb","metadata":{"execution":{"iopub.status.busy":"2021-07-23T13:20:15.506975Z","iopub.execute_input":"2021-07-23T13:20:15.507253Z","iopub.status.idle":"2021-07-23T13:20:15.520926Z","shell.execute_reply.started":"2021-07-23T13:20:15.507225Z","shell.execute_reply":"2021-07-23T13:20:15.51999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"env = mlb.make_env()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for n, (test_df, sample_prediction_df) in enumerate(env.iter_test()):\n    display(test_df)\n    display(sample_prediction_df)","metadata":{"execution":{"iopub.status.busy":"2021-07-23T13:30:51.506971Z","iopub.execute_input":"2021-07-23T13:30:51.507524Z","iopub.status.idle":"2021-07-23T13:30:52.393929Z","shell.execute_reply.started":"2021-07-23T13:30:51.507485Z","shell.execute_reply":"2021-07-23T13:30:52.393301Z"},"trusted":true},"execution_count":null,"outputs":[]}]}