{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","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"},"papermill":{"default_parameters":{},"duration":81.439701,"end_time":"2022-12-31T23:29:03.035983","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2022-12-31T23:27:41.596282","version":"2.3.4"},"kaggle":{"accelerator":"none","dataSources":[{"sourceType":"competition","sourceId":38760,"databundleVersionId":4493939},{"sourceType":"datasetVersion","sourceId":4461402,"datasetId":2611514,"databundleVersionId":4521320}],"dockerImageVersionId":31286,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"id":"a201a4cd","cell_type":"code","source":"import polars as pl","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:27.296555Z","iopub.execute_input":"2026-03-04T19:30:27.297142Z","iopub.status.idle":"2026-03-04T19:30:27.798549Z","shell.execute_reply.started":"2026-03-04T19:30:27.297119Z","shell.execute_reply":"2026-03-04T19:30:27.797916Z"},"papermill":{"duration":0.072112,"end_time":"2022-12-31T23:28:06.701020","exception":false,"start_time":"2022-12-31T23:28:06.628908","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"4a959a8b","cell_type":"code","source":"train = pl.read_parquet('/kaggle/input/datasets/radek1/otto-train-and-test-data-for-local-validation/test.parquet')\ntrain_labels = pl.read_parquet('/kaggle/input/datasets/radek1/otto-train-and-test-data-for-local-validation/test_labels.parquet')","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:27.799672Z","iopub.execute_input":"2026-03-04T19:30:27.800226Z","iopub.status.idle":"2026-03-04T19:30:29.435356Z","shell.execute_reply.started":"2026-03-04T19:30:27.800195Z","shell.execute_reply":"2026-03-04T19:30:29.434656Z"},"papermill":{"duration":1.046101,"end_time":"2022-12-31T23:28:07.759432","exception":false,"start_time":"2022-12-31T23:28:06.713331","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"ad617b4c","cell_type":"markdown","source":"## Построим новые признаки:","metadata":{"execution":{"iopub.execute_input":"2022-12-31T23:28:07.803877Z","iopub.status.busy":"2022-12-31T23:28:07.803496Z","iopub.status.idle":"2022-12-31T23:28:07.813444Z","shell.execute_reply":"2022-12-31T23:28:07.812249Z"},"papermill":{"duration":0.024222,"end_time":"2022-12-31T23:28:07.815837","exception":false,"start_time":"2022-12-31T23:28:07.791615","status":"completed"},"tags":[]}},{"id":"e96b63d3","cell_type":"markdown","source":"1. Давность действия внутри сессии:","metadata":{}},{"id":"fdf3d325","cell_type":"code","source":"train = train.select(\n    [\n        pl.all(),\n        pl.col(\"session\")\n          .cum_count(reverse=True)   # newer Polars\n          .over(\"session\")\n          .alias(\"action_rev_index\")\n    ]\n)","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:29.436551Z","iopub.execute_input":"2026-03-04T19:30:29.436827Z","iopub.status.idle":"2026-03-04T19:30:30.856493Z","shell.execute_reply.started":"2026-03-04T19:30:29.436801Z","shell.execute_reply":"2026-03-04T19:30:30.855833Z"},"papermill":{"duration":0.019381,"end_time":"2022-12-31T23:28:07.846107","exception":false,"start_time":"2022-12-31T23:28:07.826726","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"08770262","cell_type":"markdown","source":"2. Длина сессии:","metadata":{}},{"id":"ddddcc32","cell_type":"code","source":"train = train.with_columns(\n    pl.col('session').count().over('session').alias('session_length')\n)","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:30.857948Z","iopub.execute_input":"2026-03-04T19:30:30.858187Z","iopub.status.idle":"2026-03-04T19:30:31.033837Z","shell.execute_reply.started":"2026-03-04T19:30:30.858166Z","shell.execute_reply":"2026-03-04T19:30:31.033148Z"},"papermill":{"duration":7.32039,"end_time":"2022-12-31T23:28:15.177539","exception":false,"start_time":"2022-12-31T23:28:07.857149","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"59f9c0c3","cell_type":"markdown","source":"3. Логарифм от давности действия внутри сессии","metadata":{}},{"id":"c5f4499b","cell_type":"code","source":"eps = 0.2\nlinear_interpolation = eps + (((1 - eps) / (train['session_length'] - 1)) * (train['session_length'] - train['action_rev_index'] - 1))\nscores = 2 ** linear_interpolation - 1\ntrain = train.with_columns(pl.Series(scores).alias('log_recency_score')).fill_nan(1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-04T19:30:31.034592Z","iopub.execute_input":"2026-03-04T19:30:31.034775Z","iopub.status.idle":"2026-03-04T19:30:31.357678Z","shell.execute_reply.started":"2026-03-04T19:30:31.034756Z","shell.execute_reply":"2026-03-04T19:30:31.357150Z"}},"outputs":[],"execution_count":null},{"id":"eab003c8","cell_type":"markdown","source":"4. Логарифм от давности действия внутри сессии, деленный на характеристику события","metadata":{}},{"id":"67ddf698","cell_type":"code","source":"type_weights = {0: 1, 1: 6, 2: 3}\n\ntrain = train.with_columns((pl.col(\"log_recency_score\") / pl.col(\"type\").replace(type_weights)).alias(\"weighted_log_recency\"))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-03-04T19:30:31.358517Z","iopub.execute_input":"2026-03-04T19:30:31.358759Z","iopub.status.idle":"2026-03-04T19:30:31.500281Z","shell.execute_reply.started":"2026-03-04T19:30:31.358733Z","shell.execute_reply":"2026-03-04T19:30:31.499572Z"}},"outputs":[],"execution_count":null},{"id":"437afe37","cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:31.501023Z","iopub.execute_input":"2026-03-04T19:30:31.501199Z","iopub.status.idle":"2026-03-04T19:30:31.510738Z","shell.execute_reply.started":"2026-03-04T19:30:31.501182Z","shell.execute_reply":"2026-03-04T19:30:31.510196Z"},"papermill":{"duration":0.026561,"end_time":"2022-12-31T23:28:15.235879","exception":false,"start_time":"2022-12-31T23:28:15.209318","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"641a1b95","cell_type":"markdown","source":"Теперь обработаем метки для обучения модели, развернём ground_truth и соединим их с основной таблицей.","metadata":{}},{"id":"27768e9e","cell_type":"code","source":"type_mapping = {\"clicks\": 0, \"carts\": 1, \"orders\": 2}\n\ntrain_labels = (\n    train_labels\n    .explode(\"ground_truth\")\n    .with_columns(\n        aid=pl.col(\"ground_truth\"),\n        type=pl.col(\"type\").replace(type_mapping),\n    )\n    .select(\"session\", \"type\", \"aid\")\n)","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:31.511552Z","iopub.execute_input":"2026-03-04T19:30:31.511771Z","iopub.status.idle":"2026-03-04T19:30:31.649349Z","shell.execute_reply.started":"2026-03-04T19:30:31.511749Z","shell.execute_reply":"2026-03-04T19:30:31.648747Z"},"papermill":{"duration":1.427655,"end_time":"2022-12-31T23:28:16.725567","exception":false,"start_time":"2022-12-31T23:28:15.297912","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"af9b5b74","cell_type":"code","source":"train_labels = train_labels.with_columns([\n    pl.col('session').cast(pl.datatypes.Int32),\n    pl.col('type').cast(pl.datatypes.UInt8),\n    pl.col('aid').cast(pl.datatypes.Int32)\n])","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:31.650043Z","iopub.execute_input":"2026-03-04T19:30:31.650219Z","iopub.status.idle":"2026-03-04T19:30:31.673901Z","shell.execute_reply.started":"2026-03-04T19:30:31.650202Z","shell.execute_reply":"2026-03-04T19:30:31.673301Z"},"papermill":{"duration":0.055449,"end_time":"2022-12-31T23:28:16.792919","exception":false,"start_time":"2022-12-31T23:28:16.737470","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"6762338b","cell_type":"code","source":"train_labels = train_labels.with_columns(gt=pl.lit(1))","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:31.675870Z","iopub.execute_input":"2026-03-04T19:30:31.676085Z","iopub.status.idle":"2026-03-04T19:30:31.679396Z","shell.execute_reply.started":"2026-03-04T19:30:31.676067Z","shell.execute_reply":"2026-03-04T19:30:31.678805Z"},"papermill":{"duration":0.02694,"end_time":"2022-12-31T23:28:16.831181","exception":false,"start_time":"2022-12-31T23:28:16.804241","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"2cf3624f","cell_type":"code","source":"train = train.join(train_labels, how='left', on=['session', 'type', 'aid']).with_columns(\n    pl.col('gt').fill_null(0)\n)","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:31.680186Z","iopub.execute_input":"2026-03-04T19:30:31.680408Z","iopub.status.idle":"2026-03-04T19:30:32.077961Z","shell.execute_reply.started":"2026-03-04T19:30:31.680379Z","shell.execute_reply":"2026-03-04T19:30:32.077310Z"},"papermill":{"duration":1.224971,"end_time":"2022-12-31T23:28:18.067584","exception":false,"start_time":"2022-12-31T23:28:16.842613","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"43b36520","cell_type":"code","source":"train.head()","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:32.078701Z","iopub.execute_input":"2026-03-04T19:30:32.078939Z","iopub.status.idle":"2026-03-04T19:30:32.083876Z","shell.execute_reply.started":"2026-03-04T19:30:32.078897Z","shell.execute_reply":"2026-03-04T19:30:32.083271Z"},"papermill":{"duration":0.030567,"end_time":"2022-12-31T23:28:18.115056","exception":false,"start_time":"2022-12-31T23:28:18.084489","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"0cb5477f","cell_type":"markdown","source":"Теперь у нас есть предобработанный набор с колонкой ground truth. Осталось вычислить длины сессий, чтобы сгруппировать строки перед обучением","metadata":{}},{"id":"99c83641","cell_type":"code","source":"session_lengths_train = train.group_by('session').agg([pl.col('session').count().alias('session_length')])['session_length'].to_numpy()","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:32.084875Z","iopub.execute_input":"2026-03-04T19:30:32.085125Z","iopub.status.idle":"2026-03-04T19:30:32.194352Z","shell.execute_reply.started":"2026-03-04T19:30:32.085101Z","shell.execute_reply":"2026-03-04T19:30:32.193755Z"},"papermill":{"duration":0.930103,"end_time":"2022-12-31T23:28:19.113051","exception":false,"start_time":"2022-12-31T23:28:18.182948","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"87dd39c0","cell_type":"markdown","source":"## Обучение модели","metadata":{}},{"id":"fe62aee1","cell_type":"code","source":"from lightgbm.sklearn import LGBMRanker","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:32.195110Z","iopub.execute_input":"2026-03-04T19:30:32.195301Z","iopub.status.idle":"2026-03-04T19:30:35.028365Z","shell.execute_reply.started":"2026-03-04T19:30:32.195285Z","shell.execute_reply":"2026-03-04T19:30:35.027737Z"},"papermill":{"duration":1.788573,"end_time":"2022-12-31T23:28:20.935133","exception":false,"start_time":"2022-12-31T23:28:19.146560","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"c3709c66","cell_type":"code","source":"ranker = LGBMRanker(\n    objective=\"lambdarank\",\n    metric=\"ndcg\",\n    boosting_type=\"gbdt\",\n    n_estimators=30,\n    importance_type='gain',\n    learning_rate=0.1,\n    random_state=42,\n)","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:35.029314Z","iopub.execute_input":"2026-03-04T19:30:35.029745Z","iopub.status.idle":"2026-03-04T19:30:35.034163Z","shell.execute_reply.started":"2026-03-04T19:30:35.029721Z","shell.execute_reply":"2026-03-04T19:30:35.033331Z"},"papermill":{"duration":0.020613,"end_time":"2022-12-31T23:28:20.967430","exception":false,"start_time":"2022-12-31T23:28:20.946817","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"63e278ca","cell_type":"code","source":"train.columns","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:35.034858Z","iopub.execute_input":"2026-03-04T19:30:35.035059Z","iopub.status.idle":"2026-03-04T19:30:35.049477Z","shell.execute_reply.started":"2026-03-04T19:30:35.035043Z","shell.execute_reply":"2026-03-04T19:30:35.048983Z"},"papermill":{"duration":0.020355,"end_time":"2022-12-31T23:28:20.999363","exception":false,"start_time":"2022-12-31T23:28:20.979008","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"ada24443","cell_type":"code","source":"feature_columns = ['aid', 'type', 'action_rev_index', 'session_length', 'log_recency_score', 'weighted_log_recency']\ntarget_col = 'gt'","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:35.050370Z","iopub.execute_input":"2026-03-04T19:30:35.050858Z","iopub.status.idle":"2026-03-04T19:30:35.058409Z","shell.execute_reply.started":"2026-03-04T19:30:35.050834Z","shell.execute_reply":"2026-03-04T19:30:35.057787Z"},"papermill":{"duration":0.019579,"end_time":"2022-12-31T23:28:21.030471","exception":false,"start_time":"2022-12-31T23:28:21.010892","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"e82a827b","cell_type":"code","source":"ranker = ranker.fit(\n    train[feature_columns].to_pandas(),\n    train[target_col].to_pandas(),\n    group=session_lengths_train,\n)","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:35.059200Z","iopub.execute_input":"2026-03-04T19:30:35.059427Z","iopub.status.idle":"2026-03-04T19:30:49.694701Z","shell.execute_reply.started":"2026-03-04T19:30:35.059410Z","shell.execute_reply":"2026-03-04T19:30:49.693841Z"},"papermill":{"duration":16.251618,"end_time":"2022-12-31T23:28:37.293692","exception":false,"start_time":"2022-12-31T23:28:21.042074","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"21bf0cca","cell_type":"markdown","source":"## Предсказание на тестовых данных","metadata":{}},{"id":"6463c5e8","cell_type":"markdown","source":"Загружаем тестовый набор, применяем те же признаки и получаем предсказания","metadata":{}},{"id":"828a42c6","cell_type":"code","source":"test = pl.read_ndjson('/kaggle/input/competitions/otto-recommender-system/test.jsonl')\n\ntest = (\n    test\n    .explode(\"events\")\n    .unnest(\"events\")\n    .with_columns(\n        pl.col(\"session\").cast(pl.Int32),\n        pl.col(\"aid\").cast(pl.Int32),\n        (pl.col(\"ts\") // 1000).cast(pl.Int32),\n        pl.col(\"type\").replace(type_mapping).cast(pl.UInt8),\n    )\n    .select(\"session\", \"aid\", \"ts\", \"type\")\n)\n\neps = 0.2\ntype_weights = {0: 1, 1: 6, 2: 3}\n\ntest = test.with_columns([\n    pl.col(\"session\").cum_count(reverse=True).over(\"session\").alias(\"action_rev_index\"),\n    pl.len().over(\"session\").alias(\"session_length\"),\n]).with_columns([\n    (2 ** (eps + (((1 - eps) / (pl.col(\"session_length\") - 1)) * (pl.col(\"session_length\") - pl.col(\"action_rev_index\") - 1))) - 1).fill_nan(1.0).fill_null(1.0).alias(\"log_recency_score\"),\n]).with_columns([\n    (pl.col(\"log_recency_score\") / pl.col(\"type\").replace(type_weights)).alias(\"weighted_log_recency\")\n])","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:49.695548Z","iopub.execute_input":"2026-03-04T19:30:49.695774Z","iopub.status.idle":"2026-03-04T19:30:57.950498Z","shell.execute_reply.started":"2026-03-04T19:30:49.695754Z","shell.execute_reply":"2026-03-04T19:30:57.949845Z"},"papermill":{"duration":7.25803,"end_time":"2022-12-31T23:28:44.611299","exception":false,"start_time":"2022-12-31T23:28:37.353269","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"74ca52ef","cell_type":"code","source":"scores_pred = ranker.predict(test[feature_columns].to_pandas())","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:30:57.951317Z","iopub.execute_input":"2026-03-04T19:30:57.951495Z","iopub.status.idle":"2026-03-04T19:31:00.576794Z","shell.execute_reply.started":"2026-03-04T19:30:57.951478Z","shell.execute_reply":"2026-03-04T19:31:00.576202Z"},"papermill":{"duration":2.887118,"end_time":"2022-12-31T23:28:47.510440","exception":false,"start_time":"2022-12-31T23:28:44.623322","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"3dc5f07d","cell_type":"markdown","source":"## Формирование сабмита","metadata":{}},{"id":"af1d4c66","cell_type":"code","source":"test = test.with_columns(pl.Series(\"score\", scores_pred))\n\ntest_predictions = (\n    test.sort([\"session\", \"score\"], descending=[False, True])\n    .group_by(\"session\")\n    .agg(pl.col(\"aid\").head(20).alias(\"aid\"))\n)","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:31:00.577616Z","iopub.execute_input":"2026-03-04T19:31:00.577840Z","iopub.status.idle":"2026-03-04T19:31:00.847362Z","shell.execute_reply.started":"2026-03-04T19:31:00.577815Z","shell.execute_reply":"2026-03-04T19:31:00.846694Z"},"papermill":{"duration":0.79494,"end_time":"2022-12-31T23:28:48.341566","exception":false,"start_time":"2022-12-31T23:28:47.546626","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"bd6d1b09","cell_type":"code","source":"session_types = []\nlabels = []\n\nfor session, preds in zip(test_predictions['session'].to_numpy(), test_predictions['aid'].to_numpy()):\n    l = ' '.join(str(p) for p in preds)\n    for session_type in ['clicks', 'carts', 'orders']:\n        labels.append(l)\n        session_types.append(f'{session}_{session_type}')\n","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:31:00.848076Z","iopub.execute_input":"2026-03-04T19:31:00.848265Z","iopub.status.idle":"2026-03-04T19:31:06.852236Z","shell.execute_reply.started":"2026-03-04T19:31:00.848244Z","shell.execute_reply":"2026-03-04T19:31:06.851563Z"},"papermill":{"duration":10.374822,"end_time":"2022-12-31T23:28:58.751455","exception":false,"start_time":"2022-12-31T23:28:48.376633","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"id":"fa3a41f3","cell_type":"code","source":"submission = pl.DataFrame({'session_type': session_types, 'labels': labels})\nsubmission.write_csv('/kaggle/working/submission.csv')\n","metadata":{"execution":{"iopub.status.busy":"2026-03-04T19:31:06.852918Z","iopub.execute_input":"2026-03-04T19:31:06.853150Z","iopub.status.idle":"2026-03-04T19:31:08.225477Z","shell.execute_reply.started":"2026-03-04T19:31:06.853128Z","shell.execute_reply":"2026-03-04T19:31:08.224869Z"},"papermill":{"duration":2.634391,"end_time":"2022-12-31T23:29:01.398070","exception":false,"start_time":"2022-12-31T23:28:58.763679","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null}]}