{"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":104854,"databundleVersionId":12637092,"sourceType":"competition"}],"dockerImageVersionId":31040,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"### Class Exclusive Merchants + Spendings Buckets","metadata":{}},{"cell_type":"code","source":"import pandas as pd\n\ntrain = pd.read_parquet('/kaggle/input/alpha-summer-challenge/train.pa')\ntransactions = pd.read_parquet('/kaggle/input/alpha-summer-challenge/df_transaction.pa')\n\ntrain_clients = set(train['client_num'])\ntest_clients = set(transactions['client_num']) - train_clients\n\ntrain_txns = transactions[transactions['client_num'].isin(train_clients)].merge(train, on='client_num')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-05T06:21:34.726251Z","iopub.execute_input":"2025-07-05T06:21:34.726756Z","iopub.status.idle":"2025-07-05T06:21:45.091177Z","shell.execute_reply.started":"2025-07-05T06:21:34.726717Z","shell.execute_reply":"2025-07-05T06:21:45.089903Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Find exclusive merchants for each target class\nexclusive_by_target = {}\n\nfor target in range(7):\n    target_merchants = set(train_txns[train_txns['target'] == target]['merchant_name'])\n    other_merchants = set(train_txns[train_txns['target'] != target]['merchant_name'])\n    exclusive_by_target[target] = target_merchants - other_merchants\n\ntest_txns = transactions[transactions['client_num'].isin(test_clients)]\ntest_features = test_txns.groupby('client_num').agg({\n    'amount': 'sum',\n    'merchant_name': lambda x: set(x)\n}).reset_index()\n\ntest_features.columns = ['client_num', 'total_amount', 'merchants']","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-07-05T06:21:45.092858Z","iopub.execute_input":"2025-07-05T06:21:45.093229Z","iopub.status.idle":"2025-07-05T06:22:03.609857Z","shell.execute_reply.started":"2025-07-05T06:21:45.093190Z","shell.execute_reply":"2025-07-05T06:22:03.609016Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def predict(row):\n    client_merchants = row['merchants']\n    \n    # Check exclusive merchants first\n    for target, exclusive_merchants in exclusive_by_target.items():\n        if client_merchants & exclusive_merchants:\n            return target\n    \n    # Fallback to spending buckets (based on training data analysis)\n    amount = row['total_amount']\n    if amount < 130000: return 0      # Class 0: mean 199k\n    elif amount < 200000: return 1    # Class 1: mean 171k  \n    elif amount < 240000: return 2    # Class 2: mean 219k\n    elif amount < 310000: return 3    # Class 3: mean 260k\n    elif amount < 435000: return 4    # Class 4: mean 360k\n    elif amount < 670000: return 5    # Class 5: mean 509k\n    else: return 6                    # Class 6: mean 825k","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-05T06:20:02.683620Z","iopub.execute_input":"2025-07-05T06:20:02.683980Z","iopub.status.idle":"2025-07-05T06:20:02.691470Z","shell.execute_reply.started":"2025-07-05T06:20:02.683953Z","shell.execute_reply":"2025-07-05T06:20:02.690236Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_features['target'] = test_features.apply(predict, axis=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-05T06:20:05.535689Z","iopub.execute_input":"2025-07-05T06:20:05.536110Z","iopub.status.idle":"2025-07-05T06:20:06.093097Z","shell.execute_reply.started":"2025-07-05T06:20:05.536084Z","shell.execute_reply":"2025-07-05T06:20:06.091914Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission = pd.DataFrame({\n    'client_num': list(test_clients),\n    'target': 1 \n})\nsubmission = submission.merge(test_features[['client_num', 'target']], on='client_num', how='left', suffixes=['', '_pred'])\nsubmission['target'] = submission['target_pred'].fillna(submission['target']).astype(int)\nsubmission = submission[['client_num', 'target']].sort_values('client_num')\n\nsubmission.to_csv('submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-05T06:20:12.022523Z","iopub.execute_input":"2025-07-05T06:20:12.022900Z","iopub.status.idle":"2025-07-05T06:20:12.092326Z","shell.execute_reply.started":"2025-07-05T06:20:12.022873Z","shell.execute_reply":"2025-07-05T06:20:12.091223Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"-------\n\nBored here? Have fun [there](https://www.kaggle.com/code/samvelkoch/alfa-features-kitchen)!","metadata":{}}]}