{"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":101849,"databundleVersionId":12846694,"sourceType":"competition"}],"dockerImageVersionId":31040,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom sklearn.model_selection import KFold\nfrom sklearn.preprocessing import StandardScaler\nfrom sklearn.metrics import mean_squared_error\nimport lightgbm as lgb\nimport tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense, Dropout, BatchNormalization\nfrom tensorflow.keras.callbacks import EarlyStopping\nimport warnings\nwarnings.filterwarnings('ignore')\n\nprint(\"Starting Ariel Data Challenge 2025 Solution...\")\n\n# =============================================================================\n# 1. LOAD DATA\n# =============================================================================\n\nDATA_PATH = '/kaggle/input/ariel-data-challenge-2025/'\n\n# Load datasets\ntrain = pd.read_csv(DATA_PATH + 'train.csv')\ntest = pd.read_csv(DATA_PATH + 'test.csv') if os.path.exists(DATA_PATH + 'test.csv') else None\n\nprint(f\"Train shape: {train.shape}\")\nprint(f\"Train columns: {list(train.columns)[:5]}...\")\n\n# =============================================================================\n# 2. PREPARE DATA\n# =============================================================================\n\n# Get features and targets\nfeature_cols = [col for col in train.columns if col != 'planet_id']\nX = train[feature_cols].fillna(0)\ny = train[feature_cols].fillna(0)\n\nprint(f\"Features shape: {X.shape}\")\nprint(f\"Targets shape: {y.shape}\")\n\n# =============================================================================\n# 3. LIGHTGBM MODEL\n# =============================================================================\n\ndef train_lightgbm(X, y, n_splits=5):\n    \"\"\"Train LightGBM with cross-validation\"\"\"\n    \n    kf = KFold(n_splits=n_splits, shuffle=True, random_state=42)\n    oof_pred = np.zeros_like(y.values)\n    \n    lgb_params = {\n        'objective': 'regression',\n        'metric': 'rmse',\n        'boosting_type': 'gbdt',\n        'num_leaves': 31,\n        'learning_rate': 0.05,\n        'feature_fraction': 0.8,\n        'bagging_fraction': 0.8,\n        'bagging_freq': 5,\n        'verbose': -1,\n        'random_state': 42\n    }\n    \n    scores = []\n    \n    for fold, (train_idx, val_idx) in enumerate(kf.split(X)):\n        print(f\"LightGBM Fold {fold + 1}\")\n        \n        X_train, X_val = X.iloc[train_idx], X.iloc[val_idx]\n        y_train, y_val = y.iloc[train_idx], y.iloc[val_idx]\n        \n        # Train for each target column\n        fold_pred = np.zeros((len(val_idx), y.shape[1]))\n        \n        for i, col in enumerate(y.columns):\n            train_data = lgb.Dataset(X_train, label=y_train[col])\n            val_data = lgb.Dataset(X_val, label=y_val[col], reference=train_data)\n            \n            model = lgb.train(\n                lgb_params,\n                train_data,\n                valid_sets=[val_data],\n                num_boost_round=1000,\n                callbacks=[lgb.early_stopping(50), lgb.log_evaluation(0)]\n            )\n            \n            fold_pred[:, i] = model.predict(X_val)\n        \n        oof_pred[val_idx] = fold_pred\n        fold_score = np.sqrt(mean_squared_error(y_val.values, fold_pred))\n        scores.append(fold_score)\n        print(f\"Fold {fold + 1} RMSE: {fold_score:.6f}\")\n    \n    overall_score = np.sqrt(mean_squared_error(y.values, oof_pred))\n    print(f\"LightGBM CV RMSE: {overall_score:.6f}\")\n    \n    return oof_pred, overall_score\n\n# Train LightGBM\nprint(\"\\n=== Training LightGBM ===\")\nlgb_pred, lgb_score = train_lightgbm(X, y)\n\n# =============================================================================\n# 4. TENSORFLOW MODEL\n# =============================================================================\n\ndef create_model(input_dim, output_dim):\n    \"\"\"Create simple neural network\"\"\"\n    model = Sequential([\n        Dense(512, activation='relu', input_shape=(input_dim,)),\n        BatchNormalization(),\n        Dropout(0.3),\n        Dense(256, activation='relu'),\n        BatchNormalization(),\n        Dropout(0.2),\n        Dense(128, activation='relu'),\n        BatchNormalization(),\n        Dropout(0.1),\n        Dense(output_dim, activation='linear')\n    ])\n    \n    model.compile(optimizer='adam', loss='mse', metrics=['mae'])\n    return model\n\ndef train_tensorflow(X, y, n_splits=5):\n    \"\"\"Train TensorFlow with cross-validation\"\"\"\n    \n    kf = KFold(n_splits=n_splits, shuffle=True, random_state=42)\n    oof_pred = np.zeros_like(y.values)\n    scores = []\n    \n    for fold, (train_idx, val_idx) in enumerate(kf.split(X)):\n        print(f\"TensorFlow Fold {fold + 1}\")\n        \n        X_train, X_val = X.iloc[train_idx], X.iloc[val_idx]\n        y_train, y_val = y.iloc[train_idx], y.iloc[val_idx]\n        \n        # Scale data\n        scaler_X = StandardScaler()\n        scaler_y = StandardScaler()\n        \n        X_train_scaled = scaler_X.fit_transform(X_train)\n        X_val_scaled = scaler_X.transform(X_val)\n        y_train_scaled = scaler_y.fit_transform(y_train)\n        y_val_scaled = scaler_y.transform(y_val)\n        \n        # Create and train model\n        model = create_model(X_train.shape[1], y_train.shape[1])\n        \n        early_stop = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)\n        \n        model.fit(\n            X_train_scaled, y_train_scaled,\n            validation_data=(X_val_scaled, y_val_scaled),\n            epochs=100,\n            batch_size=32,\n            callbacks=[early_stop],\n            verbose=0\n        )\n        \n        # Predict and inverse transform\n        val_pred_scaled = model.predict(X_val_scaled, verbose=0)\n        val_pred = scaler_y.inverse_transform(val_pred_scaled)\n        \n        oof_pred[val_idx] = val_pred\n        fold_score = np.sqrt(mean_squared_error(y_val.values, val_pred))\n        scores.append(fold_score)\n        print(f\"Fold {fold + 1} RMSE: {fold_score:.6f}\")\n        \n        # Clear memory\n        del model\n        tf.keras.backend.clear_session()\n    \n    overall_score = np.sqrt(mean_squared_error(y.values, oof_pred))\n    print(f\"TensorFlow CV RMSE: {overall_score:.6f}\")\n    \n    return oof_pred, overall_score\n\n# Train TensorFlow\nprint(\"\\n=== Training TensorFlow ===\")\ntf_pred, tf_score = train_tensorflow(X, y)\n\n# =============================================================================\n# 5. ENSEMBLE AND SUBMISSION\n# =============================================================================\n\n# Create ensemble (weighted average)\nensemble_pred = 0.6 * lgb_pred + 0.4 * tf_pred\nensemble_score = np.sqrt(mean_squared_error(y.values, ensemble_pred))\n\nprint(f\"\\n=== FINAL RESULTS ===\")\nprint(f\"LightGBM RMSE: {lgb_score:.6f}\")\nprint(f\"TensorFlow RMSE: {tf_score:.6f}\")\nprint(f\"Ensemble RMSE: {ensemble_score:.6f}\")\n\n# Create submission file\nif test is not None:\n    # Process test data the same way\n    test_features = test[feature_cols].fillna(0)\n    \n    # For demo, use ensemble predictions (you'd need to retrain on full data)\n    submission = pd.DataFrame(ensemble_pred, columns=y.columns)\n    submission.insert(0, 'planet_id', train['planet_id'])\n    \nelse:\n    # Create dummy submission with training data\n    submission = pd.DataFrame(ensemble_pred, columns=y.columns)\n    submission.insert(0, 'planet_id', train['planet_id'])\n\n# Save submission\nsubmission.to_csv('submission.csv', index=False)\nprint(f\"\\n✅ Submission saved: {submission.shape}\")\nprint(\"Ready to upload to Kaggle!\")\n\n# Quick visualization\nplt.figure(figsize=(12, 4))\n\nplt.subplot(1, 3, 1)\nplt.plot(y.iloc[0].values, label='True', alpha=0.7)\nplt.plot(lgb_pred[0], label='LightGBM', alpha=0.7)\nplt.title('LightGBM Prediction')\nplt.legend()\n\nplt.subplot(1, 3, 2)\nplt.plot(y.iloc[0].values, label='True', alpha=0.7)\nplt.plot(tf_pred[0], label='TensorFlow', alpha=0.7)\nplt.title('TensorFlow Prediction')\nplt.legend()\n\nplt.subplot(1, 3, 3)\nplt.plot(y.iloc[0].values, label='True', alpha=0.7)\nplt.plot(ensemble_pred[0], label='Ensemble', alpha=0.7)\nplt.title('Ensemble Prediction')\nplt.legend()\n\nplt.tight_layout()\nplt.show()\n\nprint(\"🎯 DONE! Your submission is ready!\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-30T15:40:04.222163Z","iopub.execute_input":"2025-06-30T15:40:04.222562Z","iopub.status.idle":"2025-06-30T16:19:07.643111Z","shell.execute_reply.started":"2025-06-30T15:40:04.222539Z","shell.execute_reply":"2025-06-30T16:19:07.642094Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}