{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"colab":{"provenance":[{"file_id":"https://storage.googleapis.com/kaggle-colab-exported-notebooks/baseline-9b91a0e3-79c0-41c6-ac3a-cb52246ce672.ipynb?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=gcp-kaggle-com%40kaggle-161607.iam.gserviceaccount.com/20240311/auto/storage/goog4_request&X-Goog-Date=20240311T140337Z&X-Goog-Expires=259200&X-Goog-SignedHeaders=host&X-Goog-Signature=9adfbe2ed572d128d069f327e194f24edf589c05e0471d65dbe890f137537652e98ce8d45363ad09b50780386f7f9ce451a1418af036777740866d889b5a82c00cb2de001da77f3044dcd45776805322668e799ae76d802eff0b02cfc78880732646e5dc7f85b135ef4f32cecd03031d2c3887a526c76d73dcf8c4edc286ea02e2960525ae8ab88d4d01728f36759e8c56e8c9a643a43450c97d4f281676c0377e125cfb7e9b6c0c60dc31f054b4051904181f226948934accb169a985ab794aba4ea32212e06cf24e65184ae3a0a2c97c79036bde593a77ee487b90acb43a659ca29e64389ccb5bea19ec912326920fa6955a391e5012a5054efb9b61ea8e64","timestamp":1710165846930}]},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":72284,"databundleVersionId":7919275,"sourceType":"competition"}],"dockerImageVersionId":30664,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"\n# IMPORTANT: RUN THIS CELL IN ORDER TO IMPORT YOUR KAGGLE DATA SOURCES\n# TO THE CORRECT LOCATION (/kaggle/input) IN YOUR NOTEBOOK,\n# THEN FEEL FREE TO DELETE THIS CELL.\n# NOTE: THIS NOTEBOOK ENVIRONMENT DIFFERS FROM KAGGLE'S PYTHON\n# ENVIRONMENT SO THERE MAY BE MISSING LIBRARIES USED BY YOUR\n# NOTEBOOK.\n\nimport os\nimport sys\nfrom tempfile import NamedTemporaryFile\nfrom urllib.request import urlopen\nfrom urllib.parse import unquote, urlparse\nfrom urllib.error import HTTPError\nfrom zipfile import ZipFile\nimport tarfile\nimport shutil\n\nCHUNK_SIZE = 40960\nDATA_SOURCE_MAPPING = 'bi-ml-competition-2023:https%3A%2F%2Fstorage.googleapis.com%2Fkaggle-competitions-data%2Fkaggle-v2%2F49431%2F5228520%2Fbundle%2Farchive.zip%3FX-Goog-Algorithm%3DGOOG4-RSA-SHA256%26X-Goog-Credential%3Dgcp-kaggle-com%2540kaggle-161607.iam.gserviceaccount.com%252F20240311%252Fauto%252Fstorage%252Fgoog4_request%26X-Goog-Date%3D20240311T140336Z%26X-Goog-Expires%3D259200%26X-Goog-SignedHeaders%3Dhost%26X-Goog-Signature%3D0439a6647118ef93fac3b8d2f72135cfd433fa2ff3d0992a9bb24360bf7e359ce6346e0acb775939df8562e3d5ce4efb67bf65176232bd7293a8398aa85ebc4751da621a3cacef50ff5146703ffdff98d954899ee2baa8cf917f55500c0917d2f532b56b4417aa1ec82004552736d80fdc551ea663815efdb030039529fb4bbe7f4cfc7a9d859ef8ec998a3d5e8792b96eedf04e359fa2cc87bc5a691514009a2b428db00d65db322390551a6651afabef44689b1d40bfd1670fa5ff224f377ce4821e5f3b4f1a39b14007b4a62c1855d6e2f7348d17370c1dca2a4a17aa19cfeb7286b7427a95c9ca95d1190483075c33f893db9fc8526f59e53fee57f34673'\n\nKAGGLE_INPUT_PATH='/kaggle/input'\nKAGGLE_WORKING_PATH='/kaggle/working'\nKAGGLE_SYMLINK='kaggle'\n\n!umount /kaggle/input/ 2> /dev/null\nshutil.rmtree('/kaggle/input', ignore_errors=True)\nos.makedirs(KAGGLE_INPUT_PATH, 0o777, exist_ok=True)\nos.makedirs(KAGGLE_WORKING_PATH, 0o777, exist_ok=True)\n\ntry:\n  os.symlink(KAGGLE_INPUT_PATH, os.path.join(\"..\", 'input'), target_is_directory=True)\nexcept FileExistsError:\n  pass\ntry:\n  os.symlink(KAGGLE_WORKING_PATH, os.path.join(\"..\", 'working'), target_is_directory=True)\nexcept FileExistsError:\n  pass\n\nfor data_source_mapping in DATA_SOURCE_MAPPING.split(','):\n    directory, download_url_encoded = data_source_mapping.split(':')\n    download_url = unquote(download_url_encoded)\n    filename = urlparse(download_url).path\n    destination_path = os.path.join(KAGGLE_INPUT_PATH, directory)\n    try:\n        with urlopen(download_url) as fileres, NamedTemporaryFile() as tfile:\n            total_length = fileres.headers['content-length']\n            print(f'Downloading {directory}, {total_length} bytes compressed')\n            dl = 0\n            data = fileres.read(CHUNK_SIZE)\n            while len(data) > 0:\n                dl += len(data)\n                tfile.write(data)\n                done = int(50 * dl / int(total_length))\n                sys.stdout.write(f\"\\r[{'=' * done}{' ' * (50-done)}] {dl} bytes downloaded\")\n                sys.stdout.flush()\n                data = fileres.read(CHUNK_SIZE)\n            if filename.endswith('.zip'):\n              with ZipFile(tfile) as zfile:\n                zfile.extractall(destination_path)\n            else:\n              with tarfile.open(tfile.name) as tarfile:\n                tarfile.extractall(destination_path)\n            print(f'\\nDownloaded and uncompressed: {directory}')\n    except HTTPError as e:\n        print(f'Failed to load (likely expired) {download_url} to path {destination_path}')\n        continue\n    except OSError as e:\n        print(f'Failed to load {download_url} to path {destination_path}')\n        continue\n\nprint('Data source import complete.')\n","metadata":{"id":"uhLqnaui04BG","execution":{"iopub.status.busy":"2024-03-11T14:07:09.992746Z","iopub.execute_input":"2024-03-11T14:07:09.993109Z","iopub.status.idle":"2024-03-11T14:07:29.804168Z","shell.execute_reply.started":"2024-03-11T14:07:09.993079Z","shell.execute_reply":"2024-03-11T14:07:29.803122Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# <center> Предсказание победителя в Dota 2\n<center> <img src=\"https://meduza.io/impro/YnJZAHUW6WHz_JQm1uRPkTql_qAhbfxt3oFJLGH7CJg/fill/980/0/ce/1/aHR0cHM6Ly9tZWR1/emEuaW8vaW1hZ2Uv/YXR0YWNobWVudHMv/aW1hZ2VzLzAwNy8x/NTcvNjk1L29yaWdp/bmFsL0tMVThLbUti/ZG5pSzlibDA0Wmlw/WXcuanBn.webp\" width=\"700\" height=\"700\">","metadata":{"papermill":{"duration":0.044486,"end_time":"2022-02-13T23:28:22.423626","exception":false,"start_time":"2022-02-13T23:28:22.37914","status":"completed"},"tags":[],"id":"HfkYZ3AN04BJ"}},{"cell_type":"markdown","source":"[Почитать подбробнее](https://meduza.io/feature/2021/10/19/rossiyskaya-komanda-vyigrala-chempionat-mira-po-dota-2-i-poluchila-18-millionov-dollarov-postoyte-otkuda-takie-dengi-neuzheli-igrat-v-dotu-tak-slozhno)","metadata":{"papermill":{"duration":0.042953,"end_time":"2022-02-13T23:28:22.51031","exception":false,"start_time":"2022-02-13T23:28:22.467357","status":"completed"},"tags":[],"id":"svZh95LZ04BK"}},{"cell_type":"markdown","source":"#### [Оригинальная статья](https://arxiv.org/pdf/2106.01782.pdf)\n    \n### Начало\n\nПосмотрим на готовые признаки и сделаем первую посылку.\n\n1. [Описание данных](#Описание-данных)\n2. [Описание признаков](#Описание-признаков)\n3. [Наша первая модель](#Наша-первая-модель)\n4. [Посылка](#Посылка)\n\n### Первые шаги на пути в датасайенс\n\n5. [Кросс-валидация](#Кросс-валидация)\n6. [Что есть в json файлах?](#Что-есть-в-json-файлах?)\n7. [Feature engineering](#Feature-engineering)","metadata":{"papermill":{"duration":0.042954,"end_time":"2022-02-13T23:28:22.59833","exception":false,"start_time":"2022-02-13T23:28:22.555376","status":"completed"},"tags":[],"id":"l9Ks3PrA04BK"}},{"cell_type":"markdown","source":"### Импорты","metadata":{"papermill":{"duration":0.045141,"end_time":"2022-02-13T23:28:22.688388","exception":false,"start_time":"2022-02-13T23:28:22.643247","status":"completed"},"tags":[],"id":"KXWlzyH104BL"}},{"cell_type":"code","source":"import os\nimport json\nimport pandas as pd\nimport datetime\nimport warnings\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split, ShuffleSplit, cross_val_score\nfrom sklearn.ensemble import RandomForestClassifier\nfrom sklearn.metrics import roc_auc_score, accuracy_score\n\n%matplotlib inline","metadata":{"papermill":{"duration":1.526998,"end_time":"2022-02-13T23:28:24.258607","exception":false,"start_time":"2022-02-13T23:28:22.731609","status":"completed"},"tags":[],"id":"OAN8tYgU04BL","execution":{"iopub.status.busy":"2024-03-11T14:07:59.110261Z","iopub.execute_input":"2024-03-11T14:07:59.110629Z","iopub.status.idle":"2024-03-11T14:08:00.627799Z","shell.execute_reply.started":"2024-03-11T14:07:59.110593Z","shell.execute_reply":"2024-03-11T14:08:00.626324Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SEED = 10801\nsns.set_style(style=\"whitegrid\")\nplt.rcParams[\"figure.figsize\"] = 12, 8\nwarnings.filterwarnings(\"ignore\")","metadata":{"papermill":{"duration":0.051811,"end_time":"2022-02-13T23:28:24.354647","exception":false,"start_time":"2022-02-13T23:28:24.302836","status":"completed"},"tags":[],"id":"gLjgaTtL04BL","execution":{"iopub.status.busy":"2024-03-11T14:08:00.629481Z","iopub.execute_input":"2024-03-11T14:08:00.629987Z","iopub.status.idle":"2024-03-11T14:08:00.635349Z","shell.execute_reply.started":"2024-03-11T14:08:00.629956Z","shell.execute_reply":"2024-03-11T14:08:00.634465Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <left>Описание данных\n\nФайлы:\n\n- `sample_submission.csv`: пример файла-посылки\n- `train_raw_data.jsonl`, `test_raw_data.jsonl`: \"сырые\" данные\n- `train_data.csv`, `test_data.csv`: признаки, созданные авторами\n- `train_targets.csv`: результаты тренировочных игр","metadata":{"papermill":{"duration":0.042707,"end_time":"2022-02-13T23:28:24.441767","exception":false,"start_time":"2022-02-13T23:28:24.39906","status":"completed"},"tags":[],"id":"X4WIvaOF04BL"}},{"cell_type":"markdown","source":"## <left>Описание признаков\n    \nНабор простых признаков, описывающих игроков и команды в целом","metadata":{"papermill":{"duration":0.042685,"end_time":"2022-02-13T23:28:24.527617","exception":false,"start_time":"2022-02-13T23:28:24.484932","status":"completed"},"tags":[],"id":"6X7awb9s04BM"}},{"cell_type":"code","source":"PATH_TO_DATA = \"/kaggle/input/copy-of-23-24-ml/\"\n\ndf_train_features = pd.read_csv(os.path.join(PATH_TO_DATA,\n                                             \"train_data.csv\"),\n                                    index_col=\"match_id_hash\")\ndf_train_targets = pd.read_csv(os.path.join(PATH_TO_DATA,\n                                            \"train_targets.csv\"),\n                                   index_col=\"match_id_hash\")","metadata":{"papermill":{"duration":1.383765,"end_time":"2022-02-13T23:28:25.955912","exception":false,"start_time":"2022-02-13T23:28:24.572147","status":"completed"},"tags":[],"id":"X-ENehsH04BM","execution":{"iopub.status.busy":"2024-03-11T14:10:08.119486Z","iopub.execute_input":"2024-03-11T14:10:08.119913Z","iopub.status.idle":"2024-03-11T14:10:08.666901Z","shell.execute_reply.started":"2024-03-11T14:10:08.119883Z","shell.execute_reply":"2024-03-11T14:10:08.665237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_features.shape","metadata":{"papermill":{"duration":0.055919,"end_time":"2022-02-13T23:28:26.055573","exception":false,"start_time":"2022-02-13T23:28:25.999654","status":"completed"},"tags":[],"id":"nGy8OmUE04BM","execution":{"iopub.status.busy":"2024-03-11T14:10:09.638923Z","iopub.execute_input":"2024-03-11T14:10:09.639406Z","iopub.status.idle":"2024-03-11T14:10:09.647419Z","shell.execute_reply.started":"2024-03-11T14:10:09.639374Z","shell.execute_reply":"2024-03-11T14:10:09.645937Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_features.head()","metadata":{"papermill":{"duration":0.073611,"end_time":"2022-02-13T23:28:26.173793","exception":false,"start_time":"2022-02-13T23:28:26.100182","status":"completed"},"tags":[],"id":"SD7rpkYg04BM","execution":{"iopub.status.busy":"2024-03-11T14:10:10.518089Z","iopub.execute_input":"2024-03-11T14:10:10.518476Z","iopub.status.idle":"2024-03-11T14:10:10.551138Z","shell.execute_reply.started":"2024-03-11T14:10:10.518444Z","shell.execute_reply":"2024-03-11T14:10:10.549599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Имеем ~32 тысячи наблюдений, каждое из которых характеризуется уникальным `match_id_hash` (захэшированное id матча), и 245 признаков. `game_time` показывает момент времени, в который получены эти данные. То есть по сути это не длительность самого матча, а например, его середина, таким образом, в итоге мы сможем получить модель, которая будет предсказывать вероятность победы каждой из команд в течение матча (хорошо подходит для букмекеров).","metadata":{"papermill":{"duration":0.043707,"end_time":"2022-02-13T23:28:26.26179","exception":false,"start_time":"2022-02-13T23:28:26.218083","status":"completed"},"tags":[],"id":"UTQCmaAM04BM"}},{"cell_type":"markdown","source":"Нас интересует поле `radiant_win` (так называется одна из команд, вторая - dire). Остальные колоки здесь по сути получены из \"будущего\" и есть только для тренировочных данных, поэтому на них можно просто посмотреть).","metadata":{"papermill":{"duration":0.043619,"end_time":"2022-02-13T23:28:26.350788","exception":false,"start_time":"2022-02-13T23:28:26.307169","status":"completed"},"tags":[],"id":"u8t4RnnV04BM"}},{"cell_type":"code","source":"df_train_targets.head()","metadata":{"papermill":{"duration":0.059594,"end_time":"2022-02-13T23:28:26.454584","exception":false,"start_time":"2022-02-13T23:28:26.39499","status":"completed"},"tags":[],"id":"8NR2kzUI04BN","execution":{"iopub.status.busy":"2024-03-11T14:10:15.118270Z","iopub.execute_input":"2024-03-11T14:10:15.118646Z","iopub.status.idle":"2024-03-11T14:10:15.132252Z","shell.execute_reply.started":"2024-03-11T14:10:15.118618Z","shell.execute_reply":"2024-03-11T14:10:15.130989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <left>Наша первая модель","metadata":{"papermill":{"duration":0.046788,"end_time":"2022-02-13T23:28:26.547845","exception":false,"start_time":"2022-02-13T23:28:26.501057","status":"completed"},"tags":[],"id":"pNypQlel04BN"}},{"cell_type":"code","source":"X = df_train_features.values\ny = df_train_targets[\"radiant_win\"].values.astype(\"int8\")","metadata":{"papermill":{"duration":0.078234,"end_time":"2022-02-13T23:28:26.672769","exception":false,"start_time":"2022-02-13T23:28:26.594535","status":"completed"},"tags":[],"id":"KtNJF78e04BN","execution":{"iopub.status.busy":"2024-03-11T14:13:33.691245Z","iopub.execute_input":"2024-03-11T14:13:33.691720Z","iopub.status.idle":"2024-03-11T14:13:33.708110Z","shell.execute_reply.started":"2024-03-11T14:13:33.691688Z","shell.execute_reply":"2024-03-11T14:13:33.706537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train, X_valid, y_train, y_valid = train_test_split(X, y,\n                                                      test_size=0.3,\n                                                      random_state=SEED)","metadata":{"papermill":{"duration":0.152481,"end_time":"2022-02-13T23:28:26.871414","exception":false,"start_time":"2022-02-13T23:28:26.718933","status":"completed"},"tags":[],"id":"tuKrE8cu04BN","execution":{"iopub.status.busy":"2024-03-11T14:13:38.238720Z","iopub.execute_input":"2024-03-11T14:13:38.239291Z","iopub.status.idle":"2024-03-11T14:13:38.311454Z","shell.execute_reply.started":"2024-03-11T14:13:38.239261Z","shell.execute_reply":"2024-03-11T14:13:38.310402Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Обучим случайный лес","metadata":{"papermill":{"duration":0.04485,"end_time":"2022-02-13T23:28:26.961156","exception":false,"start_time":"2022-02-13T23:28:26.916306","status":"completed"},"tags":[],"id":"1k-DA3N204BN"}},{"cell_type":"code","source":"%%time\nrf_model = RandomForestClassifier(n_estimators=300, max_depth=7, n_jobs=-1, random_state=SEED)\nrf_model.fit(X_train, y_train)","metadata":{"papermill":{"duration":9.067224,"end_time":"2022-02-13T23:28:36.073116","exception":false,"start_time":"2022-02-13T23:28:27.005892","status":"completed"},"tags":[],"id":"2JMADLBO04BN","execution":{"iopub.status.busy":"2024-03-11T14:13:40.498115Z","iopub.execute_input":"2024-03-11T14:13:40.498762Z","iopub.status.idle":"2024-03-11T14:13:49.360938Z","shell.execute_reply.started":"2024-03-11T14:13:40.498731Z","shell.execute_reply":"2024-03-11T14:13:49.359378Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Сделаем предсказания и оценим качество на отложенной части данных","metadata":{"papermill":{"duration":0.045583,"end_time":"2022-02-13T23:28:36.165966","exception":false,"start_time":"2022-02-13T23:28:36.120383","status":"completed"},"tags":[],"id":"5DdGfh7e04BN"}},{"cell_type":"code","source":"y_pred = rf_model.predict_proba(X_valid)[:, 1]","metadata":{"papermill":{"duration":0.362593,"end_time":"2022-02-13T23:28:36.574368","exception":false,"start_time":"2022-02-13T23:28:36.211775","status":"completed"},"tags":[],"id":"exy3EIb804BN","execution":{"iopub.status.busy":"2024-03-11T14:13:57.039121Z","iopub.execute_input":"2024-03-11T14:13:57.039491Z","iopub.status.idle":"2024-03-11T14:13:57.270993Z","shell.execute_reply.started":"2024-03-11T14:13:57.039462Z","shell.execute_reply":"2024-03-11T14:13:57.270269Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"valid_score = roc_auc_score(y_valid, y_pred)\nprint(\"ROC-AUC score на отложенной части:\", valid_score)","metadata":{"papermill":{"duration":0.060422,"end_time":"2022-02-13T23:28:36.680786","exception":false,"start_time":"2022-02-13T23:28:36.620364","status":"completed"},"tags":[],"id":"gLuhtjM704BN","execution":{"iopub.status.busy":"2024-03-11T14:13:59.170358Z","iopub.execute_input":"2024-03-11T14:13:59.170690Z","iopub.status.idle":"2024-03-11T14:13:59.186270Z","shell.execute_reply.started":"2024-03-11T14:13:59.170664Z","shell.execute_reply":"2024-03-11T14:13:59.185629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Посмотрим на accuracy:","metadata":{"papermill":{"duration":0.045999,"end_time":"2022-02-13T23:28:36.773926","exception":false,"start_time":"2022-02-13T23:28:36.727927","status":"completed"},"tags":[],"id":"EltQrkXD04BN"}},{"cell_type":"code","source":"valid_accuracy = accuracy_score(y_valid, y_pred > 0.5)\nprint(\"Accuracy score (p > 0.5) на отложенной части:\", valid_accuracy)","metadata":{"papermill":{"duration":0.057673,"end_time":"2022-02-13T23:28:36.877714","exception":false,"start_time":"2022-02-13T23:28:36.820041","status":"completed"},"tags":[],"id":"Hna5htPn04BN","execution":{"iopub.status.busy":"2024-03-11T14:14:03.058059Z","iopub.execute_input":"2024-03-11T14:14:03.058442Z","iopub.status.idle":"2024-03-11T14:14:03.065371Z","shell.execute_reply.started":"2024-03-11T14:14:03.058410Z","shell.execute_reply":"2024-03-11T14:14:03.064055Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <left>Посылка","metadata":{"papermill":{"duration":0.046013,"end_time":"2022-02-13T23:28:36.970038","exception":false,"start_time":"2022-02-13T23:28:36.924025","status":"completed"},"tags":[],"id":"m_KGUwlP04BO"}},{"cell_type":"code","source":"df_test_features = pd.read_csv(os.path.join(PATH_TO_DATA, \"test_data.csv\"),\n                                   index_col=\"match_id_hash\")\n\nX_test = df_test_features.values\ny_test_pred = rf_model.predict_proba(X_test)[:, 1]\n\ndf_submission = pd.DataFrame({\"radiant_win_prob\": y_test_pred},\n                                 index=df_test_features.index)","metadata":{"papermill":{"duration":0.573434,"end_time":"2022-02-13T23:28:37.589831","exception":false,"start_time":"2022-02-13T23:28:37.016397","status":"completed"},"tags":[],"id":"gjdXWO8-04BO","execution":{"iopub.status.busy":"2024-03-11T14:17:04.379097Z","iopub.execute_input":"2024-03-11T14:17:04.379458Z","iopub.status.idle":"2024-03-11T14:17:04.811987Z","shell.execute_reply.started":"2024-03-11T14:17:04.379430Z","shell.execute_reply":"2024-03-11T14:17:04.809976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_filename = \"submission_{}.csv\".format(\n    datetime.datetime.now().strftime(\"%Y-%m-%d_%H-%M-%S\"))\ndf_submission.to_csv(submission_filename)\nprint(\"Файл посылки сохранен, как: {}\".format(submission_filename))","metadata":{"papermill":{"duration":0.09114,"end_time":"2022-02-13T23:28:37.732839","exception":false,"start_time":"2022-02-13T23:28:37.641699","status":"completed"},"tags":[],"id":"4BlCPPn204BO","execution":{"iopub.status.busy":"2024-03-11T14:18:19.531198Z","iopub.execute_input":"2024-03-11T14:18:19.531594Z","iopub.status.idle":"2024-03-11T14:18:19.556545Z","shell.execute_reply.started":"2024-03-11T14:18:19.531563Z","shell.execute_reply":"2024-03-11T14:18:19.555532Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <left>Кросс-валидация","metadata":{"papermill":{"duration":0.046122,"end_time":"2022-02-13T23:28:37.825794","exception":false,"start_time":"2022-02-13T23:28:37.779672","status":"completed"},"tags":[],"id":"CMeUr4xR04BO"}},{"cell_type":"markdown","source":"Во многих случаях кросс-валидация оказывается лучше простого разбиения на test и train. Воспользуемся `ShuffleSplit` чтобы создать 5 70%/30% наборов данных.","metadata":{"papermill":{"duration":0.047147,"end_time":"2022-02-13T23:28:37.919675","exception":false,"start_time":"2022-02-13T23:28:37.872528","status":"completed"},"tags":[],"id":"uabPsoTI04BO"}},{"cell_type":"code","source":"cv = ShuffleSplit(n_splits=5, test_size=0.3, random_state=SEED)","metadata":{"papermill":{"duration":0.054303,"end_time":"2022-02-13T23:28:38.021177","exception":false,"start_time":"2022-02-13T23:28:37.966874","status":"completed"},"tags":[],"id":"xl5vFaaY04BO","execution":{"iopub.status.busy":"2024-03-11T14:18:26.338942Z","iopub.execute_input":"2024-03-11T14:18:26.339342Z","iopub.status.idle":"2024-03-11T14:18:26.344746Z","shell.execute_reply.started":"2024-03-11T14:18:26.339312Z","shell.execute_reply":"2024-03-11T14:18:26.343612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nrf_model = RandomForestClassifier(n_estimators=300, max_depth=7, n_jobs=-1, random_state=SEED)\ncv_scores_rf = cross_val_score(rf_model, X, y, cv=cv, scoring=\"roc_auc\")","metadata":{"papermill":{"duration":54.652614,"end_time":"2022-02-13T23:29:32.721125","exception":false,"start_time":"2022-02-13T23:28:38.068511","status":"completed"},"tags":[],"id":"qnbl2Iyv04BO","execution":{"iopub.status.busy":"2024-03-11T14:18:27.629794Z","iopub.execute_input":"2024-03-11T14:18:27.630144Z","iopub.status.idle":"2024-03-11T14:19:13.358447Z","shell.execute_reply.started":"2024-03-11T14:18:27.630115Z","shell.execute_reply":"2024-03-11T14:19:13.357074Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cv_scores_rf","metadata":{"papermill":{"duration":0.056037,"end_time":"2022-02-13T23:29:32.824411","exception":false,"start_time":"2022-02-13T23:29:32.768374","status":"completed"},"tags":[],"id":"7rsS0eiV04BO","execution":{"iopub.status.busy":"2024-03-11T14:19:13.362394Z","iopub.execute_input":"2024-03-11T14:19:13.362847Z","iopub.status.idle":"2024-03-11T14:19:13.370110Z","shell.execute_reply.started":"2024-03-11T14:19:13.362810Z","shell.execute_reply":"2024-03-11T14:19:13.368541Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Среднее значение ROC-AUC на кросс-валидации: {cv_scores_rf.mean()}\")","metadata":{"papermill":{"duration":0.056776,"end_time":"2022-02-13T23:29:32.928669","exception":false,"start_time":"2022-02-13T23:29:32.871893","status":"completed"},"tags":[],"id":"9oM-VxeZ04BO","execution":{"iopub.status.busy":"2024-03-11T14:19:13.371745Z","iopub.execute_input":"2024-03-11T14:19:13.372329Z","iopub.status.idle":"2024-03-11T14:19:13.382965Z","shell.execute_reply.started":"2024-03-11T14:19:13.372296Z","shell.execute_reply":"2024-03-11T14:19:13.381740Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## <left>Что есть в json файлах?","metadata":{"papermill":{"duration":0.04757,"end_time":"2022-02-13T23:29:33.025145","exception":false,"start_time":"2022-02-13T23:29:32.977575","status":"completed"},"tags":[],"id":"Y5qLxRfG04BO"}},{"cell_type":"markdown","source":"Описание сырых данных можно найти в `train_matches.jsonl` и `test_matches.jsonl`. Каждый файл содержит одну запись для каждого матча в [JSON](https://en.wikipedia.org/wiki/JSON) формате. Его легко превратить в питоновский объект при помощи метода `json.loads`.","metadata":{"papermill":{"duration":0.048776,"end_time":"2022-02-13T23:29:33.122475","exception":false,"start_time":"2022-02-13T23:29:33.073699","status":"completed"},"tags":[],"id":"3OaNn5wS04BO"}},{"cell_type":"code","source":"with open(os.path.join(PATH_TO_DATA, \"train_raw_data.jsonl\")) as fin:\n    # прочтем 419 строку\n    for i in range(419):\n        line = fin.readline()\n\n    # переведем JSON в питоновский словарь\n    match = json.loads(line)","metadata":{"papermill":{"duration":0.514659,"end_time":"2022-02-13T23:29:33.685074","exception":false,"start_time":"2022-02-13T23:29:33.170415","status":"completed"},"tags":[],"id":"suiICQsv04BO","execution":{"iopub.status.busy":"2024-03-11T14:19:43.378132Z","iopub.execute_input":"2024-03-11T14:19:43.378606Z","iopub.status.idle":"2024-03-11T14:19:43.767545Z","shell.execute_reply.started":"2024-03-11T14:19:43.378574Z","shell.execute_reply":"2024-03-11T14:19:43.765710Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"player = match[\"players\"][9]\nplayer[\"kills\"], player[\"deaths\"], player[\"assists\"]","metadata":{"papermill":{"duration":0.057975,"end_time":"2022-02-13T23:29:33.792713","exception":false,"start_time":"2022-02-13T23:29:33.734738","status":"completed"},"tags":[],"id":"DPdciVYq04BP","execution":{"iopub.status.busy":"2024-03-11T14:19:48.718432Z","iopub.execute_input":"2024-03-11T14:19:48.718829Z","iopub.status.idle":"2024-03-11T14:19:48.727435Z","shell.execute_reply.started":"2024-03-11T14:19:48.718798Z","shell.execute_reply":"2024-03-11T14:19:48.726192Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"KDA - может быть неплохим признаком, этот показатель считается как:\n    \n<center>$KDA = \\frac{K + A}{D}$","metadata":{"papermill":{"duration":0.047795,"end_time":"2022-02-13T23:29:33.888962","exception":false,"start_time":"2022-02-13T23:29:33.841167","status":"completed"},"tags":[],"id":"am-oibE204BP"}},{"cell_type":"markdown","source":"Информация о количестве использованных способностей:","metadata":{"papermill":{"duration":0.047726,"end_time":"2022-02-13T23:29:33.984909","exception":false,"start_time":"2022-02-13T23:29:33.937183","status":"completed"},"tags":[],"id":"iSNh43qe04BW"}},{"cell_type":"code","source":"player[\"ability_uses\"]","metadata":{"papermill":{"duration":0.058567,"end_time":"2022-02-13T23:29:34.091868","exception":false,"start_time":"2022-02-13T23:29:34.033301","status":"completed"},"tags":[],"id":"YdFfusiX04BW","execution":{"iopub.status.busy":"2024-03-11T14:20:03.516123Z","iopub.execute_input":"2024-03-11T14:20:03.516539Z","iopub.status.idle":"2024-03-11T14:20:03.523546Z","shell.execute_reply.started":"2024-03-11T14:20:03.516485Z","shell.execute_reply":"2024-03-11T14:20:03.521427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i, player in enumerate(match[\"players\"]):\n    plt.plot(player[\"times\"], player[\"xp_t\"], label=str(i+1))\n\nplt.legend()\nplt.xlabel(\"Time, s\")\nplt.ylabel(\"XP\")\nplt.title(\"XP change for all players\");","metadata":{"papermill":{"duration":0.497079,"end_time":"2022-02-13T23:29:34.637657","exception":false,"start_time":"2022-02-13T23:29:34.140578","status":"completed"},"tags":[],"id":"I6zjkRpj04BW","execution":{"iopub.status.busy":"2024-03-11T14:20:52.017980Z","iopub.execute_input":"2024-03-11T14:20:52.018340Z","iopub.status.idle":"2024-03-11T14:20:52.462759Z","shell.execute_reply.started":"2024-03-11T14:20:52.018311Z","shell.execute_reply":"2024-03-11T14:20:52.461381Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Сделаем чтение файла с сырыми данными и добавление новых признаков удобным","metadata":{"papermill":{"duration":0.052753,"end_time":"2022-02-13T23:29:34.742623","exception":false,"start_time":"2022-02-13T23:29:34.68987","status":"completed"},"tags":[],"id":"242fnSSE04BW"}},{"cell_type":"markdown","source":"В этот раз для чтение `json` файлов лучше использовать библиотеку `ujson`, иначе все будет слишком долго :(","metadata":{"papermill":{"duration":0.051195,"end_time":"2022-02-13T23:29:34.845611","exception":false,"start_time":"2022-02-13T23:29:34.794416","status":"completed"},"tags":[],"id":"FXhodgk504BW"}},{"cell_type":"code","source":"try:\n    import ujson as json\nexcept ModuleNotFoundError:\n    import json\n    print (\"Подумайте об установке ujson, чтобы работать с JSON объектами быстрее\")\n\ntry:\n    from tqdm.notebook import tqdm\nexcept ModuleNotFoundError:\n    tqdm_notebook = lambda x: x\n    print (\"Подумайте об установке tqdm, чтобы следить за прогрессом\")\n\n\ndef read_matches(matches_file, total_matches=31698, n_matches_to_read=None):\n    \"\"\"\n    Аргуент\n    -------\n    matches_file: JSON файл с сырыми данными\n\n    Результат\n    ---------\n    Возвращает записи о каждом матче\n    \"\"\"\n\n    if n_matches_to_read is None:\n        n_matches_to_read = total_matches\n\n    c = 0\n    with open(matches_file) as fin:\n        for line in tqdm(fin, total=total_matches):\n            if c >= n_matches_to_read:\n                break\n            else:\n                c += 1\n                yield json.loads(line)","metadata":{"papermill":{"duration":0.069503,"end_time":"2022-02-13T23:29:34.966941","exception":false,"start_time":"2022-02-13T23:29:34.897438","status":"completed"},"tags":[],"id":"AdMM16A504BW","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Чтение данных в цикле\n\nЧтение всех данных занимает 1-2 минуты, поэтому для начала можно попробовать следующее:\n\n1. Читать 10-50 игр\n2. Написать код для работы с этими JSON объектами\n3. Убедиться, что все работает\n4. Запустить код на всем датасете\n5. Сохранить результат в `pickle` файл, чтобы в следующий раз не переделывать все заново","metadata":{"papermill":{"duration":0.052275,"end_time":"2022-02-13T23:29:35.07086","exception":false,"start_time":"2022-02-13T23:29:35.018585","status":"completed"},"tags":[],"id":"vhF8YjWa04BX"}},{"cell_type":"markdown","source":"## <left>Feature engineering","metadata":{"papermill":{"duration":0.051565,"end_time":"2022-02-13T23:29:35.175139","exception":false,"start_time":"2022-02-13T23:29:35.123574","status":"completed"},"tags":[],"id":"tJFzB58604BX"}},{"cell_type":"markdown","source":"Напишем функцию, которая поможет нам легче добавлять новые признаки.","metadata":{"papermill":{"duration":0.051315,"end_time":"2022-02-13T23:29:35.278664","exception":false,"start_time":"2022-02-13T23:29:35.227349","status":"completed"},"tags":[],"id":"PvzVyd8p04BX"}},{"cell_type":"code","source":"def add_new_features(df_features, matches_file):\n    \"\"\"\n    Аргуенты\n    -------\n    df_features: таблица с данными\n    matches_file: JSON файл с сырыми данными\n\n    Результат\n    ---------\n    Добавляет новые признаки в таблицу\n    \"\"\"\n\n    for match in read_matches(matches_file):\n        match_id_hash = match['match_id_hash']\n\n        # Посчитаем количество разрушенных вышек обеими командами\n        radiant_tower_kills = 0\n        dire_tower_kills = 0\n        for objective in match[\"objectives\"]:\n            if objective[\"type\"] == \"CHAT_MESSAGE_TOWER_KILL\":\n                if objective[\"team\"] == 2:\n                    radiant_tower_kills += 1\n                if objective[\"team\"] == 3:\n                    dire_tower_kills += 1\n\n        df_features.loc[match_id_hash, \"radiant_tower_kills\"] = radiant_tower_kills\n        df_features.loc[match_id_hash, \"dire_tower_kills\"] = dire_tower_kills\n        df_features.loc[match_id_hash, \"diff_tower_kills\"] = radiant_tower_kills - dire_tower_kills\n\n        # ... (/¯◡ ‿ ◡)/¯☆*:・ﾟ добавляем новые признаки ...","metadata":{"execution":{"iopub.execute_input":"2022-02-13T23:29:35.392115Z","iopub.status.busy":"2022-02-13T23:29:35.39136Z","iopub.status.idle":"2022-02-13T23:29:35.393224Z","shell.execute_reply":"2022-02-13T23:29:35.393803Z","shell.execute_reply.started":"2022-02-13T22:57:58.423089Z"},"papermill":{"duration":0.063047,"end_time":"2022-02-13T23:29:35.393977","exception":false,"start_time":"2022-02-13T23:29:35.33093","status":"completed"},"tags":[],"id":"XJiUranL04BX"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Скопируем таблицу с признаками\ndf_train_features_extended = df_train_features.copy()\n\n# Добавим новые\nadd_new_features(df_train_features_extended,\n                 os.path.join(PATH_TO_DATA,\n                              \"train_raw_data.jsonl\"))","metadata":{"execution":{"iopub.execute_input":"2022-02-13T23:29:35.500607Z","iopub.status.busy":"2022-02-13T23:29:35.499947Z","iopub.status.idle":"2022-02-13T23:31:15.695377Z","shell.execute_reply":"2022-02-13T23:31:15.695887Z","shell.execute_reply.started":"2022-02-13T22:58:02.08187Z"},"papermill":{"duration":100.250385,"end_time":"2022-02-13T23:31:15.696073","exception":false,"start_time":"2022-02-13T23:29:35.445688","status":"completed"},"tags":[],"id":"B3wPM_v904BX"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train_features_extended.head()","metadata":{"execution":{"iopub.execute_input":"2022-02-13T23:31:15.806982Z","iopub.status.busy":"2022-02-13T23:31:15.805915Z","iopub.status.idle":"2022-02-13T23:31:15.829554Z","shell.execute_reply":"2022-02-13T23:31:15.830087Z","shell.execute_reply.started":"2022-02-13T23:00:24.658661Z"},"papermill":{"duration":0.08167,"end_time":"2022-02-13T23:31:15.83029","exception":false,"start_time":"2022-02-13T23:31:15.74862","status":"completed"},"tags":[],"id":"FWEFR-1w04BX"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\ncv_scores_base = cross_val_score(rf_model, X, y, cv=cv, scoring=\"roc_auc\", n_jobs=-1)\ncv_scores_extended = cross_val_score(rf_model, df_train_features_extended.values, y,\n                                     cv=cv, scoring=\"roc_auc\", n_jobs=-1)","metadata":{"execution":{"iopub.execute_input":"2022-02-13T23:31:15.940354Z","iopub.status.busy":"2022-02-13T23:31:15.939295Z","iopub.status.idle":"2022-02-13T23:32:55.255752Z","shell.execute_reply":"2022-02-13T23:32:55.256364Z","shell.execute_reply.started":"2022-02-13T23:00:39.716567Z"},"papermill":{"duration":99.37327,"end_time":"2022-02-13T23:32:55.256572","exception":false,"start_time":"2022-02-13T23:31:15.883302","status":"completed"},"tags":[],"id":"Lw7T_fUK04BX"},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"ROC-AUC на кросс-валидации для базовых признаков: {cv_scores_base.mean()}\")\nprint(f\"ROC-AUC на кросс-валидации для новых признаков: {cv_scores_extended.mean()}\")","metadata":{"execution":{"iopub.execute_input":"2022-02-13T23:32:55.369159Z","iopub.status.busy":"2022-02-13T23:32:55.368145Z","iopub.status.idle":"2022-02-13T23:32:55.37182Z","shell.execute_reply":"2022-02-13T23:32:55.372356Z","shell.execute_reply.started":"2022-02-13T23:02:14.824997Z"},"papermill":{"duration":0.062721,"end_time":"2022-02-13T23:32:55.372536","exception":false,"start_time":"2022-02-13T23:32:55.309815","status":"completed"},"tags":[],"id":"4F9p-6x504BX"},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Видно, что случайный лес стал работать немного лучше при добавлении новых признаков. A еще нужно, наверное, как-то по-умному закодировать категориальные признаки.","metadata":{"papermill":{"duration":0.053505,"end_time":"2022-02-13T23:32:55.479766","exception":false,"start_time":"2022-02-13T23:32:55.426261","status":"completed"},"tags":[],"id":"1Qu5wnOd04BX"}},{"cell_type":"markdown","source":"Дальше дело за малым. Добавляйте новые признаки, пробуйте другие методы, которые мы изучили, а также что-то интересное, что мы не прошли. Удачи!","metadata":{"papermill":{"duration":0.053776,"end_time":"2022-02-13T23:32:55.587047","exception":false,"start_time":"2022-02-13T23:32:55.533271","status":"completed"},"tags":[],"id":"96w6UpLU04BY"}}]}