{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":104857,"databundleVersionId":12651513,"sourceType":"competition"}],"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},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\nimport pandas as pd\nimport numpy as np\nimport xgboost as xgb\nimport lightgbm as lgb\nfrom sklearn.preprocessing import StandardScaler, LabelEncoder\nfrom sklearn.impute import SimpleImputer\nfrom sklearn.metrics import mean_squared_error\nimport warnings\n\nwarnings.filterwarnings('ignore')\nprint(\"Libraries imported successfully.\")\n\ntry:\n    df_train = pd.read_csv('/kaggle/input/burnout-datathon-ieeecsmuj/train.csv')\n    df_val = pd.read_csv('/kaggle/input/burnout-datathon-ieeecsmuj/val.csv')\n    df_test = pd.read_csv('/kaggle/input/burnout-datathon-ieeecsmuj/test.csv')\n    sample_submission = pd.read_csv('/kaggle/input/burnout-datathon-ieeecsmuj/sample_submission.csv')\n    print(\"Datasets loaded successfully.\")\nexcept FileNotFoundError:\n    print(\"ERROR: Could not find data files. Make sure the Kaggle input path is correct.\")\n    exit()\n\ndf_train.columns = df_train.columns.str.lower()\ndf_val.columns = df_val.columns.str.lower()\ndf_test.columns = df_test.columns.str.lower()\nprint(\"\\nAll column names converted to lowercase for consistency.\")\nprint(f\"Train shape: {df_train.shape}, Val shape: {df_val.shape}, Test shape: {df_test.shape}\")\n\ndef feature_engineer(df):\n    df_out = df.copy()\n    df_out['corners_per_lap'].fillna(0, inplace=True)\n    df_out['circuit_length_km'].fillna(1, inplace=True)\n    df_out['corners_per_km'] = df_out['corners_per_lap'] / df_out['circuit_length_km']\n    df_out['temp_difference'] = df_out['track_temperature_celsius'] - df_out['ambient_temperature_celsius']\n    epsilon = 1e-6\n    df_out['win_rate'] = df_out['wins'] / (df_out['starts'] + epsilon)\n    df_out['podium_rate'] = df_out['podiums'] / (df_out['starts'] + epsilon)\n    df_out['finish_rate'] = df_out['finishes'] / (df_out['starts'] + epsilon)\n    df_out.replace([np.inf, -np.inf], 0, inplace=True)\n    df_out.fillna(0, inplace=True)\n    return df_out\n\nprint(\"\\nFeature engineering function defined.\")\n\nprint(\"\\nStarting data preprocessing...\")\n\nTARGET = 'lap_time_seconds'\n\ncombined_df = pd.concat([df_train.drop(TARGET, axis=1), df_val.drop(TARGET, axis=1), df_test], ignore_index=True)\n\ncols_to_drop = [\n    'rider_name', 'team_name', 'bike_name', 'circuit_name',\n    'track', 'air', 'ground', 'position', 'points', 'shortname', 'year_x', 'sequence'\n]\ncombined_df.drop(columns=cols_to_drop, inplace=True, errors='ignore')\nprint(f\"Dropped {len(cols_to_drop)} columns.\")\n\ncombined_df = feature_engineer(combined_df)\nprint(\"Feature engineering applied.\")\n\nnumerical_features = combined_df.select_dtypes(include=np.number).columns.tolist()\ncategorical_features = combined_df.select_dtypes(exclude=np.number).columns.tolist()\n\nnumerical_features.remove('unique id')\n\nimputer_num = SimpleImputer(strategy='median')\ncombined_df[numerical_features] = imputer_num.fit_transform(combined_df[numerical_features])\n\nimputer_cat = SimpleImputer(strategy='most_frequent')\ncombined_df[categorical_features] = imputer_cat.fit_transform(combined_df[categorical_features])\nprint(\"Missing values imputed.\")\n\nfor col in categorical_features:\n    le = LabelEncoder()\n    combined_df[col] = le.fit_transform(combined_df[col].astype(str))\nprint(\"Categorical features label-encoded.\")\n\nscaler = StandardScaler()\ncombined_df[numerical_features] = scaler.fit_transform(combined_df[numerical_features])\nprint(\"Numerical features scaled.\")\n\ntrain_processed = combined_df.iloc[:len(df_train)]\nval_processed = combined_df.iloc[len(df_train):len(df_train) + len(df_val)]\ntest_processed = combined_df.iloc[len(df_train) + len(df_val):]\n\ntest_ids = test_processed['unique id']\ntrain_processed.drop(columns=['unique id'], inplace=True)\nval_processed.drop(columns=['unique id'], inplace=True)\ntest_processed.drop(columns=['unique id'], inplace=True)\n\ny_train = df_train[TARGET]\ny_val = df_val[TARGET]\n\nprint(\"\\nPreprocessing complete. Final shapes:\")\nprint(f\"X_train: {train_processed.shape}, y_train: {y_train.shape}\")\nprint(f\"X_val: {val_processed.shape}, y_val: {y_val.shape}\")\nprint(f\"X_test: {test_processed.shape}\")\nprint(\"\\n--- Training LightGBM Model ---\")\n\nprint(\"\\n--- Training XGBoost Model ---\")\nxgb_model = xgb.XGBRegressor(\n    objective='reg:squarederror',\n    n_estimators=500,\n    learning_rate=0.05,\n    max_depth=15,\n    colsample_bytree=0.75,\n    random_state=42,\n    n_jobs=-1,\n    tree_method='hist'\n)\n\nxgb_model.fit(\n    train_processed, y_train,\n    eval_set=[(val_processed, y_val)],\n    verbose=False\n)\n\ny_pred_xgb_val = xgb_model.predict(val_processed)\nrmse_xgb = np.sqrt(mean_squared_error(y_val, y_pred_xgb_val))\nprint(f\"🚀 Single XGBoost Model - Validation RMSE: {rmse_xgb:.5f}\")\n\nprint(\"\\n--- Generating Final Predictions for Submission ---\")\npreds_test_xgb = xgb_model.predict(test_processed)\nfinal_predictions = preds_test_xgb\nsubmission_df = pd.DataFrame({\n    'Unique ID': test_ids.astype(int), \n    'Lap_Time_Seconds': final_predictions\n})\nsubmission_df.to_csv('submission.csv', index=False)\nprint(\"\\n✅ Submission file 'submission.csv' created successfully!\")\nprint(\"Top 5 rows of submission file:\")\nprint(submission_df.head())\n","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}