{"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":104857,"databundleVersionId":12651513,"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-06-14T16:51:13.841117Z","iopub.execute_input":"2025-06-14T16:51:13.841832Z","iopub.status.idle":"2025-06-14T16:51:14.276672Z","shell.execute_reply.started":"2025-06-14T16:51:13.841803Z","shell.execute_reply":"2025-06-14T16:51:14.275791Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df = pd.read_csv(\"/kaggle/input/burnout-datathon-ieeecsmuj/train.csv\")\nval = pd.read_csv(\"/kaggle/input/burnout-datathon-ieeecsmuj/val.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:51:14.278281Z","iopub.execute_input":"2025-06-14T16:51:14.278982Z","iopub.status.idle":"2025-06-14T16:51:31.509976Z","shell.execute_reply.started":"2025-06-14T16:51:14.278954Z","shell.execute_reply":"2025-06-14T16:51:31.509108Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport lightgbm as lgb\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.preprocessing import StandardScaler, OneHotEncoder\nfrom sklearn.compose import ColumnTransformer\nfrom sklearn.metrics import mean_squared_error\nfrom sklearn.utils import shuffle\nfrom tqdm import tqdm","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:51:31.511224Z","iopub.execute_input":"2025-06-14T16:51:31.511608Z","iopub.status.idle":"2025-06-14T16:51:33.905619Z","shell.execute_reply.started":"2025-06-14T16:51:31.511575Z","shell.execute_reply":"2025-06-14T16:51:33.904595Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# EDA","metadata":{}},{"cell_type":"code","source":"df.dtypes","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:51:33.907719Z","iopub.execute_input":"2025-06-14T16:51:33.908357Z","iopub.status.idle":"2025-06-14T16:51:33.917260Z","shell.execute_reply.started":"2025-06-14T16:51:33.908329Z","shell.execute_reply":"2025-06-14T16:51:33.916383Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Feature Engineering","metadata":{}},{"cell_type":"code","source":"def feature_engineering(df):\n    df = df.copy()\n    \n    weather_score = {\"Sunny\": 1, \"Clear\": 1, \"Partly cloudy\": 2, \"Cloudy\": 2, \"Raining\": 3, \"Overcast\": 2}\n    track_score = {\"Dry\": 1, \"Wet\": 2}\n    tire_score = {\"Soft\": 3, \"Medium\": 2, \"Hard\": 1}\n    penalty_score = {\"DNS\": 0, \"DNF\": 0, \"+3s\": 3, \"+5s\": 5, \"Ride Through\": 22, None: 0}\n    \n    df[\"Track_Surface_Index\"] = df[\"track\"].map(track_score) * df[\"Track_Condition\"].map(track_score)\n    df[\"Tire_Grip_Score\"] = df[\"Tire_Compound_Front\"].map(tire_score) + df[\"Tire_Compound_Rear\"].map(tire_score)\n    df['Composite_Performance'] = df['points'] + df['Championship_Points'] - df['position'] - df['Championship_Position']\n    df['Success_Rate'] = df['with_points'] / df['starts']\n    df['Average_Starts_Per_Year'] = df['starts'] / df['years_active']\n    df[\"Penalty_Severity\"] = df[\"Penalty\"].map(penalty_score).fillna(0)\n    \n    drop_columns = [\n        'points', 'Championship_Points', 'position', 'Championship_Position',\n        'with_points', 'finishes', 'years_active',\n        \"track\", \"Track_Condition\", \"Tire_Compound_Front\", \"Tire_Compound_Rear\",\n        'Unique ID', 'Rider_ID', 'rider_name', 'team_name', 'bike_name',\n        'circuit_name', 'shortname', 'min_year', 'max_year', 'Track_Temperature_Celsius',\n        'podiums', 'wins', 'Penalty'\n    ]\n    df.drop(columns=[col for col in drop_columns if col in df.columns], inplace=True)\n    return df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:51:33.918309Z","iopub.execute_input":"2025-06-14T16:51:33.918629Z","iopub.status.idle":"2025-06-14T16:51:33.936367Z","shell.execute_reply.started":"2025-06-14T16:51:33.918598Z","shell.execute_reply":"2025-06-14T16:51:33.935384Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Training and Testing for TRAIN data","metadata":{}},{"cell_type":"code","source":"df = feature_engineering(df)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X = df.drop(columns=[\"Lap_Time_Seconds\"])\ny = df[\"Lap_Time_Seconds\"]\n\nnum_cols = X.select_dtypes(include=[\"int64\", \"float64\"]).columns.tolist()\ncat_cols = X.select_dtypes(include=[\"object\"]).columns.tolist()\n\npreprocessor = ColumnTransformer([\n    (\"num\", StandardScaler(), num_cols),\n    (\"cat\", OneHotEncoder(handle_unknown=\"ignore\", sparse=False), cat_cols)\n])\n\nX_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)\n\n# Preprocess \npreprocessor.fit(X_train)\nX_train_trans = preprocessor.transform(X_train)\nX_val_trans = preprocessor.transform(X_val)\n\ntrain_data = lgb.Dataset(X_train_trans, label=y_train)\nval_data = lgb.Dataset(X_val_trans, label=y_val, reference=train_data)\n\n# 3. Training LightGBM Model with Verbose Logging\nparams = {\n    'objective': 'regression',\n    'metric': 'rmse',\n    'boosting_type': 'gbdt',\n    'learning_rate': 0.05,\n    'num_leaves': 64,\n    'max_depth': 7,\n    'verbosity': -1\n}\n\nmodel = lgb.train(\n    params,\n    train_data,\n    valid_sets=[train_data, val_data],\n    num_boost_round=1000\n)\n\n# Evaluation\ny_pred = model.predict(X_val_trans, num_iteration=model.best_iteration)\nrmse = np.sqrt(mean_squared_error(y_val, y_pred))\nprint(f\"\\n✅ Final RMSE: {rmse:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:52:53.171165Z","iopub.execute_input":"2025-06-14T16:52:53.171525Z","iopub.status.idle":"2025-06-14T16:54:48.704295Z","shell.execute_reply.started":"2025-06-14T16:52:53.171488Z","shell.execute_reply":"2025-06-14T16:54:48.703217Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# For Validation Set\n","metadata":{}},{"cell_type":"code","source":"val_df = feature_engineering(val)\n\n# Split features and target\nX_val_final = val_df.drop(columns=[\"Lap_Time_Seconds\"])\ny_val_final = val_df[\"Lap_Time_Seconds\"]\n\nX_val_final_trans = preprocessor.fit_transform(X_val_final)\n\n# Predict using trained model\ny_val_pred = model.predict(X_val_final_trans, num_iteration=model.best_iteration)\n\n# RMSE\nval_rmse = np.sqrt(mean_squared_error(y_val_final, y_val_pred))\nprint(f\"\\n RMSE for Validation Set: {val_rmse:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:51:35.612214Z","iopub.status.idle":"2025-06-14T16:51:35.612603Z","shell.execute_reply.started":"2025-06-14T16:51:35.612429Z","shell.execute_reply":"2025-06-14T16:51:35.612449Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Final for test","metadata":{}},{"cell_type":"code","source":"test_df = pd.read_csv(\"/kaggle/input/burnout-datathon-ieeecsmuj/test.csv\")\n\n# 2. Unique ID for submission later \nsubmission_ids = test_df[\"Unique ID\"]\n\ntest_df = feature_engineering(test_df)\nX_test = test_df.copy()\n\nX_test_trans = preprocessor.transform(X_test)\ny_test_pred = model.predict(X_test_trans, num_iteration=model.best_iteration)\n\n# 7. Creating submission DataFrame\nsubmission_df = pd.DataFrame({\n    \"Unique ID\": submission_ids,\n    \"Lap_Time_Seconds\": y_test_pred\n})\n\n# 8. Saving to CSV\nsubmission_df.to_csv(\"submission.csv\", index=False)\nprint(\"✅ submission.csv file created successfully!\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:51:35.613965Z","iopub.status.idle":"2025-06-14T16:51:35.614322Z","shell.execute_reply.started":"2025-06-14T16:51:35.614174Z","shell.execute_reply":"2025-06-14T16:51:35.614195Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}