{"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":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:28.260312Z","iopub.execute_input":"2025-07-08T22:41:28.260742Z","iopub.status.idle":"2025-07-08T22:41:28.269891Z","shell.execute_reply.started":"2025-07-08T22:41:28.260711Z","shell.execute_reply":"2025-07-08T22:41:28.268885Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Загрузка данных\ndf_train = pd.read_parquet(\"/kaggle/input/alpha-summer-challenge/train.pa\")\ndf_txn   = pd.read_parquet(\"/kaggle/input/alpha-summer-challenge/df_transaction.pa\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:29.209540Z","iopub.execute_input":"2025-07-08T22:41:29.209881Z","iopub.status.idle":"2025-07-08T22:41:36.020421Z","shell.execute_reply.started":"2025-07-08T22:41:29.209859Z","shell.execute_reply":"2025-07-08T22:41:36.019411Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def pivot_client_mcc(df_txn: pd.DataFrame, df_train: pd.DataFrame) -> pd.DataFrame:\n    df_pivot = df_txn[['client_num', 'mcc_code', 'amount']].groupby(\n        ['client_num', 'mcc_code']).agg(sum_amount=('amount','sum')).reset_index()\n    df_pivot_format = pd.pivot_table(\n        df_pivot, values='sum_amount', index=['client_num'], columns=['mcc_code']).fillna(0)\n    df = (df_pivot_format.T/df_pivot_format.sum(axis=1)).T.reset_index()\n    return df.merge(df_train, on='client_num', how='left')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:36.022498Z","iopub.execute_input":"2025-07-08T22:41:36.022926Z","iopub.status.idle":"2025-07-08T22:41:36.031162Z","shell.execute_reply.started":"2025-07-08T22:41:36.022893Z","shell.execute_reply":"2025-07-08T22:41:36.030190Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_merged = pivot_client_mcc(df_txn, df_train)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:36.032426Z","iopub.execute_input":"2025-07-08T22:41:36.032799Z","iopub.status.idle":"2025-07-08T22:41:40.542671Z","shell.execute_reply.started":"2025-07-08T22:41:36.032768Z","shell.execute_reply":"2025-07-08T22:41:40.541264Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_merged","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:40.545303Z","iopub.execute_input":"2025-07-08T22:41:40.545756Z","iopub.status.idle":"2025-07-08T22:41:40.635496Z","shell.execute_reply.started":"2025-07-08T22:41:40.545722Z","shell.execute_reply":"2025-07-08T22:41:40.633964Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Сумма вероятностей отчислений по МСС-коду по всем клиентам\ndf_valid = pd.DataFrame(df_merged.sum(axis=0).sort_values().iloc[:-2], columns=[\"total_probs\"])\n# Доля суммы вероятностей\ndf_valid[\"frac\"] = df_valid[\"total_probs\"]/df_valid[\"total_probs\"].sum()*100\ndf_valid[\"frac\"] = df_valid[\"frac\"].apply(lambda x: f'{x:.5f}')\n# Процент пустых MMC-кодов по всем клиентам\ndf_valid['Empty MCC'] = (df_merged == 0).sum(axis=0).iloc[1:-1]/df_merged.shape[0]*100\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:40.638091Z","iopub.execute_input":"2025-07-08T22:41:40.638688Z","iopub.status.idle":"2025-07-08T22:41:40.925822Z","shell.execute_reply.started":"2025-07-08T22:41:40.638643Z","shell.execute_reply":"2025-07-08T22:41:40.924659Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_valid.sort_values(by='frac', ascending=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:40.927332Z","iopub.execute_input":"2025-07-08T22:41:40.927685Z","iopub.status.idle":"2025-07-08T22:41:40.941985Z","shell.execute_reply.started":"2025-07-08T22:41:40.927662Z","shell.execute_reply":"2025-07-08T22:41:40.940822Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_merged.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:40.942857Z","iopub.execute_input":"2025-07-08T22:41:40.943148Z","iopub.status.idle":"2025-07-08T22:41:40.970210Z","shell.execute_reply.started":"2025-07-08T22:41:40.943120Z","shell.execute_reply":"2025-07-08T22:41:40.969100Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_with_target = df_merged[df_merged['target'].notna()]\ndf_without_target = df_merged[df_merged['target'].isna()]\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:40.971273Z","iopub.execute_input":"2025-07-08T22:41:40.971554Z","iopub.status.idle":"2025-07-08T22:41:41.132890Z","shell.execute_reply.started":"2025-07-08T22:41:40.971533Z","shell.execute_reply":"2025-07-08T22:41:41.131796Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_without_target","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:41.133838Z","iopub.execute_input":"2025-07-08T22:41:41.134077Z","iopub.status.idle":"2025-07-08T22:41:41.177356Z","shell.execute_reply.started":"2025-07-08T22:41:41.134058Z","shell.execute_reply":"2025-07-08T22:41:41.176005Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_with_target.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:41.180182Z","iopub.execute_input":"2025-07-08T22:41:41.180496Z","iopub.status.idle":"2025-07-08T22:41:41.187278Z","shell.execute_reply.started":"2025-07-08T22:41:41.180471Z","shell.execute_reply":"2025-07-08T22:41:41.186276Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\n# Разделение признаков и целевую переменную\nX = df_with_target.drop(columns=['client_num','target'])\ny = df_with_target['target']\n\n# Разделение на тестовую и валидационную выборки\nX_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, test_size=0.2, random_state=42)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:41.188264Z","iopub.execute_input":"2025-07-08T22:41:41.188592Z","iopub.status.idle":"2025-07-08T22:41:41.424823Z","shell.execute_reply.started":"2025-07-08T22:41:41.188568Z","shell.execute_reply":"2025-07-08T22:41:41.423557Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.ensemble import RandomForestClassifier\nfrom sklearn.metrics import classification_report, confusion_matrix\nfrom sklearn.model_selection import train_test_split","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:41.425944Z","iopub.execute_input":"2025-07-08T22:41:41.426311Z","iopub.status.idle":"2025-07-08T22:41:41.431775Z","shell.execute_reply.started":"2025-07-08T22:41:41.426285Z","shell.execute_reply":"2025-07-08T22:41:41.430682Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Обучение модели\nclf = RandomForestClassifier(\n    n_estimators=100,\n    max_depth=10,\n    class_weight='balanced', \n    random_state=42\n)\nclf.fit(X_train, y_train)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:41.432704Z","iopub.execute_input":"2025-07-08T22:41:41.433055Z","iopub.status.idle":"2025-07-08T22:41:53.023301Z","shell.execute_reply.started":"2025-07-08T22:41:41.432979Z","shell.execute_reply":"2025-07-08T22:41:53.022117Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Предсказание\ny_pred = clf.predict(X_test)\n\n# Оценка\nprint(classification_report(y_test, y_pred, digits=3))\nprint(confusion_matrix(y_test, y_pred))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:53.024344Z","iopub.execute_input":"2025-07-08T22:41:53.025101Z","iopub.status.idle":"2025-07-08T22:41:53.458797Z","shell.execute_reply.started":"2025-07-08T22:41:53.025068Z","shell.execute_reply":"2025-07-08T22:41:53.457546Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Веса по классам\nclass_weights = {\n    0: 1.00,\n    1: 0.72,\n    2: 0.52,\n    3: 0.37,\n    4: 0.27,\n    5: 0.19,\n    6: 0.14,\n    7: 0.1\n}\n\ndef wmae(y_true, y_pred, weights_map):\n    weights = np.array([weights_map.get(y, 0.0) for y in y_true])\n    abs_errors = np.abs(y_true - y_pred)\n    return np.sum(weights * abs_errors) / np.sum(weights)\n\nwmae_score = wmae(y_test, y_pred, class_weights)\nprint(\"WMAE:\", wmae_score)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:53.460012Z","iopub.execute_input":"2025-07-08T22:41:53.460537Z","iopub.status.idle":"2025-07-08T22:41:53.479641Z","shell.execute_reply.started":"2025-07-08T22:41:53.460502Z","shell.execute_reply":"2025-07-08T22:41:53.478325Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_pred","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:53.480671Z","iopub.execute_input":"2025-07-08T22:41:53.481020Z","iopub.status.idle":"2025-07-08T22:41:53.502912Z","shell.execute_reply.started":"2025-07-08T22:41:53.480993Z","shell.execute_reply":"2025-07-08T22:41:53.501730Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_test_2 = df_without_target.drop(columns=['client_num', 'target'])\ny_pred_2 = clf.predict(X_test_2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:53.504215Z","iopub.execute_input":"2025-07-08T22:41:53.504585Z","iopub.status.idle":"2025-07-08T22:41:54.297078Z","shell.execute_reply.started":"2025-07-08T22:41:53.504559Z","shell.execute_reply":"2025-07-08T22:41:54.295806Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"with open('/kaggle/working/pred.txt','w') as f:\n    f.write(f'{y_pred_2}')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:54.298029Z","iopub.execute_input":"2025-07-08T22:41:54.298395Z","iopub.status.idle":"2025-07-08T22:41:54.305281Z","shell.execute_reply.started":"2025-07-08T22:41:54.298366Z","shell.execute_reply":"2025-07-08T22:41:54.303695Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_pred_2","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:41:54.307993Z","iopub.execute_input":"2025-07-08T22:41:54.308270Z","iopub.status.idle":"2025-07-08T22:41:54.333431Z","shell.execute_reply.started":"2025-07-08T22:41:54.308250Z","shell.execute_reply":"2025-07-08T22:41:54.332000Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"forecast = df_without_target.reset_index()[['client_num']]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:51:50.872388Z","iopub.execute_input":"2025-07-08T22:51:50.872878Z","iopub.status.idle":"2025-07-08T22:51:51.057210Z","shell.execute_reply.started":"2025-07-08T22:51:50.872849Z","shell.execute_reply":"2025-07-08T22:51:51.053702Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"forecast['target'] = y_pred_2.astype(int).tolist()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T22:52:59.352315Z","iopub.execute_input":"2025-07-08T22:52:59.352706Z","iopub.status.idle":"2025-07-08T22:52:59.372016Z","shell.execute_reply.started":"2025-07-08T22:52:59.352682Z","shell.execute_reply":"2025-07-08T22:52:59.370654Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"forecast.to_csv('/kaggle/working/submission.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T23:09:46.521953Z","iopub.execute_input":"2025-07-08T23:09:46.522393Z","iopub.status.idle":"2025-07-08T23:09:46.562026Z","shell.execute_reply.started":"2025-07-08T23:09:46.522370Z","shell.execute_reply":"2025-07-08T23:09:46.560869Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"forecast","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T23:09:47.001898Z","iopub.execute_input":"2025-07-08T23:09:47.002230Z","iopub.status.idle":"2025-07-08T23:09:47.013913Z","shell.execute_reply.started":"2025-07-08T23:09:47.002209Z","shell.execute_reply":"2025-07-08T23:09:47.012554Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T23:02:41.036022Z","iopub.execute_input":"2025-07-08T23:02:41.036338Z","iopub.status.idle":"2025-07-08T23:02:41.048952Z","shell.execute_reply.started":"2025-07-08T23:02:41.036318Z","shell.execute_reply":"2025-07-08T23:02:41.047714Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_full = pd.concat([df_train, forecast], axis=0).reset_index(drop=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T23:15:29.608240Z","iopub.execute_input":"2025-07-08T23:15:29.608595Z","iopub.status.idle":"2025-07-08T23:15:29.617746Z","shell.execute_reply.started":"2025-07-08T23:15:29.608571Z","shell.execute_reply":"2025-07-08T23:15:29.616495Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_full.to_csv('/kaggle/working/submission_full.csv', index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T23:15:29.892221Z","iopub.execute_input":"2025-07-08T23:15:29.892565Z","iopub.status.idle":"2025-07-08T23:15:30.006295Z","shell.execute_reply.started":"2025-07-08T23:15:29.892542Z","shell.execute_reply":"2025-07-08T23:15:30.003785Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_full","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-08T23:14:01.246091Z","iopub.execute_input":"2025-07-08T23:14:01.246483Z","iopub.status.idle":"2025-07-08T23:14:01.258279Z","shell.execute_reply.started":"2025-07-08T23:14:01.246457Z","shell.execute_reply":"2025-07-08T23:14:01.256900Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}