{"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:27:00.766082Z","iopub.execute_input":"2025-06-14T16:27:00.766459Z","iopub.status.idle":"2025-06-14T16:27:01.213848Z","shell.execute_reply.started":"2025-06-14T16:27:00.766433Z","shell.execute_reply":"2025-06-14T16:27:01.212649Z"}},"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\n\nfrom sklearn.model_selection import StratifiedKFold\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.impute import SimpleImputer\nfrom sklearn.ensemble import RandomForestClassifier  # or RandomForestRegressor if regression\nfrom sklearn.metrics import accuracy_score  # or mean_squared_error, etc.\n\n# Load datasets\ntrain = pd.read_csv(\"/kaggle/input/burnout-datathon-ieeecsmuj/train.csv\")\ntest = pd.read_csv(\"/kaggle/input/burnout-datathon-ieeecsmuj/test.csv\")\nsample_submission = pd.read_csv(\"/kaggle/input/burnout-datathon-ieeecsmuj/sample_submission.csv\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:27:01.215575Z","iopub.execute_input":"2025-06-14T16:27:01.215977Z","iopub.status.idle":"2025-06-14T16:27:21.147881Z","shell.execute_reply.started":"2025-06-14T16:27:01.215953Z","shell.execute_reply":"2025-06-14T16:27:21.146914Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"Train shape:\", train.shape)\nprint(\"Test shape:\", test.shape)\n\nprint(\"\\nTrain Info:\")\nprint(train.info())\n\nprint(\"\\nMissing values:\\n\", train.isnull().sum())\n\nprint(\"\\nSummary statistics:\")\nprint(train.describe())\n\n# Plotting target distribution (for classification)\n#sns.countplot(x='Lap_Time_Seconds', data=train)\n#plt.title(\"Target Distribution\")\n#plt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:27:21.148817Z","iopub.execute_input":"2025-06-14T16:27:21.149124Z","iopub.status.idle":"2025-06-14T16:27:24.960214Z","shell.execute_reply.started":"2025-06-14T16:27:21.149098Z","shell.execute_reply":"2025-06-14T16:27:24.959092Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Loading the CSV into a DataFrame\ndf = pd.read_csv('/kaggle/input/burnout-datathon-ieeecsmuj/train.csv')\n\n# Create a new column for Success Rate (with points per start)\ndf['Success_Rate'] = df['with_points'] / df['starts']\n\n# Create a new column for Average Starts per Year\ndf['Average_Starts_Per_Year'] = df['starts'] / df['years_active']\n\n\nprint(\"DataFrame with new metrics:\")\nprint(df.head())  \n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:27:24.962172Z","iopub.execute_input":"2025-06-14T16:27:24.962461Z","iopub.status.idle":"2025-06-14T16:27:38.148422Z","shell.execute_reply.started":"2025-06-14T16:27:24.962436Z","shell.execute_reply":"2025-06-14T16:27:38.147359Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df['Composite_Performance'] = (\n    df['points'] + \n    df['Championship_Points'] - \n    df['position'] - \n    df['Championship_Position']\n)\n\n# View the cleaned-up DataFrame\nprint(\"Cleaned-up DataFrame:\")\nprint(df.head())\n\n# Confirm that the composite score is present\nprint(\"\\nColumns in cleaned-up DataFrame:\")\nprint(df.columns)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:27:38.149331Z","iopub.execute_input":"2025-06-14T16:27:38.149601Z","iopub.status.idle":"2025-06-14T16:27:38.180086Z","shell.execute_reply.started":"2025-06-14T16:27:38.149579Z","shell.execute_reply":"2025-06-14T16:27:38.178870Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"weather_score = {\"Sunny\": 1, \"Clear\": 1, \"Partly cloudy\": 2, \"Cloudy\": 2, \"Raining\": 3, \"Overcast\": 2}\ntrack_score = {\"Dry\": 1, \"Wet\": 2}\ntire_score = {\"Soft\": 3, \"Medium\": 2, \"Hard\": 1}\n\n\ndf[\"Track_Surface_Index\"] = df[\"track\"].map(track_score) * df[\"Track_Condition\"].map(track_score)\n\ndf[\"Tire_Grip_Score\"] = df[\"Tire_Compound_Front\"].map(tire_score) + df[\"Tire_Compound_Rear\"].map(tire_score)\n\n\ndf[[\"weather\", \"track\", \"Track_Condition\", \"Tire_Compound_Front\", \"Tire_Compound_Rear\", \"Track_Surface_Index\", \"Tire_Grip_Score\"]].head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:27:38.181575Z","iopub.execute_input":"2025-06-14T16:27:38.181900Z","iopub.status.idle":"2025-06-14T16:27:38.773097Z","shell.execute_reply.started":"2025-06-14T16:27:38.181874Z","shell.execute_reply":"2025-06-14T16:27:38.772146Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:27:38.774286Z","iopub.execute_input":"2025-06-14T16:27:38.774637Z","iopub.status.idle":"2025-06-14T16:27:38.797380Z","shell.execute_reply.started":"2025-06-14T16:27:38.774603Z","shell.execute_reply":"2025-06-14T16:27:38.796446Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"penalty_score = {\n    \"DNS\": 0,\n    \"DNF\": 0,\n    \"+3s\": 3,\n    \"+5s\": 5,\n    \"Ride Through\": 22,\n    None: 0, \n}\n\ndf[\"Penalty_Severity\"] = df[\"Penalty\"].map(penalty_score).fillna(0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:27:38.798389Z","iopub.execute_input":"2025-06-14T16:27:38.798666Z","iopub.status.idle":"2025-06-14T16:27:38.954110Z","shell.execute_reply.started":"2025-06-14T16:27:38.798643Z","shell.execute_reply":"2025-06-14T16:27:38.952924Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:27:38.955149Z","iopub.execute_input":"2025-06-14T16:27:38.955476Z","iopub.status.idle":"2025-06-14T16:27:38.976850Z","shell.execute_reply.started":"2025-06-14T16:27:38.955447Z","shell.execute_reply":"2025-06-14T16:27:38.975971Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**DROPPING COLUMNS**","metadata":{}},{"cell_type":"code","source":"df.drop(['points', 'Championship_Points', 'position', 'Championship_Position'], axis=1, inplace=True)\ndf.drop(['with_points', 'finishes', 'years_active'], axis=1, inplace=True)\ndf.drop([\"track\", \"Track_Condition\", \"Tire_Compound_Front\", \"Tire_Compound_Rear\"], axis=1)\n\n# list of columns we don't want\ndrop_columns = [\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\n# Perform the drop\ndf.drop(drop_columns, axis=1, inplace = True)\ndf.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:27:38.980154Z","iopub.execute_input":"2025-06-14T16:27:38.980448Z","iopub.status.idle":"2025-06-14T16:27:40.553636Z","shell.execute_reply.started":"2025-06-14T16:27:38.980426Z","shell.execute_reply":"2025-06-14T16:27:40.552852Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**EDA**","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\n# Loading the dataset\ndf = pd.read_csv('final_cleaned_dataset3.csv')\n\n# 1️⃣ General Data Overview\nprint(\"Dataset Shape (rows, columns):\", df.shape)\nprint(\"\\nColumn Data Types:\")\nprint(df.dtypes)\nprint(\"\\nCount of missing values per column:\")\nprint(df.isnull().sum())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:27:40.554420Z","iopub.execute_input":"2025-06-14T16:27:40.554674Z","iopub.status.idle":"2025-06-14T16:27:50.421166Z","shell.execute_reply.started":"2025-06-14T16:27:40.554654Z","shell.execute_reply":"2025-06-14T16:27:50.420153Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 2️⃣ Univariate Analysis\n# Box Plot, Histogram, Pie Chart with Annotations\nnumerical_df = df.select_dtypes(['number'])\n\nfor col in numerical_df.columns:\n    mean_val = numerical_df[col].mean()\n    max_val = numerical_df[col].max()\n    min_val = numerical_df[col].min()\n\n    # Box Plot with Annotations\n    box = numerical_df.boxplot(column=col)\n    box.annotate(f'mean: {mean_val:.2f}', (1, mean_val), color='red')\n    box.annotate(f'max: {max_val:.2f}', (1, max_val), color='green')\n    box.annotate(f'min: {min_val:.2f}', (1, min_val), color='blue')\n    box.set_title(f'Box Plot of {col}')\n\n    plt.show()\n\n    # Histogram with Mean\n    numerical_df[col].hist(bins=20)\n    plt.axvline(mean_val, color='red', label='Mean')\n    plt.legend()\n    plt.title(f'Distribution of {col}')\n    plt.xlabel(col)\n    plt.ylabel('Frequency')\n    plt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:27:50.422364Z","iopub.execute_input":"2025-06-14T16:27:50.423507Z","iopub.status.idle":"2025-06-14T16:28:54.129959Z","shell.execute_reply.started":"2025-06-14T16:27:50.423477Z","shell.execute_reply":"2025-06-14T16:28:54.128900Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 3️⃣ Bivariate Analysis\n# Pair Plot for Numerical Columns\nif len(numerical_df.columns) > 5:\n    sample_columns = numerical_df.columns[:5]\nelse:\n    sample_columns = numerical_df.columns\n\nsns.pairplot(df[sample_columns]) \nplt.suptitle('Pair Plot of Numerical Columns')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:28:54.131299Z","iopub.execute_input":"2025-06-14T16:28:54.131598Z","iopub.status.idle":"2025-06-14T16:30:22.771258Z","shell.execute_reply.started":"2025-06-14T16:28:54.131573Z","shell.execute_reply":"2025-06-14T16:30:22.770139Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Calculate correlation matrix\ncorrelation_matrix = df.select_dtypes(['number']).corr()\n\n# Plotting the Heatmap with cleaned-up annotations\nplt.figure(figsize=(12, 10))\nax = sns.heatmap(\n    correlation_matrix,\n    annot=True,\n    fmt='.2f',\n    cmap='coolwarm',\n    annot_kws={\"size\": 8},\n    square=True\n)\n\nax.set_title('Correlation Heatmap', fontsize=16)\nax.set_xticklabels(ax.get_xticklabels(), rotation=90, fontsize=10)\nax.set_yticklabels(ax.get_yticklabels(), rotation=0, fontsize=10)\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:30:22.772930Z","iopub.execute_input":"2025-06-14T16:30:22.773309Z","iopub.status.idle":"2025-06-14T16:30:28.065311Z","shell.execute_reply.started":"2025-06-14T16:30:22.773281Z","shell.execute_reply":"2025-06-14T16:30:28.064250Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"**FEATURE ENGINEERING**","metadata":{}},{"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:56:25.689589Z","iopub.execute_input":"2025-06-14T16:56:25.689912Z","iopub.status.idle":"2025-06-14T16:56:25.695482Z","shell.execute_reply.started":"2025-06-14T16:56:25.689891Z","shell.execute_reply":"2025-06-14T16:56:25.694426Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df.dtypes","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-14T16:56:28.257242Z","iopub.execute_input":"2025-06-14T16:56:28.257619Z","iopub.status.idle":"2025-06-14T16:56:28.267392Z","shell.execute_reply.started":"2025-06-14T16:56:28.257592Z","shell.execute_reply":"2025-06-14T16:56:28.266401Z"}},"outputs":[],"execution_count":null},{"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:56:31.228014Z","iopub.execute_input":"2025-06-14T16:56:31.228982Z","iopub.status.idle":"2025-06-14T16:56:31.237431Z","shell.execute_reply.started":"2025-06-14T16:56:31.228948Z","shell.execute_reply":"2025-06-14T16:56:31.236207Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#df = feature_engineering(df)\n\nX = 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:58:18.938334Z","iopub.execute_input":"2025-06-14T16:58:18.938688Z"}},"outputs":[],"execution_count":null},{"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},"outputs":[],"execution_count":null},{"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!\")","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}