{"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":"none","dataSources":[{"sourceId":38760,"databundleVersionId":4493939,"sourceType":"competition"}],"dockerImageVersionId":31040,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import time\nimport orjson\nfrom collections import defaultdict, Counter\nimport pandas as pd\nfrom lightgbm import LGBMClassifier\nfrom sklearn.model_selection import train_test_split\n\nDATA_DIR = '/kaggle/input/otto-recommender-system'\nTRAIN_PATH = f'{DATA_DIR}/train.jsonl'\nTEST_PATH = f'{DATA_DIR}/test.jsonl'\nMAX_TRAIN_SESSIONS = 2_000_000\nTOP_K_POPULAR = 100\nEVENT_WEIGHTS = {'clicks': 1, 'carts': 3, 'orders': 5}\n\n\ndef compute_item_popularity(file_path, max_sessions, weights):\n    item_popularity = Counter()\n    start_time = time.time()\n\n    with open(file_path, 'r') as file:\n        for session_idx, line in enumerate(file, 1):\n            session_data = orjson.loads(line)\n            for event in session_data['events']:\n                item_popularity[event['aid']] += weights[event['type']]\n            if session_idx >= max_sessions:\n                break\n\n    print(f\"[Popularity] Processed {session_idx} sessions in {time.time() - start_time:.2f}s\")\n    return item_popularity\n\n\nitem_popularity = compute_item_popularity(TRAIN_PATH, MAX_TRAIN_SESSIONS, EVENT_WEIGHTS)\ntop_popular_items = [item for item, _ in item_popularity.most_common(TOP_K_POPULAR)]\n\n\ndef generate_training_data(file_path, max_sessions, top_items, item_popularity):\n    training_rows = []\n    start_time = time.time()\n\n    with open(file_path, 'r') as file:\n        for session_idx, line in enumerate(file, 1):\n            if session_idx > max_sessions:\n                break\n\n            session_data = orjson.loads(line)\n            events = session_data['events']\n\n            recent_items = []\n            for event in reversed(events):\n                if event['aid'] not in recent_items:\n                    recent_items.append(event['aid'])\n                if len(recent_items) == 5:\n                    break\n\n            candidates = set(recent_items)\n            for item in top_items:\n                if len(candidates) >= 10:\n                    break\n                candidates.add(item)\n\n            stats = defaultdict(lambda: {'clicks': 0, 'carts': 0, 'orders': 0, 'first_pos': -1, 'last_pos': -1})\n            for idx, event in enumerate(events):\n                if event['aid'] in candidates:\n                    if stats[event['aid']]['first_pos'] == -1:\n                        stats[event['aid']]['first_pos'] = idx\n                    stats[event['aid']]['last_pos'] = idx\n                    stats[event['aid']][event['type']] += 1\n\n            for item, stat in stats.items():\n                training_rows.append({\n                    'clicks': stat['clicks'],\n                    'carts': stat['carts'],\n                    'orders': stat['orders'],\n                    'first_pos': stat['first_pos'],\n                    'last_pos': stat['last_pos'],\n                    'popularity': item_popularity[item],\n                    'label': int(stat['orders'] > 0)\n                })\n\n    print(f\"[Training Data] Generated {len(training_rows)} rows in {time.time() - start_time:.2f}s\")\n    return pd.DataFrame(training_rows)\n\n\ntraining_data = generate_training_data(TRAIN_PATH, MAX_TRAIN_SESSIONS, top_popular_items, item_popularity)\nfeature_columns = ['clicks', 'carts', 'orders', 'first_pos', 'last_pos', 'popularity']\n\ndef train_lightgbm_model(data, features):\n    X = data[features]\n    y = data['label']\n    X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.1, random_state=42, stratify=y)\n\n    model = LGBMClassifier(\n        objective='binary',\n        n_estimators=200,\n        learning_rate=0.1,\n        num_leaves=31,\n        random_state=42\n    )\n\n    start_time = time.time()\n    model.fit(X_train, y_train)\n    print(f\"[Model Training] Completed in {time.time() - start_time:.2f}s\")\n    return model\n\n\nmodel = train_lightgbm_model(training_data, feature_columns)\n\ndef create_submission(file_path, top_items, item_popularity, model, features, output_file='submission.csv'):\n    predictions = []\n    start_time = time.time()\n\n    with open(file_path, 'r') as file:\n        for line in file:\n            session_data = orjson.loads(line)\n            events = session_data['events']\n\n            recent_items = []\n            for event in reversed(events):\n                if event['aid'] not in recent_items:\n                    recent_items.append(event['aid'])\n                if len(recent_items) == 5:\n                    break\n\n            candidates = set(recent_items)\n            for item in top_items:\n                if len(candidates) >= 10:\n                    break\n                candidates.add(item)\n\n            candidate_features = []\n            for item in candidates:\n                stats = {'clicks': 0, 'carts': 0, 'orders': 0, 'first_pos': -1, 'last_pos': -1}\n                for idx, event in enumerate(events):\n                    if event['aid'] == item:\n                        if stats['first_pos'] == -1:\n                            stats['first_pos'] = idx\n                        stats['last_pos'] = idx\n                        stats[event['type']] += 1\n                stats['popularity'] = item_popularity[item]\n                stats['aid'] = item\n                candidate_features.append(stats)\n\n            candidate_df = pd.DataFrame(candidate_features)\n            candidate_df['score'] = model.predict_proba(candidate_df[features])[:, 1]\n            top_10_items = candidate_df.sort_values('score', ascending=False).head(10)['aid'].tolist()\n\n            session_id = session_data['session']\n            labels = ' '.join(map(str, top_10_items))\n            predictions.extend([\n                {'session_type': f'{session_id}_clicks', 'labels': labels},\n                {'session_type': f'{session_id}_carts', 'labels': labels},\n                {'session_type': f'{session_id}_orders', 'labels': labels}\n            ])\n\n    print(f\"[Submission] Generated {len(predictions)} rows in {time.time() - start_time:.2f}s\")\n    pd.DataFrame(predictions).to_csv(output_file, index=False)\n\n\ncreate_submission(TEST_PATH, top_popular_items, item_popularity, model, feature_columns)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-06-19T12:15:30.605657Z","iopub.execute_input":"2025-06-19T12:15:30.605977Z"}},"outputs":[],"execution_count":null}]}