{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":82253,"databundleVersionId":8965849,"sourceType":"competition"}],"dockerImageVersionId":30733,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport warnings\nimport os\nfrom sklearn.model_selection import train_test_split\nimport xgboost as xgb\nimport lightgbm as lgb\nimport catboost as cat\nfrom sklearn.metrics import mean_squared_error, r2_score\nfrom sklearn.tree import DecisionTreeRegressor\nfrom sklearn.ensemble import RandomForestRegressor\nwarnings.filterwarnings(\"ignore\", category=RuntimeWarning)\npd.set_option('display.max_columns', None)\npd.options.mode.copy_on_write = True \npd.set_option('future.no_silent_downcasting', True)\n\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-06-29T04:32:27.751212Z","iopub.execute_input":"2024-06-29T04:32:27.751572Z","iopub.status.idle":"2024-06-29T04:32:27.762265Z","shell.execute_reply.started":"2024-06-29T04:32:27.751546Z","shell.execute_reply":"2024-06-29T04:32:27.761291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# reading the data\ntrain_data = pd.read_csv('/kaggle/input/f1nalyze-datathon-ieeecsmuj/train.csv')\ntest_data = pd.read_csv('/kaggle/input/f1nalyze-datathon-ieeecsmuj/test.csv')\nval_data = pd.read_csv('/kaggle/input/f1nalyze-datathon-ieeecsmuj/validation.csv')","metadata":{"execution":{"iopub.status.busy":"2024-06-29T03:50:51.728753Z","iopub.execute_input":"2024-06-29T03:50:51.729113Z","iopub.status.idle":"2024-06-29T03:51:16.678900Z","shell.execute_reply.started":"2024-06-29T03:50:51.729085Z","shell.execute_reply":"2024-06-29T03:51:16.677762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"result_driver_standing = test_data['result_driver_standing']","metadata":{"execution":{"iopub.status.busy":"2024-06-29T03:51:16.680910Z","iopub.execute_input":"2024-06-29T03:51:16.681256Z","iopub.status.idle":"2024-06-29T03:51:16.686324Z","shell.execute_reply.started":"2024-06-29T03:51:16.681228Z","shell.execute_reply":"2024-06-29T03:51:16.685333Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Helper functions\ndef replaceWithNaN(df):\n    df.replace('\\\\N', np.nan, inplace=True)\n    return df\n\ndef fillNaN(df):\n    for col in ['max_speed', 'fastestLap', 'rank']:\n        df[col] = df[col].apply(lambda x: evaluate(x))\n        df[col] = df.groupby('driverId')[col].transform(lambda x: x.fillna(x.median()))\n        df[col] = df.groupby('constructorId')[col].transform(lambda x: x.fillna(x.median()))\n        df[col] = df[col].fillna(df[col].median())\n    for col in ['fastestLapTime']:\n        df[col] = df[col].apply(lambda x: evaluate_lap(x))\n        df[col] = df.groupby('driverId')[col].transform(lambda x: x.fillna(x.median()))\n        df[col] = df.groupby('constructorId')[col].transform(lambda x: x.fillna(x.median()))\n        df[col] = df[col].fillna(df[col].median())\n    return df\n\ndef evaluate(x):\n    try:\n        if pd.notna(x):\n            if type(x) == str:\n                return eval(x)\n            else:\n                return x\n        else:\n            return x\n    except:\n        return x\n\ndef evaluate_lap(x):\n    try:\n        if pd.notna(x):\n            if type(x) == str:\n                l = x.split(':')\n                return int(l[0])*60 + eval(l[1])\n            else:\n                return x\n        else:\n            return x\n    except:\n        return x","metadata":{"execution":{"iopub.status.busy":"2024-06-29T03:51:16.687821Z","iopub.execute_input":"2024-06-29T03:51:16.688527Z","iopub.status.idle":"2024-06-29T03:51:16.701281Z","shell.execute_reply.started":"2024-06-29T03:51:16.688492Z","shell.execute_reply":"2024-06-29T03:51:16.700462Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def addNewFeaturesX(df):\n    \n    df['is_pole'] = (df['positionText_x'] == 'R').astype(int)\n    df['is_front_row'] = np.where(np.isin(df['positionText_x'].values, ['1', '2']), 1, 0)\n    df['is_midfield'] = np.where(np.isin(df['positionText_x'].values, [str(x) for x in range(3,11)]), 1, 0)\n    df['is_backmarkers'] = np.where(np.isin(df['positionText_x'].values, [str(x) for x in range(11,34)]), 1, 0)\n    df.drop(['positionText_x'], axis=1, inplace=True)\n    \n    df['dob'] = pd.to_datetime(df['dob'], format='%Y-%m-%d')\n    df['date'] = pd.to_datetime(df['date'], format='%Y-%m-%d')\n    df['age'] = (df['date'] - df['dob']).apply((lambda x: (x//30).days))\n    df.drop(['dob','date'], axis=1, inplace=True)\n    \n    df['qualifying_position_change'] = df['grid'] - df['positionOrder']\n    \n    df['driver_experience'] = df.groupby('driverId').cumcount()\n    df['constructor_experience'] = df.groupby('constructorId').cumcount()\n    \n    df['driver_wins_percentage'] = df.groupby('driverId')['wins'].cumsum() / (df['driver_experience']+1)\n    df['constructor_wins_percentage'] = df.groupby('constructorId')['wins'].cumsum() / (df['constructor_experience']+1)\n    \n    df['season_points'] = df.groupby(['year', 'driverId'])['points_y'].cumsum()\n    df['season_wins'] = df.groupby(['year', 'driverId'])['wins'].cumsum()\n    df['constructor_season_points'] = df.groupby(['year', 'constructorId'])['points'].cumsum()\n    df['constructor_season_wins'] = df.groupby(['year', 'constructorId'])['wins'].cumsum()\n    \n    df['track_experience'] = df.groupby(['circuitId', 'driverId']).cumcount()\n    df['constructor_track_experience'] = df.groupby(['circuitId', 'constructorId']).cumcount()\n    \n    df['avg_points_last_5_races'] = df.groupby('driverId')['points'].rolling(5, min_periods=1).mean().reset_index(level=0, drop=True)\n    df['constructor_avg_points_last_5_races'] = df.groupby('constructorId')['points'].rolling(5, min_periods=1).mean().reset_index(level=0, drop=True)\n    \n    df['driver_grid_experience'] = df['driver_experience'] * df['grid']\n    df['constructor_track_experience'] = df['constructor_experience'] * df['track_experience']\n    \n    df['relative_fastest_lap'] = df['fastestLapTime'] - df.groupby('racerId')['fastestLapTime'].transform('min')\n    df['normalized_fastest_lap_time'] = df['fastestLapTime'] / df.groupby('racerId')['fastestLapTime'].transform('min')\n    df['speed_performance_indicator'] = df['max_speed'] - df.groupby('racerId')['max_speed'].transform('max')\n\n#     df['driver_fastest_lap_consistency'] = df.groupby('driverId')['fastestLapTime'].transform('std')\n#     df['constructor_speed_consistency'] = df.groupby('constructorId')['max_speed'].transform('std')\n\n    df['historical_fastest_lap_time'] = df.groupby(['year', 'driverId'])['fastestLapTime'].transform('mean')\n    df['historical_max_speed'] = df.groupby(['year', 'constructorId'])['max_speed'].transform('mean')\n\n    df['company_wins'] = df.groupby('company')['wins'].transform('sum')\n    df['company_points_total'] = df.groupby('company')['points'].transform('sum')\n\n    df['finish_rate'] = df['status'].apply(lambda x: 1 if x == 'Finished' else 0)\n    df['finish_rate'] = df.groupby('driverId')['finish_rate'].transform('mean')\n    \n    df['driver_nationality_wins'] = df.groupby('nationality')['wins'].transform('sum')\n    df['constructor_nationality_wins'] = df.groupby('nationality_y')['wins'].transform('sum')\n\n    df['grand_prix_win_count'] = df.groupby('grand_prix')['wins'].transform('sum')\n    df['grand_prix_points_total'] = df.groupby('grand_prix')['points'].transform('sum')\n    df.drop(['company', 'nationality', 'nationality_y', 'status', 'grand_prix'], axis=1, inplace=True)\n    return df\n\ndef addNewFeaturesY(df):\n   \n    df['is_pole'] = (df['positionText_x'] == 'R').astype(int)\n    df['is_front_row'] = np.where(np.isin(df['positionText_x'].values, ['1', '2']), 1, 0)\n    df['is_midfield'] = np.where(np.isin(df['positionText_x'].values, [str(x) for x in range(3,11)]), 1, 0)\n    df['is_backmarkers'] = np.where(np.isin(df['positionText_x'].values, [str(x) for x in range(11,34)]), 1, 0)\n    df.drop(['positionText_x'], axis=1, inplace=True)\n    \n    df['dob'] = pd.to_datetime(df['dob'], format='%d/%m/%y')\n    df['date'] = pd.to_datetime(df['date'], format='%d/%m/%y')\n    df['age'] = (df['date'] - df['dob']).apply((lambda x: (x//30).days))\n    df.drop(['dob','date'], axis=1, inplace=True)\n    \n    df['qualifying_position_change'] = df['grid'] - df['positionOrder']\n    \n    df['driver_experience'] = df.groupby('driverId').cumcount()\n    df['constructor_experience'] = df.groupby('constructorId').cumcount()\n    \n    df['driver_wins_percentage'] = df.groupby('driverId')['wins'].cumsum() / (df['driver_experience']+1)\n    df['constructor_wins_percentage'] = df.groupby('constructorId')['wins'].cumsum() / (df['constructor_experience']+1)\n    \n    df['season_points'] = df.groupby(['year', 'driverId'])['points_y'].cumsum()\n    df['season_wins'] = df.groupby(['year', 'driverId'])['wins'].cumsum()\n    df['constructor_season_points'] = df.groupby(['year', 'constructorId'])['points'].cumsum()\n    df['constructor_season_wins'] = df.groupby(['year', 'constructorId'])['wins'].cumsum()\n    \n    df['track_experience'] = df.groupby(['circuitId', 'driverId']).cumcount()\n    df['constructor_track_experience'] = df.groupby(['circuitId', 'constructorId']).cumcount()\n    \n    df['avg_points_last_5_races'] = df.groupby('driverId')['points'].rolling(5, min_periods=1).mean().reset_index(level=0, drop=True)\n    df['constructor_avg_points_last_5_races'] = df.groupby('constructorId')['points'].rolling(5, min_periods=1).mean().reset_index(level=0, drop=True)\n    \n    df['driver_grid_experience'] = df['driver_experience'] * df['grid']\n    df['constructor_track_experience'] = df['constructor_experience'] * df['track_experience']\n    \n    df['relative_fastest_lap'] = df['fastestLapTime'] - df.groupby('racerId')['fastestLapTime'].transform('min')\n    df['normalized_fastest_lap_time'] = df['fastestLapTime'] / df.groupby('racerId')['fastestLapTime'].transform('min')\n    df['speed_performance_indicator'] = df['max_speed'] - df.groupby('racerId')['max_speed'].transform('max')\n\n#     df['driver_fastest_lap_consistency'] = df.groupby('driverId')['fastestLapTime'].transform('std')\n#     df['constructor_speed_consistency'] = df.groupby('constructorId')['max_speed'].transform('std')\n\n    df['historical_fastest_lap_time'] = df.groupby(['year', 'driverId'])['fastestLapTime'].transform('mean')\n    df['historical_max_speed'] = df.groupby(['year', 'constructorId'])['max_speed'].transform('mean')\n\n    df['company_wins'] = df.groupby('company')['wins'].transform('sum')\n    df['company_points_total'] = df.groupby('company')['points'].transform('sum')\n\n    df['finish_rate'] = df['status'].apply(lambda x: 1 if x == 'Finished' else 0)\n    df['finish_rate'] = df.groupby('driverId')['finish_rate'].transform('mean')\n\n    df['driver_nationality_wins'] = df.groupby('nationality')['wins'].transform('sum')\n    df['constructor_nationality_wins'] = df.groupby('nationality_y')['wins'].transform('sum')\n\n    df['grand_prix_win_count'] = df.groupby('grand_prix')['wins'].transform('sum')\n    df['grand_prix_points_total'] = df.groupby('grand_prix')['points'].transform('sum')\n    df.drop(['company', 'nationality', 'nationality_y', 'status', 'grand_prix'], axis=1, inplace=True)\n\n    return df","metadata":{"execution":{"iopub.status.busy":"2024-06-29T03:51:16.703225Z","iopub.execute_input":"2024-06-29T03:51:16.703494Z","iopub.status.idle":"2024-06-29T03:51:16.743949Z","shell.execute_reply.started":"2024-06-29T03:51:16.703472Z","shell.execute_reply":"2024-06-29T03:51:16.742993Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# replacing /N with nan values\ntrain_data = replaceWithNaN(train_data)\ntest_data = replaceWithNaN(test_data)\nval_data = replaceWithNaN(val_data)","metadata":{"execution":{"iopub.status.busy":"2024-06-29T03:51:16.745204Z","iopub.execute_input":"2024-06-29T03:51:16.745495Z","iopub.status.idle":"2024-06-29T03:51:35.337070Z","shell.execute_reply.started":"2024-06-29T03:51:16.745466Z","shell.execute_reply":"2024-06-29T03:51:35.336022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# filling nan values with median\ntrain_data = fillNaN(train_data)\ntest_data = fillNaN(test_data)\nval_data = fillNaN(val_data)","metadata":{"execution":{"iopub.status.busy":"2024-06-29T03:51:35.338405Z","iopub.execute_input":"2024-06-29T03:51:35.338831Z","iopub.status.idle":"2024-06-29T03:52:30.188324Z","shell.execute_reply.started":"2024-06-29T03:51:35.338771Z","shell.execute_reply":"2024-06-29T03:52:30.187203Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Adding new features\ntrain_data = addNewFeaturesX(train_data)\nval_data = addNewFeaturesX(val_data)\ntest_data = addNewFeaturesY(test_data)","metadata":{"execution":{"iopub.status.busy":"2024-06-29T03:52:30.189751Z","iopub.execute_input":"2024-06-29T03:52:30.190141Z","iopub.status.idle":"2024-06-29T03:53:05.969904Z","shell.execute_reply.started":"2024-06-29T03:52:30.190106Z","shell.execute_reply":"2024-06-29T03:53:05.969095Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"colsX = [\n        'grid', 'positionOrder', 'points','points_y', 'laps',\n        'fastestLap', 'rank', 'fastestLapTime', 'max_speed', 'round', 'wins',\n        'is_pole', 'is_front_row', 'is_midfield', 'is_backmarkers', 'age',\n        'qualifying_position_change', 'driver_experience', 'constructor_experience',\n        'driver_wins_percentage', 'constructor_wins_percentage', 'season_points', 'season_wins',\n        'constructor_season_points', 'constructor_season_wins', 'track_experience',\n        'constructor_track_experience', 'avg_points_last_5_races', 'constructor_avg_points_last_5_races',\n        'driver_grid_experience', 'relative_fastest_lap', 'normalized_fastest_lap_time',\n        'speed_performance_indicator',\n        'historical_fastest_lap_time', 'historical_max_speed','company_wins', 'company_points_total',\n        'finish_rate', 'driver_nationality_wins', 'constructor_nationality_wins',\n        'grand_prix_win_count', 'grand_prix_points_total','position'\n        ]\n\ncolsY = [\n        'grid', 'positionOrder', 'points','points_y', 'laps',\n        'fastestLap', 'rank', 'fastestLapTime', 'max_speed', 'round', 'wins',\n        'is_pole', 'is_front_row', 'is_midfield', 'is_backmarkers', 'age',\n        'qualifying_position_change', 'driver_experience', 'constructor_experience',\n        'driver_wins_percentage', 'constructor_wins_percentage', 'season_points', 'season_wins',\n        'constructor_season_points', 'constructor_season_wins', 'track_experience',\n        'constructor_track_experience', 'avg_points_last_5_races', 'constructor_avg_points_last_5_races',\n        'driver_grid_experience', 'relative_fastest_lap', 'normalized_fastest_lap_time',\n        'speed_performance_indicator',\n        'historical_fastest_lap_time', 'historical_max_speed','company_wins', 'company_points_total',\n        'finish_rate', 'driver_nationality_wins', 'constructor_nationality_wins',\n        'grand_prix_win_count', 'grand_prix_points_total'\n        ]\n\ntrain_data = train_data.loc[:,colsX]\nval_data = val_data.loc[:,colsX]\ntest_data = test_data.loc[:,colsY]","metadata":{"execution":{"iopub.status.busy":"2024-06-29T03:53:05.971038Z","iopub.execute_input":"2024-06-29T03:53:05.971335Z","iopub.status.idle":"2024-06-29T03:53:06.241306Z","shell.execute_reply.started":"2024-06-29T03:53:05.971310Z","shell.execute_reply":"2024-06-29T03:53:06.240291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_data.shape[0], val_data.shape[0], test_data.shape[0]","metadata":{"execution":{"iopub.status.busy":"2024-06-29T03:53:06.242657Z","iopub.execute_input":"2024-06-29T03:53:06.242976Z","iopub.status.idle":"2024-06-29T03:53:06.257369Z","shell.execute_reply.started":"2024-06-29T03:53:06.242951Z","shell.execute_reply":"2024-06-29T03:53:06.256411Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Testing","metadata":{}},{"cell_type":"code","source":"X_train, X_val, y_train, y_val = train_test_split(train_data[colsY], train_data['position'], test_size = 0.13, random_state= 0)\nX_test, y_test = val_data[colsY], val_data['position']\neval_set = [(X_val, y_val)]","metadata":{"execution":{"iopub.status.busy":"2024-06-29T06:08:58.330319Z","iopub.execute_input":"2024-06-29T06:08:58.330861Z","iopub.status.idle":"2024-06-29T06:08:59.845854Z","shell.execute_reply.started":"2024-06-29T06:08:58.330826Z","shell.execute_reply":"2024-06-29T06:08:59.844726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"reg_cat = cat.CatBoostRegressor(random_state = 0, iterations=  1000, depth=7, learning_rate = 0.01, early_stopping_rounds=50,\n                               loss_function = 'RMSE', verbose = 0)\nreg_cat.fit(X_train, y_train, eval_set=eval_set)\nnp.sqrt(mean_squared_error(y_test,reg_cat.predict(X_test))), np.sqrt(mean_squared_error(y_val,reg_cat.predict(X_val))),  np.sqrt(mean_squared_error(y_train,reg_cat.predict(X_train)))","metadata":{"execution":{"iopub.status.busy":"2024-06-29T06:13:37.951810Z","iopub.execute_input":"2024-06-29T06:13:37.952658Z","iopub.status.idle":"2024-06-29T06:20:05.866665Z","shell.execute_reply.started":"2024-06-29T06:13:37.952617Z","shell.execute_reply":"2024-06-29T06:20:05.865584Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Main","metadata":{}},{"cell_type":"code","source":"X_train, X_val, X_test, y_train, y_val = train_data[colsY], val_data[colsY], test_data[colsY], train_data['position'], val_data['position']\neval_set = [(X_val, y_val)]","metadata":{"execution":{"iopub.status.busy":"2024-06-29T06:20:50.021539Z","iopub.execute_input":"2024-06-29T06:20:50.022327Z","iopub.status.idle":"2024-06-29T06:20:50.031464Z","shell.execute_reply.started":"2024-06-29T06:20:50.022292Z","shell.execute_reply":"2024-06-29T06:20:50.030466Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"reg_cat = cat.CatBoostRegressor(random_state = 0, iterations=  1000, depth=7, learning_rate = 0.01, early_stopping_rounds=50,\n                               loss_function = 'RMSE', verbose = 0)\nreg_cat.fit(X_train, y_train, eval_set=eval_set)","metadata":{"execution":{"iopub.status.busy":"2024-06-29T06:20:50.577771Z","iopub.execute_input":"2024-06-29T06:20:50.578470Z","iopub.status.idle":"2024-06-29T06:27:53.439529Z","shell.execute_reply.started":"2024-06-29T06:20:50.578436Z","shell.execute_reply":"2024-06-29T06:27:53.438511Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"y_pred = reg_cat.predict(X_test)","metadata":{"execution":{"iopub.status.busy":"2024-06-29T06:27:53.441240Z","iopub.execute_input":"2024-06-29T06:27:53.441593Z","iopub.status.idle":"2024-06-29T06:27:53.667889Z","shell.execute_reply.started":"2024-06-29T06:27:53.441563Z","shell.execute_reply":"2024-06-29T06:27:53.666837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = pd.DataFrame(columns = ['position', 'result_driver_standing'])\nsub['result_driver_standing'] = result_driver_standing\nsub['position'] = y_pred","metadata":{"execution":{"iopub.status.busy":"2024-06-29T06:27:53.669928Z","iopub.execute_input":"2024-06-29T06:27:53.670669Z","iopub.status.idle":"2024-06-29T06:27:53.692096Z","shell.execute_reply.started":"2024-06-29T06:27:53.670632Z","shell.execute_reply":"2024-06-29T06:27:53.691144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub.to_csv('//kaggle//working//submission.csv', index= False)","metadata":{"execution":{"iopub.status.busy":"2024-06-29T06:27:53.693739Z","iopub.execute_input":"2024-06-29T06:27:53.694022Z","iopub.status.idle":"2024-06-29T06:27:54.726739Z","shell.execute_reply.started":"2024-06-29T06:27:53.693998Z","shell.execute_reply":"2024-06-29T06:27:54.725885Z"},"trusted":true},"execution_count":null,"outputs":[]}]}