{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"tpuV5e8","dataSources":[{"sourceType":"competition","sourceId":38760,"databundleVersionId":4493939}],"dockerImageVersionId":31287,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import json\nimport pandas as pd\nfrom collections import defaultdict\nfrom tqdm.notebook import tqdm\nimport gc","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-03-05T08:02:58.905013Z","iopub.execute_input":"2026-03-05T08:02:58.905164Z","iopub.status.idle":"2026-03-05T08:03:02.996505Z","shell.execute_reply.started":"2026-03-05T08:02:58.905146Z","shell.execute_reply":"2026-03-05T08:03:02.995687Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"TYPE_WEIGHTS = {'clicks': 1, 'carts': 6, 'orders': 40}\nDEBUG = True        \nMAX_SESSIONS = 200_000 if DEBUG else None","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-05T08:03:02.997128Z","iopub.execute_input":"2026-03-05T08:03:02.997385Z","iopub.status.idle":"2026-03-05T08:03:03.000201Z","shell.execute_reply.started":"2026-03-05T08:03:02.997366Z","shell.execute_reply":"2026-03-05T08:03:02.999555Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Строим co-visitation матрицы\")\n\nclicks2clicks = defaultdict(lambda: defaultdict(int))\nclicks2carts  = defaultdict(lambda: defaultdict(int))\nclicks2orders = defaultdict(lambda: defaultdict(int))\n\npath = \"/kaggle/input/competitions/otto-recommender-system\"\n\nwith open(f\"{path}/train.jsonl\", \"r\") as f:\n    for i, line in enumerate(tqdm(f)):\n        if MAX_SESSIONS and i >= MAX_SESSIONS:\n            break\n        session = json.loads(line)\n        events = session[\"events\"]\n        \n        aids = [e[\"aid\"] for e in events]\n        types = [e[\"type\"] for e in events]\n        \n        for pos_i in range(len(aids)):\n            aid_i = aids[pos_i]\n            type_i = types[pos_i]\n            \n            for pos_j in range(pos_i + 1, len(aids)):\n                aid_j = aids[pos_j]\n                type_j = types[pos_j]\n                weight = TYPE_WEIGHTS[type_j]\n                \n                if type_i == \"clicks\":\n                    if type_j == \"clicks\":\n                        clicks2clicks[aid_i][aid_j] += weight\n                    elif type_j == \"carts\":\n                        clicks2carts[aid_i][aid_j] += weight\n                    else:\n                        clicks2orders[aid_i][aid_j] += weight\n\n\nfor matrix in [clicks2clicks, clicks2carts, clicks2orders]:\n    for aid in list(matrix.keys()):\n        matrix[aid] = dict(sorted(matrix[aid].items(), key=lambda x: x[1], reverse=True)[:40])\n\nprint(\"Матрицы построены!\")\ngc.collect()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-05T08:03:03.000639Z","iopub.execute_input":"2026-03-05T08:03:03.000796Z","iopub.status.idle":"2026-03-05T08:10:17.911046Z","shell.execute_reply.started":"2026-03-05T08:03:03.000780Z","shell.execute_reply":"2026-03-05T08:10:17.910326Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def get_recommendations(events):\n    if not events:\n        return [1460571, 1460572, 1460573]\n    \n    aids = [e[\"aid\"] for e in events]\n    last_aid = aids[-1]\n    \n    recs = list(dict.fromkeys(aids[::-1]))\n    \n    for matrix in [clicks2orders, clicks2carts, clicks2clicks]:\n        if last_aid in matrix:\n            recs.extend(list(matrix[last_aid].keys())[:30])\n    \n    recs.extend([1460571, 1460572, 1460573])\n    return list(dict.fromkeys(recs))[:20]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-05T08:10:17.911784Z","iopub.execute_input":"2026-03-05T08:10:17.911947Z","iopub.status.idle":"2026-03-05T08:10:17.915650Z","shell.execute_reply.started":"2026-03-05T08:10:17.911932Z","shell.execute_reply":"2026-03-05T08:10:17.914958Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Создаём submission\")\n\npreds = []\npath = \"/kaggle/input/competitions/otto-recommender-system\"\n\nwith open(f\"{path}/test.jsonl\", \"r\") as f:\n    for line in tqdm(f):\n        session = json.loads(line)\n        session_id = session[\"session\"]\n        recs = get_recommendations(session[\"events\"])\n        \n        for t in [\"clicks\", \"carts\", \"orders\"]:\n            preds.append({\n                \"session_type\": f\"{session_id}_{t}\",\n                \"labels\": \" \".join(map(str, recs))\n            })\n\nsub = pd.DataFrame(preds)\nsub.to_csv(\"submission.csv\", index=False)\n\nprint(f\"Submission готов Строк: {len(sub)}\")\nsub.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-05T08:10:17.916248Z","iopub.execute_input":"2026-03-05T08:10:17.916421Z","iopub.status.idle":"2026-03-05T08:11:19.260026Z","shell.execute_reply.started":"2026-03-05T08:10:17.916406Z","shell.execute_reply":"2026-03-05T08:11:19.259159Z"}},"outputs":[],"execution_count":null}]}