{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":96164,"databundleVersionId":12993472,"isSourceIdPinned":false,"sourceType":"competition"}],"dockerImageVersionId":31090,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"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-18T18:33:20.101860Z","iopub.execute_input":"2025-07-18T18:33:20.102445Z","iopub.status.idle":"2025-07-18T18:33:20.431170Z","shell.execute_reply.started":"2025-07-18T18:33:20.102422Z","shell.execute_reply":"2025-07-18T18:33:20.430412Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_path = '/kaggle/input/drw-crypto-market-prediction/train.parquet'\ntest_path = '/kaggle/input/drw-crypto-market-prediction/test.parquet'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T18:33:23.918563Z","iopub.execute_input":"2025-07-18T18:33:23.918953Z","iopub.status.idle":"2025-07-18T18:33:23.922880Z","shell.execute_reply.started":"2025-07-18T18:33:23.918931Z","shell.execute_reply":"2025-07-18T18:33:23.921932Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import gc\n\ndf_train = pd.read_parquet(train_path)\ndf_test = pd.read_parquet(test_path)\n\n# Convert all numeric columns to float32\ndf_train = df_train.apply(lambda col: col.astype(np.float32) if np.issubdtype(col.dtype, np.number) else col)\ndf_test = df_test.apply(lambda col: col.astype(np.float32) if np.issubdtype(col.dtype, np.number) else col)\n\n# ✅ Confirm the conversion\nprint(df_train.dtypes)\nprint(df_test.dtypes)\ngc.collect()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T18:33:55.508301Z","iopub.execute_input":"2025-07-18T18:33:55.509059Z","iopub.status.idle":"2025-07-18T18:34:13.390624Z","shell.execute_reply.started":"2025-07-18T18:33:55.509031Z","shell.execute_reply":"2025-07-18T18:34:13.389954Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Show the first 5 rows of df_train\nprint(\"\\n====== df_train.shape ======\")\nprint(df_train.shape)\n\n# Show the first 5 rows of df_test\nprint(\"\\n====== df_test.shape ======\")\nprint(df_test.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T18:34:23.338192Z","iopub.execute_input":"2025-07-18T18:34:23.338787Z","iopub.status.idle":"2025-07-18T18:34:23.343070Z","shell.execute_reply.started":"2025-07-18T18:34:23.338761Z","shell.execute_reply":"2025-07-18T18:34:23.342165Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import psutil\nram = psutil.virtual_memory()\nprint(f'Total RAM: {ram.total / (1024 ** 3):.2f} GB')\nprint(f'Available RAM: {ram.available / (1024 ** 3):.2f} GB')\nprint(f'Used RAM: {ram.used / (1024 ** 3):.2f} GB')\nprint(f'RAM Usage %: {ram.percent}%')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T18:34:27.418215Z","iopub.execute_input":"2025-07-18T18:34:27.418756Z","iopub.status.idle":"2025-07-18T18:34:27.423881Z","shell.execute_reply.started":"2025-07-18T18:34:27.418731Z","shell.execute_reply":"2025-07-18T18:34:27.423083Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 1. Cleaned Data by Dropping NA & Duplicates","metadata":{}},{"cell_type":"code","source":"# import gc\n# import numpy as np\n# import pandas as pd\n# from pandas.util import hash_pandas_object as hash_object\n\n# def clean_dataset(df: pd.DataFrame, file_name: str = None) -> pd.DataFrame:\n#     import time\n\n#     print(\"\\n==========================\")\n#     print(f\"🧹 Cleaning Data: {file_name if file_name else 'Unnamed'}\")\n#     print(\"==========================\")\n\n#     # 1️⃣ Null Columns Check\n#     start_null = time.time()\n#     null_counts = df.isnull().sum()\n#     null_columns = null_counts[null_counts > 0]\n#     if not null_columns.empty:\n#         print(f\"Columns with Null Values:\\n{null_columns}\")\n#     else:\n#         print(\"No columns contain null values.\")\n#     print(f\"Null Check Time: {round(time.time() - start_null, 2)} seconds\")\n\n#     # 2️⃣ Drop Duplicate Columns (Hashing)\n#     start_dup_cols = time.time()\n#     hashes = df.apply(lambda col: hash_object(col).sum())\n#     duplicates_mask = hashes.duplicated()\n#     duplicate_columns = df.columns[duplicates_mask]\n#     if len(duplicate_columns) > 0:\n#         print(f\"Dropping duplicate columns: {duplicate_columns.tolist()}\")\n#         df = df.drop(columns=duplicate_columns)\n#     else:\n#         print(\"No duplicate columns found.\")\n#     print(f\"Duplicate Columns Check Time: {round(time.time() - start_dup_cols, 2)} seconds\")\n\n#     # 2️⃣.b Drop Duplicate Rows\n#     start_row_dup = time.time()\n#     initial_shape = df.shape\n#     df.drop_duplicates(inplace=True)\n#     final_shape = df.shape\n#     rows_dropped = initial_shape[0] - final_shape[0]\n#     if rows_dropped > 0:\n#         print(f\"Dropped {rows_dropped} duplicate rows.\")\n#     else:\n#         print(\"No duplicate rows found.\")\n#     print(f\"Duplicate Rows Check Time: {round(time.time() - start_row_dup, 2)} seconds\")\n\n#     # 3️⃣ Drop inf / -inf and Rows with NaNs\n#     start_inf = time.time()\n#     df.replace([np.inf, -np.inf], np.nan, inplace=True)\n#     df.dropna(inplace=True)\n#     print(f\"Data shape after removing inf/-inf rows: {df.shape}\")\n#     print(f\"Inf / -Inf Clean Time: {round(time.time() - start_inf, 2)} seconds\")\n\n#     # 🔧 Convert all columns to float32\n#     df = df.astype(np.float32)\n#     print(f\"✅ Converted all columns to float32. Current memory usage: {df.memory_usage().sum() / 1e6:.2f} MB\")\n\n#     # 4️⃣ Save Cleaned Data (Optional)\n#     if file_name:\n#         save_path = f\"/kaggle/working/{file_name}\"\n#         df.to_parquet(save_path, index=False)\n#         print(f\"✅ Saved cleaned data to: {save_path}\")\n\n#     # 5️⃣ Delete DataFrame & Force GC\n#     del df\n#     gc.collect()\n#     print(\"🗑️ DataFrame deleted from memory and garbage collected.\")\n\n#     # 6️⃣ Read Back if Needed\n#     if file_name:\n#         df = pd.read_parquet(f\"/kaggle/working/{file_name}\")\n#         print(\"✅ Reloaded DataFrame from saved file.\")\n#         return df\n#     else:\n#         print(\"✅ Returned cleaned DataFrame.\")\n#         return df  # Instead of returning None\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import gc\nfrom pandas.util import hash_pandas_object as hash_object\n\n\ndef clean_dataset(df: pd.DataFrame) -> pd.DataFrame:\n    import time\n\n    print(\"\\n==========================\")\n    print(f\"🧹 Cleaning Data\")\n    print(\"==========================\")\n\n    # 1️⃣ Null Columns Check\n    start_null = time.time()\n    null_counts = df.isnull().sum()\n    null_columns = null_counts[null_counts > 0]\n    if not null_columns.empty:\n        print(f\"Columns with Null Values:\\n{null_columns}\")\n    else:\n        print(\"No columns contain null values.\")\n    print(f\"Null Check Time: {round(time.time() - start_null, 2)} seconds\")\n\n    # 2️⃣ Drop Duplicate Columns (Hashing)\n    start_dup_cols = time.time()\n    hashes = df.apply(lambda col: hash_object(col).sum())\n    duplicates_mask = hashes.duplicated()\n    duplicate_columns = df.columns[duplicates_mask]\n    if len(duplicate_columns) > 0:\n        print(f\"Dropping duplicate columns: {duplicate_columns.tolist()}\")\n        df = df.drop(columns=duplicate_columns)\n    else:\n        print(\"No duplicate columns found.\")\n    print(f\"Duplicate Columns Check Time: {round(time.time() - start_dup_cols, 2)} seconds\")\n\n    # 2️⃣.b Drop Duplicate Rows\n    start_row_dup = time.time()\n    initial_shape = df.shape\n    df.drop_duplicates(inplace=True)\n    final_shape = df.shape\n    rows_dropped = initial_shape[0] - final_shape[0]\n    if rows_dropped > 0:\n        print(f\"Dropped {rows_dropped} duplicate rows.\")\n    else:\n        print(\"No duplicate rows found.\")\n    print(f\"Duplicate Rows Check Time: {round(time.time() - start_row_dup, 2)} seconds\")\n\n    # 3️⃣ Drop inf / -inf and Rows with NaNs\n    start_inf = time.time()\n    df.replace([np.inf, -np.inf], np.nan, inplace=True)\n    df.dropna(inplace=True)\n    print(f\"Data shape after removing inf/-inf rows: {df.shape}\")\n    print(f\"Inf / -Inf Clean Time: {round(time.time() - start_inf, 2)} seconds\")\n\n   \n    print(f\"✅ Current memory usage: {df.memory_usage().sum() / 1e6:.2f} MB\")\n\n    # 🔄 Garbage Collection (Optional)\n    gc.collect()\n\n    print(\"✅ Returned cleaned DataFrame.\")\n    return df\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T18:34:39.428336Z","iopub.execute_input":"2025-07-18T18:34:39.428622Z","iopub.status.idle":"2025-07-18T18:34:39.436964Z","shell.execute_reply.started":"2025-07-18T18:34:39.428599Z","shell.execute_reply":"2025-07-18T18:34:39.436105Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# train_file = \"cleaned_train.parquet\"\n# test_file = \"cleaned_test.parquet\"\n\n# df_train_cleaned = clean_dataset(df_train, train_file)\n# df_test_cleaned = clean_dataset(df_test, test_file)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train_cleaned = clean_dataset(df_train)\ndf_test_cleaned = clean_dataset(df_test)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T18:34:46.118296Z","iopub.execute_input":"2025-07-18T18:34:46.118881Z","iopub.status.idle":"2025-07-18T18:35:50.539822Z","shell.execute_reply.started":"2025-07-18T18:34:46.118857Z","shell.execute_reply":"2025-07-18T18:35:50.538906Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 2. Uploading Cleaned Data","metadata":{}},{"cell_type":"code","source":"# df_train_cleaned = pd.read_parquet(\"/kaggle/working/cleaned_train.parquet\")\n# df_test_cleaned = pd.read_parquet(\"/kaggle/working/cleaned_test.parquet\")","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"\\n====== df_train_cleaned.shape ======\")\nprint(df_train_cleaned.shape)\n\n# Show the first 5 rows of df_test\nprint(\"\\n====== df_test_cleaned.shape ======\")\nprint(df_test_cleaned.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T18:36:18.048353Z","iopub.execute_input":"2025-07-18T18:36:18.049067Z","iopub.status.idle":"2025-07-18T18:36:18.053602Z","shell.execute_reply.started":"2025-07-18T18:36:18.049037Z","shell.execute_reply":"2025-07-18T18:36:18.052838Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ram = psutil.virtual_memory()\nprint(f'Total RAM: {ram.total / (1024 ** 3):.2f} GB')\nprint(f'Available RAM: {ram.available / (1024 ** 3):.2f} GB')\nprint(f'Used RAM: {ram.used / (1024 ** 3):.2f} GB')\nprint(f'RAM Usage %: {ram.percent}%')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T18:36:23.238460Z","iopub.execute_input":"2025-07-18T18:36:23.238773Z","iopub.status.idle":"2025-07-18T18:36:23.243972Z","shell.execute_reply.started":"2025-07-18T18:36:23.238749Z","shell.execute_reply":"2025-07-18T18:36:23.243357Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 4. Handle Outliers Aggressively\n## 5. Feature Importance with XGBoost / LightGBM\n## 6. RankGauss (QuantileTransformer) Scaling","metadata":{}},{"cell_type":"code","source":"# import gc\n# from sklearn.preprocessing import QuantileTransformer\n# from xgboost import XGBRegressor\n\n# #\n# def prepare_train_data(df_train: pd.DataFrame, label_col: str = 'label', importance_threshold: float = 0.000001):\n#     # 1️⃣ Clip Outliers\n#     for col in df_train.drop(columns=[label_col]).columns:\n#         lower = df_train[col].quantile(0.01)\n#         upper = df_train[col].quantile(0.99)\n#         df_train[col] = df_train[col].clip(lower, upper)\n\n#     # 2️⃣ XGBoost Feature Importance\n#     X_train = df_train.drop(columns=[label_col])\n#     y_train = df_train[label_col]\n#     model = XGBRegressor()\n#     model.fit(X_train, y_train)\n\n#     importance = pd.Series(model.feature_importances_, index=X_train.columns)\n#     important_features = importance[importance > importance_threshold].index.tolist()\n\n#     # 3️⃣ Quantile Scaling\n#     scaler = QuantileTransformer(output_distribution='normal', random_state=42)\n#     X_train_scaled = scaler.fit_transform(X_train[important_features])\n\n#     df_train_cleaned = pd.DataFrame(X_train_scaled, columns=important_features)\n#     df_train_cleaned[label_col] = y_train.reset_index(drop=True)\n\n#     # 4️⃣ Explicit Memory Cleanup\n#     del df_train, X_train, y_train, X_train_scaled, model, importance\n#     gc.collect()\n\n#     return df_train_cleaned, important_features, scaler\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.preprocessing import QuantileTransformer\nfrom xgboost import XGBRegressor\n\n\ndef prepare_train_data(df_train: pd.DataFrame, label_col: str = 'label', importance_threshold: float = 1e-6):\n    print(\"1️⃣ Clipping Outliers...\")\n    # 1️⃣ Clip Outliers\n    for col in df_train.drop(columns=[label_col]).columns:\n        low = df_train[col].quantile(0.01)\n        high = df_train[col].quantile(0.99)\n        df_train[col] = df_train[col].clip(lower=low, upper=high)\n    print(\"✅ Outliers clipped.\")\n\n    print(\"2️⃣ Fitting XGBoost Model for Feature Importance (GPU)...\")\n    # 2️⃣ XGBoost Feature Importance with GPU\n    X_train = df_train.drop(columns=[label_col])\n    y_train = df_train[label_col]\n    model = XGBRegressor(tree_method='hist', device='cuda')\n    model.fit(X_train, y_train)\n    print(\"✅ XGBoost Model Trained.\")\n\n    importance = pd.Series(model.feature_importances_, index=X_train.columns)\n    important_features = importance[importance > importance_threshold].index.tolist()\n    print(f\"✅ Selected {len(important_features)} important features: {important_features}\")\n\n    print(\"3️⃣ Applying Quantile Scaling...\")\n    # 3️⃣ Quantile Scaling (CPU)\n    scaler = QuantileTransformer(output_distribution='normal', random_state=42)\n    X_train_scaled = scaler.fit_transform(X_train[important_features])\n    print(\"✅ Quantile Scaling Completed.\")\n\n    df_train_cleaned = pd.DataFrame(X_train_scaled, columns=important_features)\n    df_train_cleaned[label_col] = y_train.reset_index(drop=True)\n\n    print(\"4️⃣ Cleaning Up Memory...\")\n    # 4️⃣ Cleanup\n    del df_train, X_train, y_train, X_train_scaled, model, importance\n    gc.collect()\n    print(\"✅ Memory cleaned.\")\n\n    print(\"🎉 Data Preparation Completed.\")\n    return df_train_cleaned, important_features, scaler\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T18:36:42.148493Z","iopub.execute_input":"2025-07-18T18:36:42.148773Z","iopub.status.idle":"2025-07-18T18:36:42.866243Z","shell.execute_reply.started":"2025-07-18T18:36:42.148752Z","shell.execute_reply":"2025-07-18T18:36:42.865655Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def prepare_test_data(df_test: pd.DataFrame, important_features, scaler):\n    print(\"1️⃣ Selecting Important Features from Test Data...\")\n    X_test = df_test[important_features]\n    print(\"✅ Selected important features.\")\n\n    print(\"2️⃣ Applying Quantile Scaling to Test Data...\")\n    X_test_scaled = scaler.transform(X_test)\n    print(\"✅ Quantile Scaling applied.\")\n\n    df_test_cleaned = pd.DataFrame(X_test_scaled, columns=important_features)\n    print(\"✅ Created cleaned test DataFrame.\")\n\n    print(\"3️⃣ Cleaning Up Memory...\")\n    # 🔴 Explicit memory cleanup\n    del df_test, X_test, X_test_scaled\n    gc.collect()\n    print(\"✅ Memory cleaned.\")\n\n    print(\"🎉 Test Data Preparation Completed.\")\n    return df_test_cleaned\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T18:36:46.098476Z","iopub.execute_input":"2025-07-18T18:36:46.099204Z","iopub.status.idle":"2025-07-18T18:36:46.104081Z","shell.execute_reply.started":"2025-07-18T18:36:46.099180Z","shell.execute_reply":"2025-07-18T18:36:46.103245Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train_cleaned, important_features, scaler = prepare_train_data(df_train_cleaned, label_col='label')\ndf_test_cleaned = prepare_test_data(df_test_cleaned, important_features, scaler)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T18:36:54.038278Z","iopub.execute_input":"2025-07-18T18:36:54.038783Z","iopub.status.idle":"2025-07-18T18:40:25.958445Z","shell.execute_reply.started":"2025-07-18T18:36:54.038757Z","shell.execute_reply":"2025-07-18T18:40:25.957565Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"\\n====== df_train_cleaned.shape ======\")\nprint(df_train_cleaned.shape)\n\n# Show the first 5 rows of df_test\nprint(\"\\n====== df_test_cleaned.shape ======\")\nprint(df_test_cleaned.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T18:40:38.358046Z","iopub.execute_input":"2025-07-18T18:40:38.358332Z","iopub.status.idle":"2025-07-18T18:40:38.362925Z","shell.execute_reply.started":"2025-07-18T18:40:38.358309Z","shell.execute_reply":"2025-07-18T18:40:38.362130Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ram = psutil.virtual_memory()\nprint(f'Total RAM: {ram.total / (1024 ** 3):.2f} GB')\nprint(f'Available RAM: {ram.available / (1024 ** 3):.2f} GB')\nprint(f'Used RAM: {ram.used / (1024 ** 3):.2f} GB')\nprint(f'RAM Usage %: {ram.percent}%')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T18:40:43.018039Z","iopub.execute_input":"2025-07-18T18:40:43.018706Z","iopub.status.idle":"2025-07-18T18:40:43.023781Z","shell.execute_reply.started":"2025-07-18T18:40:43.018677Z","shell.execute_reply":"2025-07-18T18:40:43.023050Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nfrom sklearn.model_selection import KFold\nfrom sklearn.metrics import mean_squared_error\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, BatchNormalization, Input\nfrom tensorflow.keras.callbacks import EarlyStopping\nfrom tensorflow.keras.optimizers import AdamW\nfrom tensorflow.keras import mixed_precision\n\n\n# ⚡ Mixed Precision for faster GPU computation\nprint(\"⚡ Enabling Mixed Precision for TensorFlow...\")\nmixed_precision.set_global_policy('mixed_float16')\nprint(\"✅ Mixed Precision enabled.\\n\")\n\n# 📦 KFold Setup\nkf = KFold(n_splits=5, shuffle=True, random_state=42)\nprint(f\"📦 KFold Split: {kf.get_n_splits()} folds configured.\\n\")\n\n# 🏗️ Model Architecture\ndef build_model(input_shape):\n    print(f\"🔧 Building Model for input shape: {input_shape}\")\n    model = Sequential([\n        Input(shape=(input_shape,)),\n        Dense(512, activation='relu'),\n        BatchNormalization(),\n        Dense(256, activation='relu'),\n        BatchNormalization(),\n        Dense(128, activation='relu'),\n        BatchNormalization(),\n        Dense(1, dtype='float32')  # Output must be float32\n    ])\n    model.compile(optimizer=AdamW(learning_rate=1e-3), loss='mse', metrics=['mae'])\n    print(\"✅ Model Compiled.\\n\")\n    return model\n\n\n# 🛠️ Prepare Data\nprint(\"🛠️ Preparing Data...\")\nX_np = df_train_cleaned.drop(columns=['label']).values.astype(np.float32)\ny_np = df_train_cleaned['label'].values.astype(np.float32)\nX_test_np = df_test_cleaned.values.astype(np.float32)\nprint(f\"✅ Data prepared with shapes: X_train {X_np.shape}, y_train {y_np.shape}, X_test {X_test_np.shape}\\n\")\n\noof_preds = np.zeros(len(X_np))\ntest_preds = np.zeros(len(X_test_np))\n\n# 🏋️‍♂️ Training Loop with EarlyStopping\nearly_stop = EarlyStopping(monitor='val_mae', patience=5, restore_best_weights=True, verbose=1)\n\nfor fold, (train_idx, val_idx) in enumerate(kf.split(X_np)):\n    print(f\"\\n🌀 Starting Fold {fold+1}/5...\")\n\n    X_train, X_val = X_np[train_idx], X_np[val_idx]\n    y_train, y_val = y_np[train_idx], y_np[val_idx]\n    print(f\"📊 Train shape: {X_train.shape}, Validation shape: {X_val.shape}\")\n\n    model = build_model(X_train.shape[1])\n    history = model.fit(X_train, y_train,\n                        validation_data=(X_val, y_val),\n                        epochs=100,\n                        batch_size=2048,  # T4 handles large batches better\n                        callbacks=[early_stop],\n                        verbose=1)\n\n    print(f\"📈 Predicting on validation set (Fold {fold+1})...\")\n    oof_preds[val_idx] = model.predict(X_val, batch_size=2048).reshape(-1)\n    print(f\"📈 Predicting on test set (Fold {fold+1})...\")\n    test_preds += model.predict(X_test_np, batch_size=2048).reshape(-1) / kf.n_splits\n\n    print(f\"🧹 Cleaning memory for Fold {fold+1}...\")\n    del X_train, X_val, y_train, y_val, model, history\n    gc.collect()\n    print(f\"✅ Fold {fold+1} completed.\\n\")\n\n\n# 📊 Evaluate Out-of-Fold Performance\nmse = mean_squared_error(y_np, oof_preds)\nprint(f\"\\n✅ Out-Of-Fold MSE: {mse:.5f}\")\n\n# 🎯 Final Test Predictions Sample\nprint(\"\\n🎯 Final Test Predictions (first 10 rows):\")\nprint(test_preds[:10])\n\n# 💾 Save Predictions if needed\nprint(\"\\n💾 Saving predictions to disk...\")\nnp.save(\"oof_preds.npy\", oof_preds)\nnp.save(\"test_preds.npy\", test_preds)\nprint(\"✅ Predictions saved as 'oof_preds.npy' and 'test_preds.npy'.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T18:40:47.288250Z","iopub.execute_input":"2025-07-18T18:40:47.288500Z","iopub.status.idle":"2025-07-18T18:46:31.282791Z","shell.execute_reply.started":"2025-07-18T18:40:47.288483Z","shell.execute_reply":"2025-07-18T18:46:31.281909Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ram = psutil.virtual_memory()\nprint(f'Total RAM: {ram.total / (1024 ** 3):.2f} GB')\nprint(f'Available RAM: {ram.available / (1024 ** 3):.2f} GB')\nprint(f'Used RAM: {ram.used / (1024 ** 3):.2f} GB')\nprint(f'RAM Usage %: {ram.percent}%')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T18:46:38.970297Z","iopub.execute_input":"2025-07-18T18:46:38.971231Z","iopub.status.idle":"2025-07-18T18:46:38.976528Z","shell.execute_reply.started":"2025-07-18T18:46:38.971201Z","shell.execute_reply":"2025-07-18T18:46:38.975795Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"mse = mean_squared_error(y_np, oof_preds)\nprint(f\"\\n✅ OOF MSE: {mse:.6f}\")\n\n# Save to submission\nsubmission = pd.DataFrame({\n    \"ID\": range(1, len(test_preds)+1),  # or use actual test IDs if available\n    \"prediction\": test_preds\n})\nsubmission.to_csv(\"submission.csv\", index=False)\nprint(\"📦 Saved: submission.csv\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T18:48:14.749380Z","iopub.execute_input":"2025-07-18T18:48:14.749694Z","iopub.status.idle":"2025-07-18T18:48:15.814357Z","shell.execute_reply.started":"2025-07-18T18:48:14.749670Z","shell.execute_reply":"2025-07-18T18:48:15.813512Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission.tail()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-18T18:48:20.600267Z","iopub.execute_input":"2025-07-18T18:48:20.600570Z","iopub.status.idle":"2025-07-18T18:48:20.609077Z","shell.execute_reply.started":"2025-07-18T18:48:20.600548Z","shell.execute_reply":"2025-07-18T18:48:20.608148Z"}},"outputs":[],"execution_count":null}]}