{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":81933,"databundleVersionId":9643020,"sourceType":"competition"},{"sourceId":10244205,"sourceType":"datasetVersion","datasetId":6335434}],"dockerImageVersionId":30787,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import torch\ngpu_available = torch.cuda.is_available()\nif gpu_available:\n    print(\"GPU is available.\")\nelse:\n    print(\"GPU is not available.\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:29:42.613334Z","iopub.execute_input":"2024-12-19T09:29:42.613822Z","iopub.status.idle":"2024-12-19T09:29:42.619400Z","shell.execute_reply.started":"2024-12-19T09:29:42.613780Z","shell.execute_reply":"2024-12-19T09:29:42.618522Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import warnings\nfrom functools import partial\nfrom pathlib import Path\nimport os\nfrom concurrent.futures import ThreadPoolExecutor\nimport pickle\nfrom collections import Counter\n\n\n# プロgressバー\nfrom tqdm import tqdm\n\n# データ処理・分析\nimport numpy as np\nimport pandas as pd\nfrom scipy import stats\n\n# 可視化\nimport matplotlib.pyplot as plt\n\n# 機械学習\nfrom catboost import CatBoostRegressor, MultiTargetCustomMetric\nimport lightgbm as lgb\nfrom sklearn.base import BaseEstimator\nfrom sklearn.ensemble import VotingRegressor\nfrom sklearn.impute import SimpleImputer\nfrom sklearn.metrics import cohen_kappa_score\nfrom sklearn.model_selection import StratifiedKFold, KFold, train_test_split\nfrom sklearn.preprocessing import OrdinalEncoder, StandardScaler\n\n# 深層学習\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader, TensorDataset\n\n# ハイパーパラメータチューニング\nimport optuna\n\n# Warningsの抑制\nwarnings.filterwarnings(\"ignore\", message=\"Failed to optimize method\")\nwarnings.filterwarnings(\"ignore\", category=UserWarning)  # LightGBMのWarning","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:29:42.620808Z","iopub.execute_input":"2024-12-19T09:29:42.621052Z","iopub.status.idle":"2024-12-19T09:29:42.637272Z","shell.execute_reply.started":"2024-12-19T09:29:42.621028Z","shell.execute_reply":"2024-12-19T09:29:42.636379Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"DATA_DIR = Path(\"/kaggle/input/child-mind-institute-problematic-internet-use\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:29:42.638051Z","iopub.execute_input":"2024-12-19T09:29:42.638273Z","iopub.status.idle":"2024-12-19T09:29:42.648858Z","shell.execute_reply.started":"2024-12-19T09:29:42.638242Z","shell.execute_reply":"2024-12-19T09:29:42.647968Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"TARGET_COL = \"sii\"\n\nFEATURE_COLS = [\n    \"Basic_Demos-Enroll_Season\",\n    \"Basic_Demos-Age\",\n    \"Basic_Demos-Sex\",\n    \"CGAS-Season\",\n    \"CGAS-CGAS_Score\",\n    \"Physical-Season\",\n    \"Physical-BMI\",\n    \"Physical-Height\",\n    \"Physical-Weight\",\n    \"Physical-Waist_Circumference\",\n    \"Physical-Diastolic_BP\",\n    \"Physical-HeartRate\",\n    \"Physical-Systolic_BP\",\n    \"Fitness_Endurance-Season\",\n    \"Fitness_Endurance-Max_Stage\",\n    \"Fitness_Endurance-Time_Mins\",\n    \"Fitness_Endurance-Time_Sec\",\n    \"FGC-Season\",\n    \"FGC-FGC_CU\",\n    \"FGC-FGC_CU_Zone\",\n    \"FGC-FGC_GSND\",\n    \"FGC-FGC_GSND_Zone\",\n    \"FGC-FGC_GSD\",\n    \"FGC-FGC_GSD_Zone\",\n    \"FGC-FGC_PU\",\n    \"FGC-FGC_PU_Zone\",\n    \"FGC-FGC_SRL\",\n    \"FGC-FGC_SRL_Zone\",\n    \"FGC-FGC_SRR\",\n    \"FGC-FGC_SRR_Zone\",\n    \"FGC-FGC_TL\",\n    \"FGC-FGC_TL_Zone\",\n    \"BIA-Season\",\n    \"BIA-BIA_Activity_Level_num\",\n    \"BIA-BIA_BMC\",\n    \"BIA-BIA_BMI\",\n    \"BIA-BIA_BMR\",\n    \"BIA-BIA_DEE\",\n    \"BIA-BIA_ECW\",\n    \"BIA-BIA_FFM\",\n    \"BIA-BIA_FFMI\",\n    \"BIA-BIA_FMI\",\n    \"BIA-BIA_Fat\",\n    \"BIA-BIA_Frame_num\",\n    \"BIA-BIA_ICW\",\n    \"BIA-BIA_LDM\",\n    \"BIA-BIA_LST\",\n    \"BIA-BIA_SMM\",\n    \"BIA-BIA_TBW\",\n    \"PAQ_A-Season\",\n    \"PAQ_A-PAQ_A_Total\",\n    \"PAQ_C-Season\",\n    \"PAQ_C-PAQ_C_Total\",\n    \"SDS-Season\",\n    \"SDS-SDS_Total_Raw\",\n    \"SDS-SDS_Total_T\",\n    \"PreInt_EduHx-Season\",\n    \"PreInt_EduHx-computerinternet_hoursday\",\n]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:29:42.650507Z","iopub.execute_input":"2024-12-19T09:29:42.650740Z","iopub.status.idle":"2024-12-19T09:29:42.660336Z","shell.execute_reply.started":"2024-12-19T09:29:42.650717Z","shell.execute_reply":"2024-12-19T09:29:42.659502Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# def feature_engineering(df):\n#     added_columns = []\n\n#     # 新しい特徴量の作成\n#     # 年齢とBMIの積\n#     df['cal_BMI_Age'] = df['Physical-BMI'] * df['Basic_Demos-Age']\n#     added_columns.append('cal_BMI_Age')\n\n#     # インターネット使用時間と年齢の積\n#     df['cal_Internet_Hours_Age'] = df['PreInt_EduHx-computerinternet_hoursday'] * df['Basic_Demos-Age']\n#     added_columns.append('cal_Internet_Hours_Age')\n\n#     # BMIとインターネット使用時間の積\n#     df['cal_BMI_Internet_Hours'] = df['Physical-BMI'] * df['PreInt_EduHx-computerinternet_hoursday']\n#     added_columns.append('cal_BMI_Internet_Hours')\n\n#     # 体脂肪量とBMIの比率\n#     df['cal_BFP_BMI'] = df['BIA-BIA_Fat'] / df['BIA-BIA_BMI'].replace(0, np.nan)\n#     added_columns.append('cal_BFP_BMI')\n\n#     # 除脂肪体重指数と体脂肪の比率\n#     df['cal_FFMI_BFP'] = df['BIA-BIA_FFMI'] / df['BIA-BIA_Fat'].replace(0, np.nan)\n#     added_columns.append('cal_FFMI_BFP')\n\n#     # 体脂肪指数と体脂肪量の比率\n#     df['cal_FMI_BFP'] = df['BIA-BIA_FMI'] / df['BIA-BIA_Fat'].replace(0, np.nan)\n#     added_columns.append('cal_FMI_BFP')\n\n#     # 除脂肪体重と総水分量の比率\n#     df['cal_LST_TBW'] = df['BIA-BIA_LST'] / df['BIA-BIA_TBW'].replace(0, np.nan)\n#     added_columns.append('cal_LST_TBW')\n\n#     # 体脂肪量と基礎代謝率の積\n#     df['cal_BFP_BMR'] = df['BIA-BIA_Fat'] * df['BIA-BIA_BMR'].replace(0, np.nan)\n#     added_columns.append('cal_BFP_BMR')\n\n#     # 体脂肪量と日常活動に必要なエネルギー消費の積\n#     df['cal_BFP_DEE'] = df['BIA-BIA_Fat'] * df['BIA-BIA_DEE'].replace(0, np.nan)\n#     added_columns.append('cal_BFP_DEE')\n\n#     # 基礎代謝率と体重の比率\n#     df['cal_BMR_Weight'] = df['BIA-BIA_BMR'] / df['Physical-Weight'].replace(0, np.nan)\n#     added_columns.append('cal_BMR_Weight')\n\n#     # エネルギー消費量と体重の比率\n#     df['cal_DEE_Weight'] = df['BIA-BIA_DEE'] / df['Physical-Weight'].replace(0, np.nan)\n#     added_columns.append('cal_DEE_Weight')\n\n#     # 筋肉量と身長の比率\n#     df['cal_SMM_Height'] = df['BIA-BIA_SMM'] / df['Physical-Height'].replace(0, np.nan)\n#     added_columns.append('cal_SMM_Height')\n\n#     # 筋肉量と体脂肪量の比率\n#     df['cal_Muscle_to_Fat'] = df['BIA-BIA_SMM'] / df['BIA-BIA_FMI'].replace(0, np.nan)\n#     added_columns.append('cal_Muscle_to_Fat')\n\n#     # 体重に対する総水分量\n#     df['cal_Hydration_Status'] = df['BIA-BIA_TBW'] / df['Physical-Weight'].replace(0, np.nan)\n#     added_columns.append('cal_Hydration_Status')\n\n#     # 細胞内液量と総水分量の比率\n#     df['cal_ICW_TBW'] = df['BIA-BIA_ICW'] / df['BIA-BIA_TBW'].replace(0, np.nan)\n#     added_columns.append('cal_ICW_TBW')\n\n#     # 収縮期血圧と拡張期血圧の比率\n#     df['cal_BP_ratio'] = df['Physical-Systolic_BP'] / df['Physical-Diastolic_BP'].replace(0, np.nan)\n#     added_columns.append('cal_BP_ratio')\n\n#     # 体重と身長の比率\n#     df['cal_Weight_Height_ratio'] = df['Physical-Weight'] / df['Physical-Height'].replace(0, np.nan)\n#     added_columns.append('cal_Weight_Height_ratio')\n\n#     # 体力指標の比率\n#     endurance_time = df['Fitness_Endurance-Time_Mins'] * 60 + df['Fitness_Endurance-Time_Sec']\n#     df['cal_Endurance_ratio'] = df['Fitness_Endurance-Max_Stage'] / endurance_time.replace(0, np.nan)\n#     added_columns.append('cal_Endurance_ratio')\n\n#     # 水分と脂肪の比率\n#     df['cal_Water_Fat_ratio'] = df['BIA-BIA_TBW'] / (df['BIA-BIA_Fat'].replace(0, np.nan) + 1e-9)\n#     added_columns.append('cal_Water_Fat_ratio')\n\n#     # 筋肉量と体重の比率\n#     df['cal_Muscle_Weight_ratio'] = df['BIA-BIA_SMM'] / df['Physical-Weight'].replace(0, np.nan)\n#     added_columns.append('cal_Muscle_Weight_ratio')\n\n#     return df, added_columns","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:29:42.661417Z","iopub.execute_input":"2024-12-19T09:29:42.661695Z","iopub.status.idle":"2024-12-19T09:29:42.675213Z","shell.execute_reply.started":"2024-12-19T09:29:42.661671Z","shell.execute_reply":"2024-12-19T09:29:42.674512Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# def feature_engineering(df):\n#     added_columns = []\n\n#     # 特徴量生成\n#     if 'Physical-BMI' in df and 'Basic_Demos-Age' in df:\n#         df['cal_BMI_Age'] = df['Physical-BMI'] * df['Basic_Demos-Age']\n#         added_columns.append('cal_BMI_Age')\n\n#     if 'PreInt_EduHx-computerinternet_hoursday' in df and 'Basic_Demos-Age' in df:\n#         df['cal_Internet_Hours_Age'] = df['PreInt_EduHx-computerinternet_hoursday'] * df['Basic_Demos-Age']\n#         added_columns.append('cal_Internet_Hours_Age')\n\n#     if 'Physical-BMI' in df and 'PreInt_EduHx-computerinternet_hoursday' in df:\n#         df['cal_BMI_Internet_Hours'] = df['Physical-BMI'] * df['PreInt_EduHx-computerinternet_hoursday']\n#         added_columns.append('cal_BMI_Internet_Hours')\n\n#     if 'BIA-BIA_Fat' in df and 'BIA-BIA_BMI' in df:\n#         df['cal_BFP_BMI'] = df['BIA-BIA_Fat'] / df['BIA-BIA_BMI']\n#         added_columns.append('cal_BFP_BMI')\n\n#     if 'BIA-BIA_FFMI' in df and 'BIA-BIA_Fat' in df:\n#         df['cal_FFMI_BFP'] = df['BIA-BIA_FFMI'] / df['BIA-BIA_Fat']\n#         added_columns.append('cal_FFMI_BFP')\n\n#     if 'BIA-BIA_FMI' in df and 'BIA-BIA_Fat' in df:\n#         df['cal_FMI_BFP'] = df['BIA-BIA_FMI'] / df['BIA-BIA_Fat']\n#         added_columns.append('cal_FMI_BFP')\n\n#     if 'BIA-BIA_LST' in df and 'BIA-BIA_TBW' in df:\n#         df['cal_LST_TBW'] = df['BIA-BIA_LST'] / df['BIA-BIA_TBW']\n#         added_columns.append('cal_LST_TBW')\n\n#     if 'BIA-BIA_Fat' in df and 'BIA-BIA_BMR' in df:\n#         df['cal_BFP_BMR'] = df['BIA-BIA_Fat'] * df['BIA-BIA_BMR']\n#         added_columns.append('cal_BFP_BMR')\n\n#     if 'BIA-BIA_Fat' in df and 'BIA-BIA_DEE' in df:\n#         df['cal_BFP_DEE'] = df['BIA-BIA_Fat'] * df['BIA-BIA_DEE']\n#         added_columns.append('cal_BFP_DEE')\n\n#     if 'BIA-BIA_BMR' in df and 'Physical-Weight' in df:\n#         df['cal_BMR_Weight'] = df['BIA-BIA_BMR'] / df['Physical-Weight']\n#         added_columns.append('cal_BMR_Weight')\n\n#     if 'BIA-BIA_DEE' in df and 'Physical-Weight' in df:\n#         df['cal_DEE_Weight'] = df['BIA-BIA_DEE'] / df['Physical-Weight']\n#         added_columns.append('cal_DEE_Weight')\n\n#     if 'BIA-BIA_SMM' in df and 'Physical-Height' in df:\n#         df['cal_SMM_Height'] = df['BIA-BIA_SMM'] / df['Physical-Height']\n#         added_columns.append('cal_SMM_Height')\n\n#     if 'BIA-BIA_SMM' in df and 'BIA-BIA_FMI' in df:\n#         df['cal_Muscle_to_Fat'] = df['BIA-BIA_SMM'] / df['BIA-BIA_FMI']\n#         added_columns.append('cal_Muscle_to_Fat')\n\n#     if 'BIA-BIA_TBW' in df and 'Physical-Weight' in df:\n#         df['cal_Hydration_Status'] = df['BIA-BIA_TBW'] / df['Physical-Weight']\n#         added_columns.append('cal_Hydration_Status')\n\n#     if 'BIA-BIA_ICW' in df and 'BIA-BIA_TBW' in df:\n#         df['cal_ICW_TBW'] = df['BIA-BIA_ICW'] / df['BIA-BIA_TBW']\n#         added_columns.append('cal_ICW_TBW')\n\n#     if 'Physical-Systolic_BP' in df and 'Physical-Diastolic_BP' in df:\n#         df['cal_BP_ratio'] = df['Physical-Systolic_BP'] / df['Physical-Diastolic_BP']\n#         added_columns.append('cal_BP_ratio')\n\n#     if 'Physical-Weight' in df and 'Physical-Height' in df:\n#         df['cal_Weight_Height_ratio'] = df['Physical-Weight'] / df['Physical-Height']\n#         added_columns.append('cal_Weight_Height_ratio')\n\n#     if 'Fitness_Endurance-Time_Mins' in df and 'Fitness_Endurance-Time_Sec' in df and 'Fitness_Endurance-Max_Stage' in df:\n#         endurance_time = df['Fitness_Endurance-Time_Mins'] * 60 + df['Fitness_Endurance-Time_Sec']\n#         df['cal_Endurance_ratio'] = df['Fitness_Endurance-Max_Stage'] / endurance_time\n#         added_columns.append('cal_Endurance_ratio')\n\n#     if 'BIA-BIA_TBW' in df and 'BIA-BIA_Fat' in df:\n#         df['cal_Water_Fat_ratio'] = df['BIA-BIA_TBW'] / (df['BIA-BIA_Fat'] + 1e-9)  # 小さい値を足して0割防止\n#         added_columns.append('cal_Water_Fat_ratio')\n\n#     if 'BIA-BIA_SMM' in df and 'Physical-Weight' in df:\n#         df['cal_Muscle_Weight_ratio'] = df['BIA-BIA_SMM'] / df['Physical-Weight']\n#         added_columns.append('cal_Muscle_Weight_ratio')\n\n#     return df, added_columns\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:29:42.859877Z","iopub.execute_input":"2024-12-19T09:29:42.860133Z","iopub.status.idle":"2024-12-19T09:29:42.866748Z","shell.execute_reply.started":"2024-12-19T09:29:42.860109Z","shell.execute_reply":"2024-12-19T09:29:42.865681Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def feature_engineering(df):\n    added_columns = []\n\n    # 基準値の統合 (年齢と性別に基づく基準値を追加)\n    normal_values = pd.DataFrame({\n        'Basic_Demos-Age': list(range(5, 23)) * 2,  # 年齢: 5歳から22歳\n        'Basic_Demos-Sex': [0] * 18 + [1] * 18,  # 性別: 0=男性, 1=女性\n        'Normal_BMI': [15 + i * 0.5 for i in range(18)] * 2,  # BMIの基準値\n        'Normal_BMR': [1100 + i * 50 for i in range(18)] * 2,  # 基礎代謝率 (BMR) の基準値\n        'Normal_HeartRate': [80 for _ in range(36)],  # 心拍数の基準値\n        'Normal_Systolic_BP': [100 + i for i in range(18)] * 2,  # 収縮期血圧の基準値\n        'Normal_Diastolic_BP': [65 + i for i in range(18)] * 2,  # 拡張期血圧の基準値\n    })\n    df = df.merge(normal_values, on=['Basic_Demos-Age', 'Basic_Demos-Sex'], how='left')\n\n    # インフレーション係数の計算 (各値が基準値と比べてどれだけ高いか)\n    df['cal_BMI_Inflation'] = df['Physical-BMI'] / df['Normal_BMI']  # BMI の基準値に対する比率\n    added_columns.append('cal_BMI_Inflation')\n    df['cal_BMR_Inflation'] = df['BIA-BIA_BMR'] / df['Normal_BMR']  # 基礎代謝率の基準値に対する比率\n    added_columns.append('cal_BMR_Inflation')\n    df['cal_HeartRate_Inflation'] = df['Physical-HeartRate'] / df['Normal_HeartRate']  # 心拍数の基準値に対する比率\n    added_columns.append('cal_HeartRate_Inflation')\n    df['cal_Systolic_BP_Inflation'] = df['Physical-Systolic_BP'] / df['Normal_Systolic_BP']  # 収縮期血圧の基準値に対する比率\n    added_columns.append('cal_Systolic_BP_Inflation')\n    df['cal_Diastolic_BP_Inflation'] = df['Physical-Diastolic_BP'] / df['Normal_Diastolic_BP']  # 拡張期血圧の基準値に対する比率\n    added_columns.append('cal_Diastolic_BP_Inflation')\n\n    # 季節関連特徴量のエンコード (PCIAT-Season 関連を除外)\n    season_start_month = {'Spring': 3, 'Summer': 6, 'Fall': 9, 'Winter': 12}\n    season_cols = [col for col in df.columns if 'Season' in col and 'PCIAT' not in col]  # 'PCIAT-Season' を除外\n    for col in season_cols:\n        df[col + '_StartMonth'] = df[col].map(season_start_month)  # 季節の開始月をマッピング\n        added_columns.append(col + '_StartMonth')\n        for season, start_month in season_start_month.items():\n            df[f'{col}_{season}'] = (df[col] == season).astype(float)  # 季節ごとのダミー変数\n            added_columns.append(f'{col}_{season}')\n\n    # 季節間の月差 (PCIAT-Season 関連を除外)\n    if 'Basic_Demos-Enroll_Season' in season_cols:\n        for col in season_cols:\n            if col != 'Basic_Demos-Enroll_Season':\n                df[f'{col}_MonthDifference'] = df.apply(\n                    lambda row: (\n                        12 - abs(row['Basic_Demos-Enroll_Season_StartMonth'] - row[col + '_StartMonth'])\n                        if row['Basic_Demos-Enroll_Season_StartMonth'] > row[col + '_StartMonth'] else\n                        abs(row['Basic_Demos-Enroll_Season_StartMonth'] - row[col + '_StartMonth'])\n                    ) if pd.notna(row['Basic_Demos-Enroll_Season_StartMonth']) and pd.notna(row[col + '_StartMonth'])\n                    else np.nan, axis=1\n                )\n                added_columns.append(f'{col}_MonthDifference')\n\n    # 相互作用変数の作成\n    df['cal_BMI_Age'] = df['Physical-BMI'] * df['Basic_Demos-Age']  # BMI と年齢の積\n    added_columns.append('cal_BMI_Age')\n    df['cal_Internet_Hours_Age'] = df['PreInt_EduHx-computerinternet_hoursday'] * df['Basic_Demos-Age']  # インターネット使用時間と年齢の積\n    added_columns.append('cal_Internet_Hours_Age')\n    df['cal_BMI_Internet_Hours'] = df['Physical-BMI'] * df['PreInt_EduHx-computerinternet_hoursday']  # BMI とインターネット使用時間の積\n    added_columns.append('cal_BMI_Internet_Hours')\n    df['cal_BFP_BMI'] = df['BIA-BIA_Fat'] / df['BIA-BIA_BMI'].replace(0, np.nan)  # 体脂肪量と BMI の比率\n    added_columns.append('cal_BFP_BMI')\n    df['cal_FFMI_BFP'] = df['BIA-BIA_FFMI'] / df['BIA-BIA_Fat'].replace(0, np.nan)  # 除脂肪体重指数と体脂肪量の比率\n    added_columns.append('cal_FFMI_BFP')\n    df['cal_FMI_BFP'] = df['BIA-BIA_FMI'] / df['BIA-BIA_Fat'].replace(0, np.nan)  # 体脂肪指数と体脂肪量の比率\n    added_columns.append('cal_FMI_BFP')\n    df['cal_LST_TBW'] = df['BIA-BIA_LST'] / df['BIA-BIA_TBW'].replace(0, np.nan)  # 除脂肪体重と総水分量の比率\n    added_columns.append('cal_LST_TBW')\n    df['cal_BFP_BMR'] = df['BIA-BIA_Fat'] * df['BIA-BIA_BMR']  # 体脂肪量と基礎代謝率の積\n    added_columns.append('cal_BFP_BMR')\n    df['cal_BFP_DEE'] = df['BIA-BIA_Fat'] * df['BIA-BIA_DEE']  # 体脂肪量とエネルギー消費量の積\n    added_columns.append('cal_BFP_DEE')\n    df['cal_BMR_Weight'] = df['BIA-BIA_BMR'] / df['Physical-Weight'].replace(0, np.nan)  # 基礎代謝率と体重の比率\n    added_columns.append('cal_BMR_Weight')\n    df['cal_DEE_Weight'] = df['BIA-BIA_DEE'] / df['Physical-Weight'].replace(0, np.nan)  # エネルギー消費量と体重の比率\n    added_columns.append('cal_DEE_Weight')\n    df['cal_SMM_Height'] = df['BIA-BIA_SMM'] / df['Physical-Height'].replace(0, np.nan)  # 筋肉量と身長の比率\n    added_columns.append('cal_SMM_Height')\n    df['cal_Muscle_to_Fat'] = df['BIA-BIA_SMM'] / df['BIA-BIA_FMI'].replace(0, np.nan)  # 筋肉量と体脂肪指数の比率\n    added_columns.append('cal_Muscle_to_Fat')\n    df['cal_Hydration_Status'] = df['BIA-BIA_TBW'] / df['Physical-Weight'].replace(0, np.nan)  # 体重に対する総水分量\n    added_columns.append('cal_Hydration_Status')\n    df['cal_ICW_TBW'] = df['BIA-BIA_ICW'] / df['BIA-BIA_TBW'].replace(0, np.nan)  # 細胞内液量と総水分量の比率\n    added_columns.append('cal_ICW_TBW')\n\n    # 新しい KPI 指標\n    df['cal_Sleep_Disturbance_Index'] = (df['SDS-SDS_Total_Raw'] * df['SDS-SDS_Total_T']) / 100  # 睡眠障害指数\n    added_columns.append('cal_Sleep_Disturbance_Index')\n    df['cal_Strength_Flexibility_Score'] = (\n        df['FGC-FGC_GSD'] + df['FGC-FGC_GSND'] + df['FGC-FGC_SRL'] + df['FGC-FGC_SRR']\n    ) / 4  # 筋力・柔軟性スコア\n    added_columns.append('cal_Strength_Flexibility_Score')\n    df['cal_Hydration_BMI'] = df['BIA-BIA_TBW'] / df['Physical-BMI']  # 総水分量と BMI の比率\n    added_columns.append('cal_Hydration_BMI')\n    df['cal_Metabolic_Risk'] = (\n        df['BIA-BIA_Fat'] + df['Physical-BMI'] + df['Physical-Systolic_BP'] + df['Physical-Diastolic_BP']\n    ) / 4  # 代謝リスクスコア\n    added_columns.append('cal_Metabolic_Risk')\n\n    return df, added_columns\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:29:42.868316Z","iopub.execute_input":"2024-12-19T09:29:42.869102Z","iopub.status.idle":"2024-12-19T09:29:42.894630Z","shell.execute_reply.started":"2024-12-19T09:29:42.869063Z","shell.execute_reply":"2024-12-19T09:29:42.893715Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def quadratic_weighted_kappa(preds, data):\n    y_true = data.get_label()\n    y_pred = preds.clip(y_min, y_max).round()\n    qwk = cohen_kappa_score(y_true, y_pred, weights=\"quadratic\")\n    return 'QWK', qwk, True","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:29:42.895935Z","iopub.execute_input":"2024-12-19T09:29:42.896239Z","iopub.status.idle":"2024-12-19T09:29:42.909267Z","shell.execute_reply.started":"2024-12-19T09:29:42.896215Z","shell.execute_reply":"2024-12-19T09:29:42.908433Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# GLOBAL_TS_LENGTH=[]\n\ndef extract_advanced_features(data):\n    # Initial data preprocessing\n    data = data.copy()\n    data['timestamp'] = pd.to_datetime(data['relative_date_PCIAT'], unit='D') + pd.to_timedelta(data['time_of_day'])\n    data = data[data['non-wear_flag'] == 0]\n\n    # Calculate basic metrics\n    data['magnitude'] = np.sqrt(data['X']**2 + data['Y']**2 + data['Z']**2)\n    data['velocity'] = data['magnitude']\n    data['distance'] = data['velocity'] * 5  # 5 seconds per observation\n    data['date'] = data['timestamp'].dt.date\n    hour = pd.to_datetime(data['time_of_day']).dt.hour\n\n    # Calculate aggregated distances\n    distances = {\n        'daily': data.groupby('date')['distance'].sum(),\n        'monthly': data.groupby(data['timestamp'].dt.to_period('M'))['distance'].sum(),\n        'quarterly': data.groupby('quarter')['distance'].sum()\n    }\n\n    # Initialize features dictionary\n    features = {}\n\n    # Time masks for different periods\n    time_masks = {\n        'morning': (hour >= 6) & (hour < 12),\n        'afternoon': (hour >= 12) & (hour < 18),\n        'evening': (hour >= 18) & (hour < 22),\n        'night': (hour >= 22) | (hour < 6)\n    }\n\n    # 1. Activity Pattern Features\n    for period, mask in time_masks.items():\n        features.update({\n            f'{period}_activity_mean': data.loc[mask, 'magnitude'].mean(),\n            f'{period}_activity_std': data.loc[mask, 'magnitude'].std(),\n            f'{period}_enmo_mean': data.loc[mask, 'enmo'].mean()\n        })\n\n    # 2. Sleep Quality Features\n    sleep_hours = time_masks['night']\n    magnitude_threshold = data['magnitude'].mean() + data['magnitude'].std()\n\n    features.update({\n        'sleep_movement_mean': data.loc[sleep_hours, 'magnitude'].mean(),\n        'sleep_movement_std': data.loc[sleep_hours, 'magnitude'].std(),\n        'sleep_disruption_count': len(data.loc[sleep_hours & (data['magnitude'] >\n            data['magnitude'].mean() + 2 * data['magnitude'].std())]),\n        'light_exposure_during_sleep': data.loc[sleep_hours, 'light'].mean(),\n        'sleep_position_changes': len(data.loc[sleep_hours &\n            (abs(data['anglez'].diff()) > 45)]),\n        'good_sleep_cycle': int(data.loc[sleep_hours, 'light'].mean() < 50)\n    })\n\n    # 3. Activity Intensity Features\n    features.update({\n        'sedentary_time_ratio': (data['magnitude'] < magnitude_threshold * 0.5).mean(),\n        'moderate_activity_ratio': ((data['magnitude'] >= magnitude_threshold * 0.5) &\n            (data['magnitude'] < magnitude_threshold * 1.5)).mean(),\n        'vigorous_activity_ratio': (data['magnitude'] >= magnitude_threshold * 1.5).mean(),\n        'activity_peaks_per_day': len(data[data['magnitude'] >\n            data['magnitude'].quantile(0.95)]) / len(data.groupby('relative_date_PCIAT'))\n    })\n\n    # 4. Circadian Rhythm Features\n    hourly_activity = data.groupby(hour)['magnitude'].mean()\n    features.update({\n        'circadian_regularity': hourly_activity.std() / hourly_activity.mean(),\n        'peak_activity_hour': hourly_activity.idxmax(),\n        'trough_activity_hour': hourly_activity.idxmin(),\n        'activity_range': hourly_activity.max() - hourly_activity.min()\n    })\n\n    # 5-11. Additional Feature Groups\n    weekend_mask = data['weekday'].isin([6, 7])\n\n    features.update({\n        # Movement Patterns\n        'movement_entropy': stats.entropy(pd.qcut(data['magnitude'], q=10, duplicates='drop').value_counts()),\n        'direction_changes': len(data[abs(data['anglez'].diff()) > 30]) / len(data),\n        'sustained_activity_periods': len(data[data['magnitude'].rolling(12).mean() >\n            magnitude_threshold]) / len(data),\n\n        # Weekend vs Weekday\n        'weekend_activity_ratio': data.loc[weekend_mask, 'magnitude'].mean() /\n            data.loc[~weekend_mask, 'magnitude'].mean(),\n        'weekend_sleep_difference': data.loc[weekend_mask & sleep_hours, 'magnitude'].mean() -\n            data.loc[~weekend_mask & sleep_hours, 'magnitude'].mean(),\n\n        # Non-wear Time\n        'wear_time_ratio': (data['non-wear_flag'] == 0).mean(),\n        'wear_consistency': len(data['non-wear_flag'].value_counts()),\n        'longest_wear_streak': data['non-wear_flag'].eq(0).astype(int).groupby(\n            data['non-wear_flag'].ne(0).cumsum()).sum().max(),\n\n        # Device Usage\n        'screen_time_proxy': (data['light'] > data['light'].quantile(0.75)).mean(),\n        'dark_environment_ratio': (data['light'] < data['light'].quantile(0.25)).mean(),\n        'light_variation': data['light'].std() / data['light'].mean() if data['light'].mean() != 0 else 0,\n\n        # Battery Usage\n        'battery_drain_rate': -np.polyfit(range(len(data)), data['battery_voltage'], 1)[0],\n        'battery_variability': data['battery_voltage'].std(),\n        'low_battery_time': (data['battery_voltage'] < data['battery_voltage'].quantile(0.1)).mean(),\n\n        # Time-based\n        'days_monitored': data['relative_date_PCIAT'].nunique(),\n        'total_active_hours': len(data[data['magnitude'] > magnitude_threshold * 0.5]) * 5 / 3600,\n        'activity_regularity': data.groupby('weekday')['magnitude'].mean().std()\n    })\n\n    # Variability Features for multiple columns\n    for col in ['X', 'Y', 'Z', 'enmo', 'anglez']:\n        features.update({\n            f'{col}_skewness': data[col].skew(),\n            f'{col}_kurtosis': data[col].kurtosis(),\n            f'{col}_trend': np.polyfit(range(len(data)), data[col], 1)[0]\n        })\n\n    return pd.DataFrame([features])\n\ndef process_file(filename, dirname):\n    df= pd.read_parquet(os.path.join(dirname, filename, 'part-0.parquet'))\n    data=extract_advanced_features(df)\n    array_1=data.values[0]\n    array_2=df.describe().values.reshape(-1), filename.split('=')[1]\n    # Combine the two arrays\n    combined_array = np.concatenate((array_1, array_2[0]))\n    combined_tuple=(array_1,array_2[1])\n    return combined_tuple\n\ndef load_time_series(dirname) -> pd.DataFrame:\n    ids = os.listdir(dirname)\n\n    with ThreadPoolExecutor() as executor:\n        results = list(tqdm(executor.map(lambda fname: process_file(fname, dirname), ids), total=len(ids)))\n\n    stats, indexes = zip(*results)\n\n    df = pd.DataFrame(stats, columns=[f\"stat_{i}\" for i in range(len(stats[0]))])\n    df['id'] = indexes\n    return df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:29:42.911392Z","iopub.execute_input":"2024-12-19T09:29:42.911711Z","iopub.status.idle":"2024-12-19T09:29:42.935318Z","shell.execute_reply.started":"2024-12-19T09:29:42.911688Z","shell.execute_reply":"2024-12-19T09:29:42.934449Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom sklearn.preprocessing import StandardScaler\nfrom torch.utils.data import DataLoader, TensorDataset\nfrom tqdm import tqdm\n\n# PyTorchでオートエンコーダーモデルを構築\nclass Autoencoder(nn.Module):\n    def __init__(self, input_dim, encoding_dim):\n        super(Autoencoder, self).__init__()\n        self.encoder = nn.Sequential(\n            nn.Linear(input_dim, encoding_dim),\n            nn.ReLU()\n        )\n        self.decoder = nn.Sequential(\n            nn.Linear(encoding_dim, input_dim),\n            nn.Sigmoid()\n        )\n\n    def forward(self, x):\n        encoded = self.encoder(x)\n        decoded = self.decoder(encoded)\n        return encoded, decoded\n\n\n# 改良点1: バッチ正規化とドロップアウトを追加した深層オートエンコーダーモデル\nclass DeepAutoencoder(nn.Module):\n    def __init__(self, input_dim, encoding_dim):\n        super(DeepAutoencoder, self).__init__()\n        # エンコーダー\n        self.encoder = nn.Sequential(\n            nn.Linear(input_dim, encoding_dim * 3),\n            nn.BatchNorm1d(encoding_dim * 3),  # バッチ正規化追加\n            nn.ReLU(),\n            nn.Dropout(0.2),  # ドロップアウト追加\n            nn.Linear(encoding_dim * 3, encoding_dim * 2),\n            nn.BatchNorm1d(encoding_dim * 2),\n            nn.ReLU(),\n            nn.Dropout(0.2),\n            nn.Linear(encoding_dim * 2, encoding_dim),\n            nn.BatchNorm1d(encoding_dim),\n            nn.ReLU()\n        )\n        # デコーダー\n        self.decoder = nn.Sequential(\n            nn.Linear(encoding_dim, encoding_dim * 2),\n            nn.BatchNorm1d(encoding_dim * 2),\n            nn.ReLU(),\n            nn.Dropout(0.2),\n            nn.Linear(encoding_dim * 2, encoding_dim * 3),\n            nn.BatchNorm1d(encoding_dim * 3),\n            nn.ReLU(),\n            nn.Dropout(0.2),\n            nn.Linear(encoding_dim * 3, input_dim),\n            nn.Sigmoid()\n        )\n\n    def forward(self, x):\n        encoded = self.encoder(x)\n        decoded = self.decoder(encoded)\n        return encoded, decoded\n\n# 改良点2: メイン関数内で改善ポイントを反映\ndef perform_autoencoder(df, encoding_dim=50, epochs=50, batch_size=32, learning_rate=0.001,\n                        use_deep=True, save_model_path=None, seed=42):\n    # 再現性のための乱数シード\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    np.random.seed(seed)\n    torch.backends.cudnn.deterministic = True  # 再現性確保\n    torch.backends.cudnn.benchmark = False\n\n    # データの欠損値補完と定数列の削除\n    df.fillna(df.mean(), inplace=True)\n    df = df.loc[:, df.std() > 0]\n\n    # データの標準化\n    scaler = StandardScaler()\n    df_scaled = scaler.fit_transform(df)\n\n    # データをテンソルに変換し、デバイスに送る\n    device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n    data_tensor = torch.tensor(df_scaled, dtype=torch.float32).to(device)\n\n    # DataLoaderの作成\n    dataset = TensorDataset(data_tensor, data_tensor)\n    dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True)\n\n    # モデルのインスタンス化\n    input_dim = df_scaled.shape[1]\n    if use_deep:\n        model = DeepAutoencoder(input_dim=input_dim, encoding_dim=encoding_dim).to(device)\n    else:\n        model = Autoencoder(input_dim=input_dim, encoding_dim=encoding_dim).to(device)\n\n    # 損失関数と最適化手法\n    criterion = nn.MSELoss()\n    optimizer = optim.Adam(model.parameters(), lr=learning_rate)\n    scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', factor=0.5, patience=5)  # 動的学習率調整\n\n    # 訓練ループ\n    best_loss = float('inf')  # ベストモデル保存の基準\n    losses = []  # 損失を記録するリスト\n    for epoch in range(epochs):\n        model.train()\n        epoch_loss = 0.0\n        progress_bar = tqdm(dataloader, desc=f\"Epoch {epoch + 1}/{epochs}\", leave=False)\n\n        for batch_features, _ in progress_bar:\n            batch_features = batch_features.to(device)\n\n            # 順伝播と損失計算\n            _, decoded = model(batch_features)\n            loss = criterion(decoded, batch_features)\n\n            # 逆伝播と最適化\n            optimizer.zero_grad()\n            loss.backward()\n            optimizer.step()\n\n            epoch_loss += loss.item()\n            progress_bar.set_postfix(loss=loss.item())\n\n        # エポック平均損失を記録\n        epoch_loss /= len(dataloader)\n        losses.append(epoch_loss)\n\n        # ベストモデルの保存\n        if epoch_loss < best_loss:\n            best_loss = epoch_loss\n            if save_model_path:\n                torch.save(model.state_dict(), save_model_path)\n                print(f\"Best model saved at Epoch {epoch + 1} with Loss: {best_loss:.4f}\")\n\n        # 学習率の更新\n        scheduler.step(epoch_loss)\n        print(f\"Epoch {epoch + 1}/{epochs}, Avg Loss: {epoch_loss:.4f}\")\n\n    # 損失の可視化\n    plt.plot(range(1, epochs + 1), losses)\n    plt.xlabel('Epoch')\n    plt.ylabel('Loss')\n    plt.title('Training Loss')\n    plt.show()\n\n    # エンコードされたデータの抽出\n    model.eval()\n    with torch.no_grad():\n        encoded_data = model.encoder(data_tensor).cpu().numpy()\n\n    # エンコードデータをDataFrameに変換\n    df_encoded = pd.DataFrame(encoded_data, columns=[f'Enc_{i + 1}' for i in range(encoded_data.shape[1])])\n\n    return df_encoded","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:29:42.937048Z","iopub.execute_input":"2024-12-19T09:29:42.937323Z","iopub.status.idle":"2024-12-19T09:29:42.958478Z","shell.execute_reply.started":"2024-12-19T09:29:42.937298Z","shell.execute_reply":"2024-12-19T09:29:42.957663Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def convert_object_to_category(df):\n    return df.astype({col: \"category\" for col in df.select_dtypes(include=[\"object\"]).columns})","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:29:42.959578Z","iopub.execute_input":"2024-12-19T09:29:42.959921Z","iopub.status.idle":"2024-12-19T09:29:42.972376Z","shell.execute_reply.started":"2024-12-19T09:29:42.959881Z","shell.execute_reply":"2024-12-19T09:29:42.971601Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# # しきい値を設定\n# thresholds = [0.5, 1.5, 2.5]\n\n# # threshold_rounder 関数の定義\n# def threshold_rounder(y_pred, thresholds):\n#     return np.where(y_pred < thresholds[0], 0,\n#                     np.where(y_pred < thresholds[1], 1,\n#                              np.where(y_pred < thresholds[2], 2, 3)))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:29:42.973535Z","iopub.execute_input":"2024-12-19T09:29:42.973878Z","iopub.status.idle":"2024-12-19T09:29:42.983127Z","shell.execute_reply.started":"2024-12-19T09:29:42.973823Z","shell.execute_reply":"2024-12-19T09:29:42.982248Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_test = pd.read_csv(f\"{DATA_DIR}/test.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:29:43.104327Z","iopub.execute_input":"2024-12-19T09:29:43.104783Z","iopub.status.idle":"2024-12-19T09:29:43.115034Z","shell.execute_reply.started":"2024-12-19T09:29:43.104737Z","shell.execute_reply":"2024-12-19T09:29:43.114021Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_test, added_cols = feature_engineering(df_test)\nFEATURE_COLS = FEATURE_COLS + added_cols","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:29:43.116857Z","iopub.execute_input":"2024-12-19T09:29:43.117199Z","iopub.status.idle":"2024-12-19T09:29:43.179601Z","shell.execute_reply.started":"2024-12-19T09:29:43.117158Z","shell.execute_reply":"2024-12-19T09:29:43.178670Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_test","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:29:43.180591Z","iopub.execute_input":"2024-12-19T09:29:43.181499Z","iopub.status.idle":"2024-12-19T09:29:43.207506Z","shell.execute_reply.started":"2024-12-19T09:29:43.181444Z","shell.execute_reply":"2024-12-19T09:29:43.206432Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_submission = pd.read_csv(f\"{DATA_DIR}/sample_submission.csv\", index_col='id')\nMODEL_DIR = Path(\"/kaggle/input/cmi-submission-lgbmdeepautoencoder\")\n\nSEEDS = [42, 777, 7, 8, 108, 888, 123, 369, 999, 1089]\n\n\n# 各ファイルごとの予測結果を格納\nresults_by_seed = {}\nfor SEED in SEEDS:\n    ts_test = load_time_series(f\"{DATA_DIR}/series_test.parquet\")\n    # DeepAutoencoderを使用\n    test_ts_encoded = perform_autoencoder(\n        df=ts_test.set_index(\"id\"),\n        encoding_dim=60,\n        epochs=100,\n        batch_size=32,\n        use_deep=True,              # DeepAutoencoderを使用\n        seed=SEED\n        # save_model_path=\"deep_autoencoder_model.pth\"  # モデル保存パス\n    )\n\n    test_ts_encoded[\"id\"] = ts_test[\"id\"]\n    test_ts_encoded.set_index(\"id\", inplace=True)\n    \n    df_test_sub = df_test.copy()\n    display(df_test_sub)\n    display(test_ts_encoded)\n    df_test_sub = pd.merge(df_test_sub, test_ts_encoded, how=\"left\", on='id')\n    df_test_sub = pd.merge(df_test_sub, ts_test, how=\"left\", on='id')\n    df_test_sub = df_test_sub.set_index('id')\n    \n    df_test_sub = convert_object_to_category(df_test_sub)\n\n\n    test_ts_encoded[\"id\"] = ts_test[\"id\"]\n    test_ts_encoded.set_index(\"id\", inplace=True)\n\n    time_series_cols = ts_test.columns.tolist()\n    ts_encoded_cols = test_ts_encoded.columns.tolist()\n    time_series_cols.remove('id')\n    FEATURE_COLS_TEST = FEATURE_COLS + ts_encoded_cols + time_series_cols\n\n    model_file = f\"models_{SEED}.pkl\"\n    threshold_file = f\"fold_thresholds_{SEED}.pkl\"\n\n    print(f\"Processing {model_file} with thresholds from {threshold_file}...\")\n    \n    # モデルを読み込む\n    with open(MODEL_DIR / model_file, \"rb\") as f:\n        models = pickle.load(f)  # 各.pkl内に複数モデルが含まれる（10個のFoldに対応）\n    \n    # しきい値を読み込む\n    with open(MODEL_DIR / threshold_file, \"rb\") as f:\n        thresholds = pickle.load(f)  # 各.pkl内に対応する10個のしきい値リストが含まれる\n    \n    # モデルとしきい値の数が一致しているか確認\n    if len(models) != len(thresholds):\n        raise ValueError(f\"Mismatch between models ({len(models)}) and thresholds ({len(thresholds)})\")\n\n    # このモデルファイルの予測結果を計算\n    predictions = []\n\n    def threshold_rounder(y_pred, thresholds):\n        return np.digitize(y_pred, [-np.inf] + thresholds + [np.inf]) - 1\n\n\n    trained_features = set(models[0].feature_name())\n    test_features = set(df_test_sub.columns)\n    missing_features = trained_features - test_features\n    if missing_features:\n        print(f\"Missing features in test data: {missing_features}\")\n\n\n    \n    for model, fold_threshold in zip(models, thresholds):\n        # 各モデルで予測値を計算\n        y_pred = model.predict(df_test_sub[FEATURE_COLS_TEST])\n        \n        # 対応するFoldのしきい値で調整\n        y_pred_adjusted = threshold_rounder(y_pred, fold_threshold)\n        predictions.append(y_pred_adjusted)\n    \n    # 複数モデルの予測値を統合\n    # 平均予測を使用\n    # seed_average = np.mean(predictions, axis=0)\n\n\n\n    # 多数決を使用する場合（コメントアウト部分を有効化すると切り替え可能）\n    seed_majority = []\n    for i in range(len(df_test_sub)):\n        votes = [pred[i] for pred in predictions]\n        seed_majority.append(Counter(votes).most_common(1)[0][0])\n    seed_average = np.array(seed_majority)\n\n    # 結果を保存\n    results_by_seed[SEED] = seed_average\n    print(f\"Adjusted predictions for SEED {SEED} calculated.\")\n\n# 多数決の集計\nfinal_predictions = []\nfor i in range(len(df_test_sub)):\n    votes = [results_by_seed[SEED][i] for SEED in SEEDS]\n    final_predictions.append(Counter(votes).most_common(1)[0][0])\n\n# 提出データフレーム作成\ndf_submission[TARGET_COL] = final_predictions  # 最終多数決結果をセット\n\n# 提出ファイルの保存\nsubmission_path = \"submission.csv\"\ndf_submission.to_csv(submission_path)\nprint(f\"Submission file saved at: {submission_path}\")\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:29:43.209234Z","iopub.execute_input":"2024-12-19T09:29:43.209598Z","iopub.status.idle":"2024-12-19T09:30:02.644289Z","shell.execute_reply.started":"2024-12-19T09:29:43.209563Z","shell.execute_reply":"2024-12-19T09:30:02.643423Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_submission","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:30:02.646118Z","iopub.execute_input":"2024-12-19T09:30:02.646410Z","iopub.status.idle":"2024-12-19T09:30:02.653857Z","shell.execute_reply.started":"2024-12-19T09:30:02.646383Z","shell.execute_reply":"2024-12-19T09:30:02.652975Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_submission","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-19T09:30:02.655125Z","iopub.execute_input":"2024-12-19T09:30:02.655510Z","iopub.status.idle":"2024-12-19T09:30:02.671102Z","shell.execute_reply.started":"2024-12-19T09:30:02.655450Z","shell.execute_reply":"2024-12-19T09:30:02.670232Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}