{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":38760,"databundleVersionId":4493939,"sourceType":"competition"}],"dockerImageVersionId":31011,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Импорты","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\n\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nimport torch\nfrom torch import nn\nfrom torch.utils.data import Dataset, DataLoader\n\nfrom torch.optim import AdamW\n\nfrom pathlib import Path\nfrom datetime import timedelta\nimport json\nfrom tqdm import tqdm","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:20:25.932257Z","iopub.execute_input":"2025-04-13T16:20:25.932691Z","iopub.status.idle":"2025-04-13T16:20:31.495143Z","shell.execute_reply.started":"2025-04-13T16:20:25.932669Z","shell.execute_reply":"2025-04-13T16:20:31.494619Z"}},"outputs":[],"execution_count":1},{"cell_type":"markdown","source":"# Парсинг данных","metadata":{}},{"cell_type":"code","source":"data_path = Path('/kaggle/input/otto-recommender-system/')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:20:31.496374Z","iopub.execute_input":"2025-04-13T16:20:31.496732Z","iopub.status.idle":"2025-04-13T16:20:31.500817Z","shell.execute_reply.started":"2025-04-13T16:20:31.496714Z","shell.execute_reply":"2025-04-13T16:20:31.500034Z"}},"outputs":[],"execution_count":2},{"cell_type":"code","source":"train_df = pd.DataFrame()\nchunks = pd.read_json(data_path / 'train.jsonl', lines=True, chunksize=100000)\n\nfor i, chunk in enumerate(chunks):\n    if i < 2:\n        train_df = pd.concat([train_df, chunk])\n    else:\n        break\n\ntrain_df = train_df.set_index('session', drop=True).sort_index()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:20:31.501424Z","iopub.execute_input":"2025-04-13T16:20:31.501652Z","iopub.status.idle":"2025-04-13T16:21:01.225937Z","shell.execute_reply.started":"2025-04-13T16:20:31.501603Z","shell.execute_reply":"2025-04-13T16:21:01.225147Z"}},"outputs":[],"execution_count":3},{"cell_type":"code","source":"indices = [i for i in range(100)][:3]\nchunks_of_train = []\nfor idx, chunk in enumerate(chunks):\n    if idx in indices:\n        chunks_of_train.append(chunk)\n    if idx > max(indices):\n        break\n\nchunks_of_train = pd.concat(chunks_of_train)\nchunks_of_train.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:21:01.226753Z","iopub.execute_input":"2025-04-13T16:21:01.227032Z","iopub.status.idle":"2025-04-13T16:21:34.480213Z","shell.execute_reply.started":"2025-04-13T16:21:01.227004Z","shell.execute_reply":"2025-04-13T16:21:34.479618Z"}},"outputs":[{"execution_count":4,"output_type":"execute_result","data":{"text/plain":"        session                                             events\n300000   300000  [{'aid': 17703, 'ts': 1659342306961, 'type': '...\n300001   300001  [{'aid': 1337750, 'ts': 1659342306977, 'type':...\n300002   300002  [{'aid': 1140963, 'ts': 1659342306977, 'type':...\n300003   300003  [{'aid': 962105, 'ts': 1659342307084, 'type': ...\n300004   300004  [{'aid': 1072852, 'ts': 1659342307092, 'type':...","text/html":"<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>session</th>\n      <th>events</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>300000</th>\n      <td>300000</td>\n      <td>[{'aid': 17703, 'ts': 1659342306961, 'type': '...</td>\n    </tr>\n    <tr>\n      <th>300001</th>\n      <td>300001</td>\n      <td>[{'aid': 1337750, 'ts': 1659342306977, 'type':...</td>\n    </tr>\n    <tr>\n      <th>300002</th>\n      <td>300002</td>\n      <td>[{'aid': 1140963, 'ts': 1659342306977, 'type':...</td>\n    </tr>\n    <tr>\n      <th>300003</th>\n      <td>300003</td>\n      <td>[{'aid': 962105, 'ts': 1659342307084, 'type': ...</td>\n    </tr>\n    <tr>\n      <th>300004</th>\n      <td>300004</td>\n      <td>[{'aid': 1072852, 'ts': 1659342307092, 'type':...</td>\n    </tr>\n  </tbody>\n</table>\n</div>"},"metadata":{}}],"execution_count":4},{"cell_type":"markdown","source":"aid - тип товара \\\nts - временная метка \\\ntype - тип взаимодействия","metadata":{}},{"cell_type":"code","source":"events_dict = {\n    'session': [],\n    'aid': [],\n    'ts': [],\n    'type': []\n}","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:21:34.482281Z","iopub.execute_input":"2025-04-13T16:21:34.482811Z","iopub.status.idle":"2025-04-13T16:21:34.485828Z","shell.execute_reply.started":"2025-04-13T16:21:34.482792Z","shell.execute_reply":"2025-04-13T16:21:34.485273Z"}},"outputs":[],"execution_count":5},{"cell_type":"code","source":"for _, row in chunks_of_train.iterrows():\n    for event in row['events']:\n        events_dict['session'].append(row['session'])\n        events_dict['aid'].append(event['aid'])\n        events_dict['ts'].append(event['ts'])\n        events_dict['type'].append(event['type'])\n\ntrain_dict = pd.DataFrame(events_dict)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:21:34.486451Z","iopub.execute_input":"2025-04-13T16:21:34.486687Z","iopub.status.idle":"2025-04-13T16:22:19.062884Z","shell.execute_reply.started":"2025-04-13T16:21:34.486671Z","shell.execute_reply":"2025-04-13T16:22:19.062352Z"}},"outputs":[],"execution_count":6},{"cell_type":"markdown","source":"# Визуализация данных","metadata":{}},{"cell_type":"code","source":"events_type = train_dict.groupby(['type'])['type'].count().sort_values(ascending=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:22:19.063562Z","iopub.execute_input":"2025-04-13T16:22:19.063765Z","iopub.status.idle":"2025-04-13T16:22:21.597639Z","shell.execute_reply.started":"2025-04-13T16:22:19.063749Z","shell.execute_reply":"2025-04-13T16:22:21.597081Z"}},"outputs":[],"execution_count":7},{"cell_type":"code","source":"events_type","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:22:21.598661Z","iopub.execute_input":"2025-04-13T16:22:21.598937Z","iopub.status.idle":"2025-04-13T16:22:21.604594Z","shell.execute_reply.started":"2025-04-13T16:22:21.59891Z","shell.execute_reply":"2025-04-13T16:22:21.604013Z"}},"outputs":[{"execution_count":8,"output_type":"execute_result","data":{"text/plain":"type\nclicks    10369552\ncarts       876993\norders      268313\nName: type, dtype: int64"},"metadata":{}}],"execution_count":8},{"cell_type":"code","source":"fig, ax = plt.subplots(figsize=(16, 9))\nsns.barplot(x=events_type.index, y=events_type.values, ax=ax)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:22:21.605418Z","iopub.execute_input":"2025-04-13T16:22:21.6057Z","iopub.status.idle":"2025-04-13T16:22:22.500374Z","shell.execute_reply.started":"2025-04-13T16:22:21.605677Z","shell.execute_reply":"2025-04-13T16:22:22.499719Z"}},"outputs":[{"output_type":"display_data","data":{"text/plain":"<Figure size 1600x900 with 1 Axes>","image/png":"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AAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAABbEQAAAAAEgiFgIAAAAAhTcUC+fOnZv+/funQ4cOGTFiRFasWLHX9X/4wx9y8cUX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FyyefPLJueeee/KZz3wmV199dY477rjcf//9OeGEE/bfWQC7qKyszMyZM3f5SD8AtASvOwAcKF5zoGWVlV7v95IBAAAAgLeEZn1nIQAAAADw50ssBAAAAACSiIUAAAAAQEEshIPMunXrUlZWltWrVydJli1blrKysvzhD3/Yp/2nn356PvWpT7XYfAAAAC3F+xloeWIhHOROPvnkPP/886mqqmrtUQBgF97UAQAcXMRCOMhVVFSkV69eKSsra+1RAKDRzp07W3sEAA5SpVIpr732Wos8dn19fRoaGlrkseHPhVgIbVRDQ0NuvPHGHHvssamsrMyRRx6Zz33uc7us293HkB9++OGcfvrp6dSpUw4//PCMHj06L7744m6f54EHHkhVVVXuvvvuxsc76aST0rlz5xx22GE55ZRT8swzz7TIOQLQtuzttefKK6/MgAED0qlTpxx99NGZPn16Xn311ca91157bYYMGZI77rgjb3vb29KhQ4ecf/75+fGPf5xbbrklZWVlKSsry7p16/Liiy9m/Pjx6dGjRzp27JjjjjsuCxYsaK3TBuAAqKuryyc/+cn07NkzHTp0yKmnnppf/OIXSf70nuYHP/hBhg0blsrKyvz0pz/Njh07UlNTky5duqR3796ZPXv2bh936tSp6du3bzp37pwRI0Zk2bJljfffeeedOeyww/K9730vAwcOTGVlZdavX+99D+xF+9YeANi9adOm5fbbb8+Xv/zlnHrqqXn++efzxBNPvO6+1atX54wzzsjHP/7x3HLLLWnfvn2WLl2a+vr6Xdbec889ufDCC3PPPffkgx/8YF577bWcc845mTx5cr7xjW9k586dWbFihasWAd4i9vbac+ihh+bOO+9Mnz598thjj2Xy5Mk59NBDc8UVVzTuX7NmTb797W/nO9/5TsrLy3PUUUflqaeeygknnJDPfvazSZIePXrk0ksvza9//ev84Ac/SPfu3bNmzZq8/PLLrXLOABwYV1xxRb797W/n61//eo466qjceOONGT16dNasWdO45qqrrsqXvvSlHH300Tn88MNz+eWX58c//nG++93vpmfPnrn66quzatWqDBkypHHPJZdckl//+tdZuHBh+vTpk/vuuy9nnnlmHnvssRx33HFJkpdeeilf/OIXc8cdd+SII45It27dMmTIEO97YE9KQJtTW1tbqqysLN1+++273Ld27dpSktKjjz5aKpVKpaVLl5aSlF588cVSqVQqnXvuuaVTTjllj4/9nve8p3TppZeWbr311lJVVVVp2bJljff97ne/KyVpcgyAt4a9vfbszk033VQaNmxY498zZ84sHXLIIaXNmzc3WffH153/a8yYMaWJEye+6ZkBODhs3769dMghh5TuvvvuxmM7d+4s9enTp3TjjTc2vqe5//77G+/ftm1bqaKiovTNb36z8djvfve7UseOHRtfV5555plSeXl56dlnn23yfGeccUZp2rRppVKpVFqwYEEpSWn16tVNHsf7HtgzVxZCG/T444+nrq4uZ5xxRrP3rl69OmPHjt3rmnvvvTebN2/Oww8/nHe9612Nx7t165bzzz8/o0ePzvve976MGjUqH/3oR9O7d+9mzwHAweX1XnsWLVqUf/qnf8rTTz+d7du357XXXkvXrl2brDnqqKPSo0eP132uiy66KB/5yEeyatWqvP/9788555yTk08+eb+cBwBtz9NPP51XX301p5xySuOxQw45JCeddFIef/zxxvckw4cPb7Jn586dGTFiROOxbt265e1vf3vj34899ljq6+szYMCAJs9XV1eXI444ovHvioqKDBo0qMnjeN8De+Y7C6EN6tixY4vuHTp0aHr06JH58+enVCo1uW/BggVZvnx5Tj755CxatCgDBgzIz372szc8DwAHh729fixfvjzjx4/PBz7wgXz/+9/Po48+mmuuuWaXHzHp3LnzPj3XWWedlWeeeSaXXXZZnnvuuZxxxhmZOnXqm5ofgIPfvr6O/NH27dtTXl6elStXZvXq1Y23xx9/PLfcckvjuo4dO+7yEWPve2DPxEJog4477rh07NgxS5YsafbeQYMGve6+Y445JkuXLs13v/vdfOITn9jl/qFDh2batGl55JFHcsIJJ+See+5p9hwAHFz29trzyCOP5Kijjso111yT4cOH57jjjtvnL4GvqKjY7ffm9ujRIxMmTMi//Mu/ZM6cObntttve9DkA0DYdc8wxqaioyMMPP9x47NVXX80vfvGLDBw4cI97DjnkkPz85z9vPPbiiy/mqaeeavx76NChqa+vz+bNm3Psscc2ufXq1et15/K+B3bPx5ChDerQoUOuvPLKXHHFFamoqMgpp5ySLVu25L//+79f96PJ06ZNy4knnph//Md/zIUX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\n"},"metadata":{}}],"execution_count":9},{"cell_type":"code","source":"# Считаем длину сессии\ndef count_seconds(x):\n    max_value = int(x.max())\n    min_value = int(x.min())\n\n    session_time = timedelta(microseconds=max_value-min_value)\n\n    return session_time.total_seconds() / 60","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:22:22.501107Z","iopub.execute_input":"2025-04-13T16:22:22.501299Z","iopub.status.idle":"2025-04-13T16:22:22.505355Z","shell.execute_reply.started":"2025-04-13T16:22:22.501285Z","shell.execute_reply":"2025-04-13T16:22:22.504697Z"}},"outputs":[],"execution_count":10},{"cell_type":"code","source":"time_counts = train_dict.groupby(['session'])['ts'].apply(count_seconds)\n\nfig, ax = plt.subplots(figsize=(16, 9))\nsns.displot(x=time_counts.values, ax=ax, bins=30, kde=False)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:22:22.505991Z","iopub.execute_input":"2025-04-13T16:22:22.506194Z","iopub.status.idle":"2025-04-13T16:22:33.794463Z","shell.execute_reply.started":"2025-04-13T16:22:22.506181Z","shell.execute_reply":"2025-04-13T16:22:33.793852Z"}},"outputs":[{"name":"stderr","text":"/usr/local/lib/python3.11/dist-packages/seaborn/distributions.py:2142: UserWarning: `displot` is a figure-level function and does not accept the ax= parameter. You may wish to try histplot.\n  warnings.warn(msg, UserWarning)\n/usr/local/lib/python3.11/dist-packages/seaborn/_oldcore.py:1119: FutureWarning: use_inf_as_na option is deprecated and will be removed in a future version. Convert inf values to NaN before operating instead.\n  with pd.option_context('mode.use_inf_as_na', True):\n","output_type":"stream"},{"output_type":"display_data","data":{"text/plain":"<Figure size 1600x900 with 1 Axes>","image/png":"iVBORw0KGgoAAAANSUhEUgAABRYAAALmCAYAAAA37shJAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuNSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/xnp5ZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAriUlEQVR4nO3df2zV9b348VdboNXMVryM8mPdZdf9cAsKDrSrzntj0tlkhl3+WG6HCxCuzrjLjNK7ewFFOudGuZsallBHZC7ef7hwZyZZhNR5e0d2vTaXCDTRXMA4ZCXGFrgLLbdurWvP94+bdd+O8uPV0RbZ45GcP/re+30+77PkDebJ5/RTVCgUCgEAAAAAkFA80RsAAAAAAN5/hEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIC0dFn/+85/HokWLYtasWVFUVBQ7d+4875o9e/bEpz/96SgtLY2PfvSj8eyzz45iqwAAAADApSIdFnt7e2PevHnR3Nx8QfPfeuutuPPOO+P222+P9vb2ePDBB+Oee+6JF198Mb1ZAAAAAODSUFQoFAqjXlxUFM8//3wsXrz4rHNWr14du3btitdff31o7Etf+lKcOnUqWlpaRntpAAAAAGACTRrrC7S1tUVtbe2wsbq6unjwwQfPuqavry/6+vqGfh4cHIxf/epX8Wd/9mdRVFQ0VlsFAAAAgMtSoVCI06dPx6xZs6K4+OI8dmXMw2JnZ2dUVlYOG6usrIyenp749a9/HVdcccUZa5qamuLRRx8d660BAAAAwJ+UY8eOxYc+9KGL8l5jHhZHY+3atdHQ0DD0c3d3d3z4wx+OY8eORXl5+QTuDAAAAADef3p6eqKqqiquuuqqi/aeYx4WZ8yYEV1dXcPGurq6ory8fMS7FSMiSktLo7S09Izx8vJyYREAAAAARuli/prBi/OF6nOoqamJ1tbWYWMvvfRS1NTUjPWlAQAAAIAxkg6L//u//xvt7e3R3t4eERFvvfVWtLe3R0dHR0T839eYly1bNjT/vvvuiyNHjsQ//uM/xqFDh+Kpp56Kf/3Xf41Vq1ZdnE8AAAAAAIy7dFh89dVX48Ybb4wbb7wxIiIaGhrixhtvjPXr10dExDvvvDMUGSMiPvKRj8SuXbvipZdeinnz5sUTTzwRP/jBD6Kuru4ifQQAAAAAYLwVFQqFwkRv4nx6enqioqIiuru7/Y5FAAAAAEgai7425r9jEQAAAAC4/AiLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAEDaqMJic3NzzJkzJ8rKyqK6ujr27t17zvmbNm2KT3ziE3HFFVdEVVVVrFq1Kn7zm9+MasMAAAAAwMRLh8UdO3ZEQ0NDNDY2xv79+2PevHlRV1cXx48fH3H+tm3bYs2aNdHY2BgHDx6MZ555Jnbs2BEPPfTQH715AAAAAGBipMPik08+GV/5yldixYoV8alPfSq2bNkSV155Zfzwhz8ccf4rr7wSt956a9x1110xZ86cuOOOO2LJkiXnvcsRAAAAALh0pcJif39/7Nu3L2pra3//BsXFUVtbG21tbSOuueWWW2Lfvn1DIfHIkSOxe/fu+PznP3/W6/T19UVPT8+wFwAAAABw6ZiUmXzy5MkYGBiIysrKYeOVlZVx6NChEdfcddddcfLkyfjsZz8bhUIhfvvb38Z99913zq9CNzU1xaOPPprZGgAAAAAwjsb8qdB79uyJDRs2xFNPPRX79++PH//4x7Fr16547LHHzrpm7dq10d3dPfQ6duzYWG8TAAAAAEhI3bE4bdq0KCkpia6urmHjXV1dMWPGjBHXPPLII7F06dK45557IiLi+uuvj97e3rj33nvj4YcfjuLiM9tmaWlplJaWZrYGAAAAAIyj1B2LU6ZMiQULFkRra+vQ2ODgYLS2tkZNTc2Ia959990z4mFJSUlERBQKhex+AQAAAIBLQOqOxYiIhoaGWL58eSxcuDBuvvnm2LRpU/T29saKFSsiImLZsmUxe/bsaGpqioiIRYsWxZNPPhk33nhjVFdXx5tvvhmPPPJILFq0aCgwAgAAAADvL+mwWF9fHydOnIj169dHZ2dnzJ8/P1paWoYe6NLR0THsDsV169ZFUVFRrFu3Lt5+++344Ac/GIsWLYpvf/vbF+9TAAAAAADjqqjwPvg+ck9PT1RUVER3d3eUl5dP9HYAAAAA4H1lLPramD8VGgAAAAC4/AiLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApAmLAAAAAECasAgAAAAApI0qLDY3N8ecOXOirKwsqqurY+/eveecf+rUqVi5cmXMnDkzSktL4+Mf/3js3r17VBsGAAAAACbepOyCHTt2RENDQ2zZsiWqq6tj06ZNUVdXF4cPH47p06efMb+/vz8+97nPxfTp0+O5556L2bNnxy9/+cu4+uqrL8b+AQAAAIAJUFQoFAqZBdXV1XHTTTfF5s2bIyJicHAwqqqq4v777481a9acMX/Lli3x3e9+Nw4dOhSTJ08e1SZ7enqioqIiuru7o7y8fFTvAQAAAAB/qsair6W+Ct3f3x/79u2L2tra379BcXHU1tZGW1vbiGt+8pOfRE1NTaxcuTIqKytj7ty5sWHDhhgYGDjrdfr6+qKnp2fYCwAAAAC4dKTC4smTJ2NgYCAqKyuHjVdWVkZnZ+eIa44cORLPPfdcDAwMxO7du+ORRx6JJ554Ir71rW+d9TpNTU1RUVEx9KqqqspsEwAAAAAYY2P+VOjBwcGYPn16PP3007FgwYKor6+Phx9+OLZs2XLWNWvXro3u7u6h17Fjx8Z6mwAAAABAQurhLdOmTYuSkpLo6uoaNt7V1RUzZswYcc3MmTNj8uTJUVJSMjT2yU9+Mjo7O6O/vz+mTJlyxprS0tIoLS3NbA0AAAAAGEepOxanTJkSCxYsiNbW1qGxwcHBaG1tjZqamhHX3HrrrfHmm2/G4ODg0Ngbb7wRM2fOHDEqAgAAAACXvvRXoRsaGmLr1q3xz//8z3Hw4MH46le/Gr29vbFixYqIiFi2bFmsXbt2aP5Xv/rV+NWvfhUPPPBAvPHGG7Fr167YsGFDrFy58uJ9CgAAAABgXKW+Ch0RUV9fHydOnIj169dHZ2dnzJ8/P1paWoYe6NLR0RHFxb/vlVVVVfHiiy/GqlWr4oYbbojZs2fHAw88EKtXr754nwIAAAAAGFdFhUKhMNGbOJ+enp6oqKiI7u7uKC8vn+jtAAAAAMD7ylj0tTF/KjQAAAAAcPkRFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACANGERAAAAAEgTFgEAAACAtFGFxebm5pgzZ06UlZVFdXV17N2794LWbd++PYqKimLx4sWjuSwAAAAAcIlIh8UdO3ZEQ0NDNDY2xv79+2PevHlRV1cXx48fP+e6o0ePxte//vW47bbbRr1ZAAAAAODSkA6LTz75ZHzlK1+JFStWxKc+9anYsmVLXHnllfHDH/7wrGsGBgbiy1/+cjz66KPxF3/xF3/UhgEAAACAiZcKi/39/bFv376ora39/RsUF0dtbW20tbWddd03v/nNmD59etx9990XdJ2+vr7o6ekZ9gIAAAAALh2psHjy5MkYGBiIysrKYeOVlZXR2dk54pqXX345nnnmmdi6desFX6epqSkqKiqGXlVVVZltAgAAAABjbEyfCn369OlYunRpbN26NaZNm3bB69auXRvd3d1Dr2PHjo3hLgEAAACArEmZydOmTYuSkpLo6uoaNt7V1RUzZsw4Y/4vfvGLOHr0aCxatGhobHBw8P8uPGlSHD58OK699toz1pWWlkZpaWlmawAAAADAOErdsThlypRYsGBBtLa2Do0NDg5Ga2tr1NTUnDH/uuuui9deey3a29uHXl/4whfi9ttvj/b2dl9xBgAAAID3qdQdixERDQ0NsXz58li4cGHcfPPNsWnTpujt7Y0VK1ZERMSyZcti9uzZ0dTUFGVlZTF37txh66+++uqIiDPGAQAAAID3j3RYrK+vjxMnTsT69eujs7Mz5s+fHy0tLUMPdOno6Iji4jH91Y0AAAAAwAQrKhQKhYnexPn09PRERUVFdHd3R3l5+URvBwAAAADeV8air7m1EAAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIG1VYbG5ujjlz5kRZWVlUV1fH3r17zzp369atcdttt8XUqVNj6tSpUVtbe875AAAAAMClLx0Wd+zYEQ0NDdHY2Bj79++PefPmRV1dXRw/fnzE+Xv27IklS5bEz372s2hra4uqqqq444474u233/6jNw8AAAAATIyiQqFQyCyorq6Om266KTZv3hwREYODg1FVVRX3339/rFmz5rzrBwYGYurUqbF58+ZYtmzZBV2zp6cnKioqoru7O8rLyzPbBQAAAIA/eWPR11J3LPb398e+ffuitrb2929QXBy1tbXR1tZ2Qe/x7rvvxnvvvRfXXHNNbqcAAAAAwCVjUmbyyZMnY2BgICorK4eNV1ZWxqFDhy7oPVavXh2zZs0aFif/UF9fX/T19Q393NPTk9kmAAAAADDGxvWp0Bs3bozt27fH888/H2VlZWed19TUFBUVFUOvqqqqcdwlAAAAAHA+qbA4bdq0KCkpia6urmHjXV1dMWPGjHOuffzxx2Pjxo3x05/+NG644YZzzl27dm10d3cPvY4dO5bZJgAAAAAwxlJhccqUKbFgwYJobW0dGhscHIzW1taoqak567rvfOc78dhjj0VLS0ssXLjwvNcpLS2N8vLyYS8AAAAA4NKR+h2LERENDQ2xfPnyWLhwYdx8882xadOm6O3tjRUrVkRExLJly2L27NnR1NQUERH/9E//FOvXr49t27bFnDlzorOzMyIiPvCBD8QHPvCBi/hRAAAAAIDxkg6L9fX1ceLEiVi/fn10dnbG/Pnzo6WlZeiBLh0dHVFc/PsbIb///e9Hf39/fPGLXxz2Po2NjfGNb3zjj9s9AAAAADAhigqFQmGiN3E+PT09UVFREd3d3b4WDQAAAABJY9HXxvWp0AAAAADA5UFYBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADShEUAAAAAIE1YBAAAAADSRhUWm5ubY86cOVFWVhbV1dWxd+/ec87/0Y9+FNddd12UlZXF9ddfH7t37x7VZgEAAACAS0M6LO7YsSMaGhqisbEx9u/fH/PmzYu6uro4fvz4iPNfeeWVWLJkSdx9991x4MCBWLx4cSxevDhef/31P3rzAAAAAMDEKCoUCoXMgurq6rjpppti8+bNERExODgYVVVVcf/998eaNWvOmF9fXx+9vb3xwgsvDI195jOfifnz58eWLVsu6Jo9PT1RUVER3d3dUV5entkuAAAAAPzJG4u+Nikzub+/P/bt2xdr164dGisuLo7a2tpoa2sbcU1bW1s0NDQMG6urq4udO3ee9Tp9fX3R19c39HN3d3dE/N//AQAAAABAzu+6WvIew3NKhcWTJ0/GwMBAVFZWDhuvrKyMQ4cOjbims7NzxPmdnZ1nvU5TU1M8+uijZ4xXVVVltgsAAAAA/H/+53/+JyoqKi7Ke6XC4nhZu3btsLscT506FX/+538eHR0dF+2DA5eGnp6eqKqqimPHjvlVB3CZcb7h8uV8w+XL+YbLV3d3d3z4wx+Oa6655qK9ZyosTps2LUpKSqKrq2vYeFdXV8yYMWPENTNmzEjNj4goLS2N0tLSM8YrKir8wQaXqfLycucbLlPON1y+nG+4fDnfcPkqLk4/y/ns75WZPGXKlFiwYEG0trYOjQ0ODkZra2vU1NSMuKampmbY/IiIl1566azzAQAAAIBLX/qr0A0NDbF8+fJYuHBh3HzzzbFp06bo7e2NFStWRETEsmXLYvbs2dHU1BQREQ888ED81V/9VTzxxBNx5513xvbt2+PVV1+Np59++uJ+EgAAAABg3KTDYn19fZw4cSLWr18fnZ2dMX/+/GhpaRl6QEtHR8ewWypvueWW2LZtW6xbty4eeuih+NjHPhY7d+6MuXPnXvA1S0tLo7GxccSvRwPvb843XL6cb7h8Od9w+XK+4fI1Fue7qHAxnzENAAAAAPxJuHi/rREAAAAA+JMhLAIAAAAAacIiAAAAAJAmLAIAAAAAaZdMWGxubo45c+ZEWVlZVFdXx969e885/0c/+lFcd911UVZWFtdff33s3r17nHYKZGXO99atW+O2226LqVOnxtSpU6O2tva8fx4AEyf79/fvbN++PYqKimLx4sVju0Fg1LLn+9SpU7Fy5cqYOXNmlJaWxsc//nH/jQ6XqOz53rRpU3ziE5+IK664IqqqqmLVqlXxm9/8Zpx2C1yIn//857Fo0aKYNWtWFBUVxc6dO8+7Zs+ePfHpT386SktL46Mf/Wg8++yz6eteEmFxx44d0dDQEI2NjbF///6YN29e1NXVxfHjx0ec/8orr8SSJUvi7rvvjgMHDsTixYtj8eLF8frrr4/zzoHzyZ7vPXv2xJIlS+JnP/tZtLW1RVVVVdxxxx3x9ttvj/POgfPJnu/fOXr0aHz961+P2267bZx2CmRlz3d/f3987nOfi6NHj8Zzzz0Xhw8fjq1bt8bs2bPHeefA+WTP97Zt22LNmjXR2NgYBw8ejGeeeSZ27NgRDz300DjvHDiX3t7emDdvXjQ3N1/Q/LfeeivuvPPOuP3226O9vT0efPDBuOeee+LFF19MXbeoUCgURrPhi6m6ujpuuumm2Lx5c0REDA4ORlVVVdx///2xZs2aM+bX19dHb29vvPDCC0Njn/nMZ2L+/PmxZcuWcds3cH7Z8/2HBgYGYurUqbF58+ZYtmzZWG8XSBjN+R4YGIi//Mu/jL/927+N//iP/4hTp05d0L+mAuMre763bNkS3/3ud+PQoUMxefLk8d4ukJA931/72tfi4MGD0draOjT293//9/Ff//Vf8fLLL4/bvoELV1RUFM8///w5vx20evXq2LVr17Cb9L70pS/FqVOnoqWl5YKvNeF3LPb398e+ffuitrZ2aKy4uDhqa2ujra1txDVtbW3D5kdE1NXVnXU+MDFGc77/0LvvvhvvvfdeXHPNNWO1TWAURnu+v/nNb8b06dPj7rvvHo9tAqMwmvP9k5/8JGpqamLlypVRWVkZc+fOjQ0bNsTAwMB4bRu4AKM537fcckvs27dv6OvSR44cid27d8fnP//5cdkzMDYuVlubdDE3NRonT56MgYGBqKysHDZeWVkZhw4dGnFNZ2fniPM7OzvHbJ9A3mjO9x9avXp1zJo164w/8ICJNZrz/fLLL8czzzwT7e3t47BDYLRGc76PHDkS//7v/x5f/vKXY/fu3fHmm2/G3/3d38V7770XjY2N47Ft4AKM5nzfddddcfLkyfjsZz8bhUIhfvvb38Z9993nq9DwPne2ttbT0xO//vWv44orrrig95nwOxYBzmbjxo2xffv2eP7556OsrGyitwP8EU6fPh1Lly6NrVu3xrRp0yZ6O8BFNjg4GNOnT4+nn346FixYEPX19fHwww/7NUVwGdizZ09s2LAhnnrqqdi/f3/8+Mc/jl27dsVjjz020VsDLgETfsfitGnToqSkJLq6uoaNd3V1xYwZM0ZcM2PGjNR8YGKM5nz/zuOPPx4bN26Mf/u3f4sbbrhhLLcJjEL2fP/iF7+Io0ePxqJFi4bGBgcHIyJi0qRJcfjw4bj22mvHdtPABRnN398zZ86MyZMnR0lJydDYJz/5yejs7Iz+/v6YMmXKmO4ZuDCjOd+PPPJILF26NO65556IiLj++uujt7c37r333nj44YejuNj9SvB+dLa2Vl5efsF3K0ZcAncsTpkyJRYsWDDsF8EODg5Ga2tr1NTUjLimpqZm2PyIiJdeeums84GJMZrzHRHxne98Jx577LFoaWmJhQsXjsdWgaTs+b7uuuvitddei/b29qHXF77whaGn0FVVVY3n9oFzGM3f37feemu8+eabQ/9gEBHxxhtvxMyZM0VFuISM5ny/++67Z8TD3/0jwiXwLFhglC5aWytcArZv314oLS0tPPvss4X//u//Ltx7772Fq6++utDZ2VkoFAqFpUuXFtasWTM0/z//8z8LkyZNKjz++OOFgwcPFhobGwuTJ08uvPbaaxP1EYCzyJ7vjRs3FqZMmVJ47rnnCu+8887Q6/Tp0xP1EYCzyJ7vP7R8+fLCX//1X4/TboGM7Pnu6OgoXHXVVYWvfe1rhcOHDxdeeOGFwvTp0wvf+ta3JuojAGeRPd+NjY2Fq666qvAv//IvhSNHjhR++tOfFq699trC3/zN30zURwBGcPr06cKBAwcKBw4cKERE4cknnywcOHCg8Mtf/rJQKBQKa9asKSxdunRo/pEjRwpXXnll4R/+4R8KBw8eLDQ3NxdKSkoKLS0tqetO+FehIyLq6+vjxIkTsX79+ujs7Iz58+dHS0vL0C+R7OjoGPYvJLfcckts27Yt1q1bFw899FB87GMfi507d8bcuXMn6iMAZ5E939///vejv78/vvjFLw57n8bGxvjGN74xnlsHziN7voH3j+z5rqqqihdffDFWrVoVN9xwQ8yePTseeOCBWL169UR9BOAssud73bp1UVRUFOvWrYu33347PvjBD8aiRYvi29/+9kR9BGAEr776atx+++1DPzc0NERExPLly+PZZ5+Nd955Jzo6Oob+94985COxa9euWLVqVXzve9+LD33oQ/GDH/wg6urqUtctKhTcuwwAAAAA5LiNAAAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgDRhEQAAAABIExYBAAAAgLT/B0WLAL2jFArSAAAAAElFTkSuQmCC\n"},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"<Figure size 500x500 with 1 Axes>","image/png":"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pTku1Hd0dLSR43z8+HE9+uijyszMVGBgYLsfn4+7DXE13CozJCREN954o44dO+btVpqsfmyv5HGXpOuvv16hoaFGjH1ycrI2btyoDz74QL169bLXR0REqLq6WiUlJR71poz1hfpuTP31/L053gEBAerfv79iYmK0ePFiDRs2TKtXrzZ+nC/Ud2NMGOfc3FwVFxdrxIgR6tChgzp06KDs7GytWbNGHTp0UHh4eJuONyFtiKvhVpnl5eX67LPP1LNnT2+30mRRUVGKiIjwGHe3261du3ZdMeMuSf/4xz/05ZdfenXsLctScnKy3nrrLW3btk1RUVEe22NiYuTv7+8x1vn5+SosLPTqWF+q78bk5eVJklG/63V1daqqqjJ2nC+kvu/GmDDO48aN08GDB5WXl2cvI0eO1NSpU+2f23S8L3vqGVrN+vXrLYfDYWVkZFhHjhyxHn74YSskJMRyuVzebq1R//Ef/2Ft377dKigosP7yl79YcXFxVmhoqFVcXOzt1jyUlZVZ+/fvt/bv329JslasWGHt37/f+r//+z/LsixryZIlVkhIiPXHP/7ROnDggHX33XdbUVFR1pkzZ4zsuayszPr5z39u5eTkWAUFBdb7779vjRgxwhowYIBVWVnptZ5nzZplBQcHW9u3b7dOnjxpL//85z/tmpkzZ1p9+vSxtm3bZu3du9dyOp2W0+n0Ws+Wdem+jx07Zi1atMjau3evVVBQYP3xj3+0rr/+emvMmDFe6/nJJ5+0srOzrYKCAuvAgQPWk08+afn4+Fhbt261LMvMcbasi/dt4jhfyPmz0NtyvAlpwzz33HNWnz59rICAAOuWW26xdu7c6e2WLmjKlClWz549rYCAAOsb3/iGNWXKFOvYsWPebquBDz74wJLUYElMTLQs6+vTsJ5++mkrPDzccjgc1rhx46z8/Hxje/7nP/9pjR8/3rruuussf39/q2/fvtaMGTO8/s9cY/1Ksl599VW75syZM9bPfvYzq1u3blanTp2s73//+9bJkye917R16b4LCwutMWPGWN27d7ccDofVv39/67HHHrNKS0u91vODDz5o9e3b1woICLCuu+46a9y4cXZAW5aZ42xZF+/bxHG+kPNDui3Hm1tVAgBgKL6TBgDAUIQ0AACGIqQBADAUIQ0AgKEIaQAADEVIAwBgKEIaAABDEdIAABiKkAYAwFCENAAAhiKkAQAw1P8DJmwNm0GXZboAAAAASUVORK5CYII=\n"},"metadata":{}}],"execution_count":11},{"cell_type":"markdown","source":"# Пробуем разные алгоритмы","metadata":{}},{"cell_type":"markdown","source":"## Multi-label классификация","metadata":{}},{"cell_type":"code","source":"class Config:\n    def __init__(self):\n        self.embed_dim = 128\n        self.num_heads = 4\n        self.num_layers = 2\n        self.max_len = 20\n        self.batch_size = 16\n        self.num_epochs = 10\n        self.lr = 1e-4\n        self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:22:33.795218Z","iopub.execute_input":"2025-04-13T16:22:33.79594Z","iopub.status.idle":"2025-04-13T16:22:33.800213Z","shell.execute_reply.started":"2025-04-13T16:22:33.795918Z","shell.execute_reply":"2025-04-13T16:22:33.799433Z"}},"outputs":[],"execution_count":12},{"cell_type":"code","source":"def load_data(data_path: str = '/kaggle/input/otto-recommender-system/', sample_fraction=0.0001, min_item_freq=5):\n    def read_jsonl(file_path, sample_fraction):\n        data = []\n        with open(file_path, 'r') as f:\n            for line in tqdm(f, desc=f'Reading {file_path.name}'):\n                if sample_fraction < 0.1 and np.random.rand() > sample_fraction:\n                    continue\n                session = json.loads(line)\n                for event in session['events']:\n                    data.append({\n                        'session': session['session'],\n                        'aid': event['aid'], \n                        'ts': event['ts'],\n                        'type': event['type']\n                    })\n\n        return pd.DataFrame(data)\n\n    train_path = Path(data_path) / 'train.jsonl'\n    test_path = Path(data_path) / 'test.jsonl'\n\n    train = read_jsonl(train_path, sample_fraction)\n    test = read_jsonl(test_path, 1)\n\n    all_items = pd.concat([train['aid'], test['aid']]).unique()\n    item2id = {aid: i+1 for i, aid in enumerate(all_items)}\n\n    type_mapping = {'clicks': 0, 'carts': 1, 'orders': 2}\n    train['type'] = train['type'].map(type_mapping)\n    test['type'] = test['type'].map(type_mapping)\n\n    return train, test, item2id","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:22:33.801148Z","iopub.execute_input":"2025-04-13T16:22:33.801398Z","iopub.status.idle":"2025-04-13T16:22:33.820392Z","shell.execute_reply.started":"2025-04-13T16:22:33.801371Z","shell.execute_reply":"2025-04-13T16:22:33.819705Z"}},"outputs":[],"execution_count":13},{"cell_type":"code","source":"class OttoDataset(Dataset):\n    def __init__(self, sessions, max_len):\n        self.sessions = sessions\n        self.max_len = max_len\n\n    def __len__(self):\n        return len(self.sessions)\n\n    def __getitem__(self, idx):\n        session = self.sessions[idx]\n        aids = session['aids'][-self.max_len:]\n        types = session['types'][-self.max_len:]\n        seq_len = len(aids)\n\n        aids_pad = [0] * (self.max_len - seq_len) + aids\n        types_pad = [0] * (self.max_len - seq_len) + types\n\n        mask = [0] * (self.max_len - seq_len) + [1] * seq_len\n\n        return {\n            'aids': torch.LongTensor(aids_pad),\n            'types': torch.LongTensor(types_pad),\n            'mask': torch.BoolTensor(mask)\n        }\n        ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:22:33.823186Z","iopub.execute_input":"2025-04-13T16:22:33.82345Z","iopub.status.idle":"2025-04-13T16:22:33.836563Z","shell.execute_reply.started":"2025-04-13T16:22:33.823434Z","shell.execute_reply":"2025-04-13T16:22:33.835942Z"}},"outputs":[],"execution_count":14},{"cell_type":"code","source":"class MultiHeadTransformer(nn.Module):\n    def __init__(self, num_items, config):\n        super().__init__()\n        self.config = config\n        self.item_emb = nn.Embedding(num_items + 1, config.embed_dim, padding_idx=0)\n        self.type_emb = nn.Embedding(3, config.embed_dim)\n        self.pos_emb = nn.Embedding(config.max_len, config.embed_dim)\n\n        encoder_layer = nn.TransformerEncoderLayer(\n            d_model=config.embed_dim,\n            nhead=config.num_heads,\n            dim_feedforward=4*config.embed_dim,\n            dropout=0.1,\n            activation='gelu'\n        )\n        self.encoder = nn.TransformerEncoder(encoder_layer, config.num_layers)\n\n        self.head_clicks = nn.Linear(config.embed_dim, num_items+1)\n        self.head_carts = nn.Linear(config.embed_dim, num_items+1)\n        self.head_orders = nn.Linear(config.embed_dim, num_items+1)\n\n    def forward(self, aids, types, mask):\n        batch_size, seq_len = aids.size()\n\n        item_emb = self.item_emb(aids)\n\n        item_emb = self.item_emb(aids)\n        type_emb = self.type_emb(types)\n        pos = self.pos_emb(torch.arange(seq_len, device=aids.device)).unsqueeze(0)\n\n        x = item_emb + type_emb + pos\n        x = x.permute(1, 0, 2)  # (seq_len, batch, embed_dim)\n\n        src_key_padding_mask = ~mask\n        attn_mask = torch.triu(torch.ones(seq_len, seq_len), diagonal=1).bool().to(aids.device) # маска внимания\n\n        output = self.encoder(x, attn_mask, src_key_padding_mask)\n        output = output.permute(1, 0, 2) # (batch, seq_len, embed_dim)\n\n        return {\n            self.head_clicks(output),\n            self.head_carts(output),\n            self.head_orders(output),\n        }","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:22:33.837329Z","iopub.execute_input":"2025-04-13T16:22:33.83754Z","iopub.status.idle":"2025-04-13T16:22:33.853692Z","shell.execute_reply.started":"2025-04-13T16:22:33.837521Z","shell.execute_reply":"2025-04-13T16:22:33.853023Z"}},"outputs":[],"execution_count":15},{"cell_type":"markdown","source":"# Обучение","metadata":{}},{"cell_type":"code","source":"def compute_loss(logits, targets, mask):\n    if not mask.any():\n        return torch.tensor(0.0, device=logits.device)\n    \n    # logits shape: [batch, seq_len, num_items]\n    # targets shape: [batch, seq_len]\n    # mask shape: [batch, seq_len-1]\n    \n    logits = logits[:, :-1, :]  # [batch, seq_len-1, num_items]\n    logits = logits[mask].view(-1, logits.size(-1))\n    labels = targets[:, 1:][mask].view(-1)\n    \n    return nn.CrossEntropyLoss()(logits, labels)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:22:33.854398Z","iopub.execute_input":"2025-04-13T16:22:33.854612Z","iopub.status.idle":"2025-04-13T16:22:33.870078Z","shell.execute_reply.started":"2025-04-13T16:22:33.854599Z","shell.execute_reply":"2025-04-13T16:22:33.869333Z"}},"outputs":[],"execution_count":16},{"cell_type":"code","source":"def train_model(config, train_session, item2id):\n    print(\"Training started...\")\n    \n    dataset = OttoDataset(train_session, config.max_len)\n    train_loader = DataLoader(dataset, batch_size=config.batch_size, shuffle=True)\n\n    model = MultiHeadTransformer(len(item2id), config).to(config.device)\n    optimizer = AdamW(model.parameters(), lr=config.lr)\n    print(\"Model created\")\n\n    for epoch in range(config.num_epochs):\n        model.train()\n\n        total_loss = 0\n\n        for batch in tqdm(train_loader, desc=f'Epoch {epoch + 1}'):\n            aids = batch['aids'].to(config.device)\n            types = batch['types'].to(config.device)\n            mask = batch['mask'].to(config.device)\n\n            # Targets are next items (shifted by 1)\n            targets = aids.roll(-1, dims=1)\n            # Mask for valid targets (next items)\n            target_mask = mask & (targets != 0)  # [batch, seq_len]\n            # For prediction, we use all but last position\n            pred_mask = target_mask[:, :-1]  # [batch, seq_len-1]\n\n            logits_clicks, logits_carts, logits_orders = model(aids, types, mask)\n\n            loss_clicks = compute_loss(logits_clicks, targets, pred_mask & (types[:, :-1] == 0))\n            loss_carts = compute_loss(logits_carts, targets, pred_mask & (types[:, :-1] == 1))\n            loss_orders = compute_loss(logits_orders, targets, pred_mask & (types[:, :-1] == 2))\n\n            loss = 0.1 * loss_clicks + 0.3 * loss_carts + 0.6 * loss_orders\n\n            optimizer.zero_grad()\n            loss.backward()\n            optimizer.step()\n\n            total_loss += loss.item()\n\n        print(f'Epoch: {epoch + 1} Loss: {total_loss}')\n\n    return model, item2id","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:22:33.870926Z","iopub.execute_input":"2025-04-13T16:22:33.871166Z","iopub.status.idle":"2025-04-13T16:22:33.888776Z","shell.execute_reply.started":"2025-04-13T16:22:33.871143Z","shell.execute_reply":"2025-04-13T16:22:33.888065Z"}},"outputs":[],"execution_count":17},{"cell_type":"code","source":"train, test, item2id = load_data()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:22:33.889496Z","iopub.execute_input":"2025-04-13T16:22:33.889692Z","iopub.status.idle":"2025-04-13T16:26:01.693858Z","shell.execute_reply.started":"2025-04-13T16:22:33.889678Z","shell.execute_reply":"2025-04-13T16:26:01.693283Z"}},"outputs":[{"name":"stderr","text":"Reading train.jsonl: 12899779it [03:04, 69853.81it/s] \nReading test.jsonl: 1671803it [00:13, 126759.76it/s]\n","output_type":"stream"}],"execution_count":18},{"cell_type":"code","source":"config = Config()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:26:01.694674Z","iopub.execute_input":"2025-04-13T16:26:01.694945Z","iopub.status.idle":"2025-04-13T16:26:01.790646Z","shell.execute_reply.started":"2025-04-13T16:26:01.694924Z","shell.execute_reply":"2025-04-13T16:26:01.790044Z"}},"outputs":[],"execution_count":19},{"cell_type":"code","source":"train_session = train.groupby('session').apply(lambda x: {\n    'aids': x['aid'].map(item2id).tolist(),\n    'types': x['type'].tolist()\n}).tolist()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T16:26:01.791584Z","iopub.execute_input":"2025-04-13T16:26:01.791787Z","iopub.status.idle":"2025-04-13T17:02:11.411149Z","shell.execute_reply.started":"2025-04-13T16:26:01.791772Z","shell.execute_reply":"2025-04-13T17:02:11.410128Z"}},"outputs":[{"name":"stderr","text":"/tmp/ipykernel_31/507928715.py:1: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.\n  train_session = train.groupby('session').apply(lambda x: {\n","output_type":"stream"}],"execution_count":20},{"cell_type":"code","source":"model, item2id = train_model(config, train_session, item2id)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T17:02:11.41202Z","iopub.execute_input":"2025-04-13T17:02:11.412393Z","iopub.status.idle":"2025-04-13T17:09:13.528855Z","shell.execute_reply.started":"2025-04-13T17:02:11.412369Z","shell.execute_reply":"2025-04-13T17:09:13.528132Z"}},"outputs":[{"name":"stdout","text":"Training started...\n","output_type":"stream"},{"name":"stderr","text":"/usr/local/lib/python3.11/dist-packages/torch/nn/modules/transformer.py:379: UserWarning: enable_nested_tensor is True, but self.use_nested_tensor is False because encoder_layer.self_attn.batch_first was not True(use batch_first for better inference performance)\n  warnings.warn(\n","output_type":"stream"},{"name":"stdout","text":"Model created\n","output_type":"stream"},{"name":"stderr","text":"Epoch 1: 100%|██████████| 86/86 [00:39<00:00,  2.16it/s]\n","output_type":"stream"},{"name":"stdout","text":"Epoch: 1 Loss: 1005.2982021570206\n","output_type":"stream"},{"name":"stderr","text":"Epoch 2: 100%|██████████| 86/86 [00:39<00:00,  2.18it/s]\n","output_type":"stream"},{"name":"stdout","text":"Epoch: 2 Loss: 970.6423815488815\n","output_type":"stream"},{"name":"stderr","text":"Epoch 3: 100%|██████████| 86/86 [00:40<00:00,  2.10it/s]\n","output_type":"stream"},{"name":"stdout","text":"Epoch: 3 Loss: 943.1725301742554\n","output_type":"stream"},{"name":"stderr","text":"Epoch 4: 100%|██████████| 86/86 [00:42<00:00,  2.01it/s]\n","output_type":"stream"},{"name":"stdout","text":"Epoch: 4 Loss: 887.9080243110657\n","output_type":"stream"},{"name":"stderr","text":"Epoch 5: 100%|██████████| 86/86 [00:41<00:00,  2.06it/s]\n","output_type":"stream"},{"name":"stdout","text":"Epoch: 5 Loss: 786.6129188537598\n","output_type":"stream"},{"name":"stderr","text":"Epoch 6: 100%|██████████| 86/86 [00:41<00:00,  2.07it/s]\n","output_type":"stream"},{"name":"stdout","text":"Epoch: 6 Loss: 700.5545690059662\n","output_type":"stream"},{"name":"stderr","text":"Epoch 7: 100%|██████████| 86/86 [00:42<00:00,  2.04it/s]\n","output_type":"stream"},{"name":"stdout","text":"Epoch: 7 Loss: 672.579372882843\n","output_type":"stream"},{"name":"stderr","text":"Epoch 8: 100%|██████████| 86/86 [00:42<00:00,  2.04it/s]\n","output_type":"stream"},{"name":"stdout","text":"Epoch: 8 Loss: 607.2662475705147\n","output_type":"stream"},{"name":"stderr","text":"Epoch 9: 100%|██████████| 86/86 [00:42<00:00,  2.05it/s]\n","output_type":"stream"},{"name":"stdout","text":"Epoch: 9 Loss: 555.2085301876068\n","output_type":"stream"},{"name":"stderr","text":"Epoch 10: 100%|██████████| 86/86 [00:41<00:00,  2.05it/s]","output_type":"stream"},{"name":"stdout","text":"Epoch: 10 Loss: 529.8927363753319\n","output_type":"stream"},{"name":"stderr","text":"\n","output_type":"stream"}],"execution_count":21},{"cell_type":"markdown","source":"# Making submission","metadata":{}},{"cell_type":"code","source":"def generate_predictions(model, test, item2id):\n    config = Config()\n    test_session = test.groupby('session').apply(lambda x: {\n        'aids': x['aid'].map(item2id).tolist(),\n        'types': x['type'].tolist()\n    }).tolist()\n\n    dataset = OttoDataset(test_session, config.max_len)\n    test_loader = DataLoader(dataset, batch_size=config.batch_size, shuffle=False)\n\n    model.eval()\n    clicks_preds, carts_preds, orders_preds = [], [], []\n    id2item = {v: k for k, v in item2id.items()}\n\n    with torch.no_grad():\n        for batch in tqdm(test_loader, desc='Generating predictions'):\n            aids = batch['aids'].to(config.device)\n            types = batch['types'].to(config.device)\n            mask = batch['mask'].to(config.device)\n\n            logits_clicks, logits_carts, logits_orders = model(aids, types, mask)\n\n            for logits, preds in zip(\n                [logits_clicks[:, -1], logits_carts[:, -1], logits_orders[:, -1]],\n                [clicks_preds, carts_preds, orders_preds]\n            ):\n                probs = torch.softmax(logits, dim=-1)\n                top20 = probs.topk(20).indices.cpu().numpy()\n                for row in top20:\n                    preds.append(' '.join(str(id2item.get(i, 0)) for i in row))\n\n    return clicks_preds, carts_preds, orders_preds","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T17:09:13.529799Z","iopub.execute_input":"2025-04-13T17:09:13.530192Z","iopub.status.idle":"2025-04-13T17:09:13.53751Z","shell.execute_reply.started":"2025-04-13T17:09:13.530175Z","shell.execute_reply":"2025-04-13T17:09:13.536842Z"}},"outputs":[],"execution_count":22},{"cell_type":"code","source":"clicks_preds, carts_preds, orders_preds = generate_predictions(model, test, item2id)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-04-13T17:09:13.538217Z","iopub.execute_input":"2025-04-13T17:09:13.53845Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"clicks_preds, carts_preds, orders_preds","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}