{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.0"},"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":"markdown","source":"# F1analyze","metadata":{}},{"cell_type":"markdown","source":"## To do\n- [ ] Basics\n- [ ] Read the data\n- [ ] EDA\n- [ ] Preprocessing\n- [ ] Model\n- [ ] Evaluation\n- [ ] Submission\n- [ ] age of driver?","metadata":{}},{"cell_type":"markdown","source":"## Setting up the basics","metadata":{}},{"cell_type":"markdown","source":"### Importing the libraries","metadata":{}},{"cell_type":"code","source":"# Imports\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom sklearn.experimental import enable_iterative_imputer  # noqa\nfrom sklearn.impute import SimpleImputer, IterativeImputer\nimport seaborn as sns\n\nimport re\nimport pickle\n\nfrom tqdm import tqdm\nfrom sklearn.ensemble import ExtraTreesRegressor\nfrom sklearn.linear_model import BayesianRidge\nfrom sklearn.tree import DecisionTreeRegressor\nfrom sklearn.neighbors import KNeighborsRegressor\nfrom sklearn.preprocessing import OrdinalEncoder\nfrom sklearn import preprocessing\n\nfrom sklearn.cluster import KMeans\n\nfrom sklearn.model_selection import cross_val_score\nfrom sklearn.pipeline import make_pipeline\n\nimport warnings\nwarnings.filterwarnings('ignore')\n\n%matplotlib inline","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Global variables","metadata":{}},{"cell_type":"code","source":"# Global Constants\n\nDATA_PATH = '/kaggle/input/f1nalyze-datathon-ieeecsmuj/'\nOUTPUT_PATH = '/kaggle/working/'\nPRE_PROC = '/kaggle/working/pre_proc/'\nTEST_FILE_PATH = DATA_PATH + 'test.csv'\nTRAIN_FILE_PATH = DATA_PATH + 'train.csv'\nVALIDATION_FILE_PATH = DATA_PATH + 'validation.csv'\n\n# Column Names\nRESULT_ID = 'resultId'\nRACER_ID = 'racerId'\nDRIVER_ID = 'driverId'\nNUMBER = 'number'\nGRID = 'grid'\nPOSITION_X = 'position_x'\nPOSITION_TEXT_X = 'positionText_x'\nPOSITION_ORDER = 'positionOrder'\nPOINTS = 'points'\nLAPS = 'laps'\nTIME_TAKEN_IN_MS = 'timetaken_in_millisec'\nFASTEST_LAP = 'fastestLap'\nRANK = 'rank'\nFASTEST_LAP_TIME = 'fastestLapTime'\nMAX_SPEED = 'max_speed'\nSTATUS_ID = 'statusId'\nYEAR = 'year'\nROUND = 'round'\nCIRCUIT_ID = 'circuitId'\nGRAND_PRIX = 'grand_prix'\nDATE = 'date'\nTIME_Y = 'time_y'\nURL_X = 'url_x'\n\nDRIVER_STANDINGS_ID = 'driverStandingsId'\nRACE_ID_Y = 'raceId_y'\nPOINTS_Y = 'points_y'\nPOSITION = 'position'\nPOSITION_TEXT_Y = 'positionText_y'\nWINS = 'wins'\n\n# Need to scrape\nFP1_DATE = 'fp1_date'\nFP1_TIME = 'fp1_time'\nFP2_DATE = 'fp2_date'\nFP2_TIME = 'fp2_time'\nFP3_DATE = 'fp3_date'\nFP3_TIME = 'fp3_time'\nQUALIFYING_DATE = 'quali_date'\nQUALIFYING_TIME = 'quali_time'\nSPRINT_DATE = 'sprint_date'\nSPRINT_TIME = 'sprint_time'\n\n# Driver Cols\nDRIVER_REF = 'driverRef'\nDRIVER_NUM = 'driver_num'\nDRIVER_CODE = 'driver_code'\nFORENAME = 'forename'\nSURNAME = 'surname'\nDOB = 'dob'\nNATIONALITY = 'nationality'\nURL_Y = 'url_y'\n\n# Constructor Cols\nCONSTRUCTOR_ID = 'constructorId'\nCONSTRUCTOR_REF = 'constructorRef'\nCOMPANY = 'company'\nNATIONALITY_Y = 'nationality_y'\nURL = 'url'\n\nSTATUS = 'status'\nRESULT_DRIVER_STANDING = 'result_driver_standing'\n\n# Unnecessary Columns\nTIME_X = 'time_x'\n\n# Input Data\ntrain_data = pd.read_csv(TRAIN_FILE_PATH)\ntest_data = pd.read_csv(TEST_FILE_PATH)\nvalidation_data = pd.read_csv(VALIDATION_FILE_PATH)\n\npd.set_option('display.max_columns', None)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(len(train_data))\ntrain_data.head(10)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = train_data.copy()\ntest_df = test_data.copy()\nval_df = validation_data.copy()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# replace \\N with np.nan\ndf = df.replace('\\\\N', np.nan)\ntest_df = test_df.replace('\\\\N', np.nan)\nval_df = val_df.replace('\\\\N', np.nan)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.isnull().sum()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(test_df), test_df.isnull().sum()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.nunique()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df[POSITION_X].unique(), df[POSITION_TEXT_X].unique(), df[POSITION_ORDER].unique()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# print rows with total_time as null but total time taken in milliseconds is not null\ndf[(df[TIME_X].isnull()) & (df[TIME_TAKEN_IN_MS].notnull())]","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data Cleaning","metadata":{}},{"cell_type":"code","source":"REMOVE_COLS = [FP1_DATE, FP1_TIME, FP2_DATE, FP2_TIME, FP3_DATE, FP3_TIME, QUALIFYING_DATE, QUALIFYING_TIME, SPRINT_DATE, SPRINT_TIME]\nREMOVE_COLS += [URL, URL_X, URL_Y, TIME_X, RESULT_DRIVER_STANDING]","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = df.drop(REMOVE_COLS, axis=1)\ntest_df = test_df.drop(REMOVE_COLS, axis=1)\nval_df = val_df.drop(REMOVE_COLS, axis=1)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# convert date to datetime\ndf[DATE] = pd.to_datetime(df[DATE])\ntest_df[DATE] = pd.to_datetime(test_df[DATE])\nval_df[DATE] = pd.to_datetime(val_df[DATE])\n\n# convert dob to datetime\ndf[DOB] = pd.to_datetime(df[DOB])\ntest_df[DOB] = pd.to_datetime(test_df[DOB])\nval_df[DOB] = pd.to_datetime(val_df[DOB])\n\n# # convert date to datetime\n# df[DATE] = pd.to_datetime(df[DATE]).dt.date\n# test_df[DATE] = pd.to_datetime(test_df[DATE]).dt.date\n# val_df[DATE] = pd.to_datetime(val_df[DATE]).dt.date\n\n# # convert dob to datetime\n# df[DOB] = pd.to_datetime(df[DOB]).dt.date\n# test_df[DOB] = pd.to_datetime(test_df[DOB]).dt.date\n# val_df[DOB] = pd.to_datetime(val_df[DOB]).dt.date\n\n# # convert fastest lap time to milliseconds\n# df[FASTEST_LAP_TIME] = pd.to_timedelta(df[FASTEST_LAP_TIME]).dt.total_seconds() * 1000\n# test_df[FASTEST_LAP_TIME] = pd.to_timedelta(test_df[FASTEST_LAP_TIME]).dt.total_seconds() * 1000\n# val_df[FASTEST_LAP_TIME] = pd.to_timedelta(val_df[FASTEST_LAP_TIME]).dt.total_seconds() * 1000\n\n# # convert time taken in milliseconds to int\n# df[TIME_TAKEN_IN_MS] = df[TIME_TAKEN_IN_MS].astype(int)\n# test_df[TIME_TAKEN_IN_MS] = test_df[TIME_TAKEN_IN_MS].astype(int)\n# val_df[TIME_TAKEN_IN_MS] = val_df[TIME_TAKEN_IN_MS].astype(int)\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = df.drop([POSITION_TEXT_Y], axis=1)\nval_df = val_df.drop([POSITION_TEXT_Y], axis=1)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# move position to the end\nposition = df.pop(POSITION)\ndf[POSITION] = position\n\nposition = val_df.pop(POSITION)\nval_df[POSITION] = position","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.columns","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.iloc[0]","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# convert fastest lap time to miliseconds\ndef fastest_lap_time_to_ms(x :str):\n    if pd.isnull(x):\n        return np.nan\n    x = re.split('[:.]', x)\n    return int(x[0]) * 60000 + int(x[1]) * 1000 + int(x[2])\n\ndf[FASTEST_LAP_TIME] = df[FASTEST_LAP_TIME].apply(fastest_lap_time_to_ms)\ntest_df[FASTEST_LAP_TIME] = test_df[FASTEST_LAP_TIME].apply(fastest_lap_time_to_ms)\nval_df[FASTEST_LAP_TIME] = val_df[FASTEST_LAP_TIME].apply(fastest_lap_time_to_ms)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def time_y_to_s(x :str):\n    if pd.isnull(x):\n        return np.nan\n    x = re.split('[:]', x)\n    return int(x[0]) * 3600 + int(x[1]) * 60 + int(x[2])\n\ndf[TIME_Y] = df[TIME_Y].apply(time_y_to_s)\ntest_df[TIME_Y] = test_df[TIME_Y].apply(time_y_to_s)\nval_df[TIME_Y] = val_df[TIME_Y].apply(time_y_to_s)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df[TIME_Y].unique()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"CAT_COLS  = [POSITION_TEXT_X, GRAND_PRIX, DRIVER_REF, DRIVER_CODE, FORENAME, SURNAME,\\\n                COMPANY, NATIONALITY, NATIONALITY_Y, CONSTRUCTOR_REF, STATUS]\n\ndf[CAT_COLS] = df[CAT_COLS].astype(str)\ntest_df[CAT_COLS] = test_df[CAT_COLS].astype(str)\nval_df[CAT_COLS] = val_df[CAT_COLS].astype(str)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import catboost as cb\n\n# # cat = cb.CatBoostRegressor()\n# # cat.fit(df.drop([POSITION], axis=1), df[POSITION], \n# #         eval_set=(val_df.drop([POSITION], axis=1), val_df[POSITION]), \n# #         # verbose=100, \n# #         cat_features=CAT_COLS\n#         # )\n\n# cat_file = OUTPUT_PATH + 'cat_model.pkl'\n# f = open(cat_file, 'rb')\n# cat = pickle.load(f)\n# f.close()\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# cat.score(val_df.drop([POSITION], axis=1), val_df[POSITION])","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# cat.score(df.drop([POSITION], axis=1), df[POSITION])","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# predictions = cat.predict(test_df)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# submission = pd.DataFrame(predictions)\n# submission.columns = [POSITION]\n# submission = pd.concat([submission, test_data[RESULT_DRIVER_STANDING]], axis=1)\n\n# submission.to_csv(OUTPUT_PATH + 'submission.csv', index=False)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# cat.save_model(OUTPUT_PATH + 'cat_model')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# feature importance plot\n# plt.figure(figsize=(20, 10))\n# plt.bar(df.drop([POSITION], axis=1).columns, cat.feature_importances_)\n# plt.xticks(rotation=90)\n# plt.show()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# df.dtypes","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"OBJECT_COLS = [NUMBER, POSITION_X, POSITION_TEXT_X, TIME_TAKEN_IN_MS, FASTEST_LAP, RANK, MAX_SPEED, GRAND_PRIX, DRIVER_REF, DRIVER_NUM, DRIVER_CODE, FORENAME, SURNAME, NATIONALITY, CONSTRUCTOR_REF, COMPANY, NATIONALITY_Y, STATUS]\nDATE_COLS = [DATE, DOB]","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in OBJECT_COLS:\n    try:\n        df[i] = df[i].astype(float)\n        test_df[i] = test_df[i].astype(float)\n        val_df[i] = val_df[i].astype(float)\n    except:\n        df[i] = df[i].astype('category')\n        test_df[i] = test_df[i].astype('category')\n        val_df[i] = val_df[i].astype('category')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in DATE_COLS:\n    try:\n        df[i] = df[i].astype(float)\n        test_df[i] = test_df[i].astype(float)\n        val_df[i] = val_df[i].astype(float)\n    except:\n        df[i] = df[i].astype('category')\n        test_df[i] = test_df[i].astype('category')\n        val_df[i] = val_df[i].astype('category')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.dtypes","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# save to csv\ndf.to_csv(PRE_PROC + 'train_proc.csv', index=False)\ntest_df.to_csv(PRE_PROC + 'test_proc.csv', index=False)\nval_df.to_csv(PRE_PROC + 'val_proc.csv', index=False)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import OrdinalEncoder, LabelEncoder\n\nle = OrdinalEncoder(handle_unknown='use_encoded_value', unknown_value=-1)\nles = {}","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv('train.csv')\ntest_df = pd.read_csv('test.csv')\nval_df = pd.read_csv('val.csv')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"weather = pd.read_csv(DATA_PATH + 'weather.csv')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# create a dictionary of url_x to weather\nurl_x_to_weather = {}\nfor i in range(len(weather)):\n    url_x_to_weather[weather.iloc[i][URL].strip()] = weather.iloc[i].str.strip()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_bak = df.copy()\ntest_df_bak = test_df.copy()\nval_df_bak = val_df.copy()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# invoke garbage collector\nimport gc\n\ngc.collect()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = df_bak.copy()\ntest_df = test_df_bak.copy()\nval_df = val_df_bak.copy()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"WEATHER = 'weather'\n\ndf[WEATHER] = train_data[URL_X].apply(lambda x: url_x_to_weather[x][WEATHER])\ntest_df[WEATHER] = test_data[URL_X].apply(lambda x: url_x_to_weather[x][WEATHER])\nval_df[WEATHER] = validation_data[URL_X].apply(lambda x: url_x_to_weather[x][WEATHER])","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"RAINY = 'rainy'\n\ndf[RAINY] = df[WEATHER].apply(lambda x: np.nan if pd.isnull(x) else 1 if 'rain' in x.lower() or 'shower' in x.lower() or 'drizzle' in x.lower() else 0)\ntest_df[RAINY] = test_df[WEATHER].apply(lambda x: np.nan if pd.isnull(x) else 1 if 'rain' in x.lower() or 'shower' in x.lower() or 'drizzle' in x.lower() else 0)\nval_df[RAINY] = val_df[WEATHER].apply(lambda x: np.nan if pd.isnull(x) else 1 if 'rain' in x.lower() or 'shower' in x.lower() or 'drizzle' in x.lower() else 0)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # save the data\n# df.to_csv('train.csv', index=False)\n# test_df.to_csv('test.csv', index=False)\n# val_df.to_csv('val.csv', index=False)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# df[WEATHER].unique()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# def clean_weather(x: str):\n#     if x is np.nan:\n#         return x\n#     x = x.lower().strip()\n#     x = x.replace('and', ',')\n#     x = re.sub(r'\\s+', '', x)\n\n#     if 'rain' in x or 'drizzly' in x or 'showers' in x:\n#         return 'rainy'\n#     if 'cloud' in x:\n#         return 'cloudy'\n#     if 'storm' in x:\n#         return 'stormy'\n#     if 'fog' in x:\n#         return 'foggy'\n#     if 'thunder' in x:\n#         return 'thunderstorm'\n#     if 'hail' in x:\n#         return 'hailstorm'\n#     if 'overcast' in x:\n#         return 'overcast'\n#     if 'sunny' in x:\n#         return 'sunny'\n#     if 'clear' in x:\n#         return 'clear'\n#     if 'dry' in x:\n#         return 'dry'\n#     return 'unknown'","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# df[WEATHER] = df[WEATHER].apply(clean_weather)\n# test_df[WEATHER] = test_df[WEATHER].apply(clean_weather)\n# val_df[WEATHER] = val_df[WEATHER].apply(clean_weather)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# AGE = 'age'\n\n# def extract_age(x):\n#     return (pd.to_datetime(x[DATE])-pd.to_datetime(x[DOB])).dt.days//365\n\n# df[AGE] = extract_age(df)\n# test_df[AGE] = extract_age(test_df)\n# val_df[AGE] = extract_age(val_df)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test = test_df.copy()\ndf_val = val_df.copy()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['dob'] = pd.to_datetime(df['dob'])\ndf['dob'] = df['dob'].dt.year\ndf_test['dob'] = pd.to_datetime(df_test['dob'])\ndf_test['dob'] = df_test['dob'].dt.year\ndf_val['dob'] = pd.to_datetime(df_val['dob'])\ndf_val['dob'] = df_val['dob'].dt.year\ndf['driver_age'] = df['year'] - df['dob']\ndf_test['driver_age'] = df_test['year'] - df_test['dob']\ndf_val['driver_age'] = df_val['year'] - df_val['dob']","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.drop(['weather'], axis=1, inplace=True)\ndf_test.drop(['weather'], axis=1, inplace=True)\ndf_val.drop(['weather'], axis=1, inplace=True)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.nunique()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from sklearn.preprocessing import OneHotEncoder\n\n# ohe = OneHotEncoder(handle_unknown='ignore')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# OHE_COLS = []","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# for i in OHE_COLS:\n#     ohe.fit(df[[i]])\n#     df = pd.concat([df, pd.DataFrame(ohe.transform(df[[i]]).toarray(), columns=ohe.get_feature_names_out())], axis=1)\n#     test_df = pd.concat([test_df, pd.DataFrame(ohe.transform(test_df[[i]]).toarray(), columns=ohe.get_feature_names_out())], axis=1)\n#     val_df = pd.concat([val_df, pd.DataFrame(ohe.transform(val_df[[i]]).toarray(), columns=ohe.get_feature_names_out())], axis=1)\n\n# df = df.drop(OHE_COLS, axis=1)\n# test_df = test_df.drop(OHE_COLS, axis=1)\n# val_df = val_df.drop(OHE_COLS, axis=1)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for col in df.columns:\n    if df[col].dtype == \"object\":  # Target object columns specifically\n        print(f\"Encoding column: {col}\")\n\n        # Combine unique values from all datasets\n        unique_values = pd.concat([df[col], test_df[col], val_df[col]]).unique()\n\n        # Create and fit the LabelEncoder\n        lenc = LabelEncoder()\n        lenc.fit(unique_values)\n\n        # Transform the data\n        df[col] = lenc.transform(df[col])\n\n        # Handle potential unknown categories in test and validation sets\n        test_df[col] = test_df[col].map(\n            dict(zip(lenc.classes_, lenc.transform(lenc.classes_)))\n        )\n        val_df[col] = val_df[col].map(\n            dict(zip(lenc.classes_, lenc.transform(lenc.classes_)))\n        )\n\n        # Fill NaN values (resulting from unknown categories) with a specific value, e.g., -1\n        test_df[col] = test_df[col].fillna(-1).astype(int)\n        val_df[col] = val_df[col].fillna(-1).astype(int)\n\n        # Store the encoder\n        les[col] = lenc\n\n    # print(f\"Encoded values for {col}:\", df[col].unique())\n    # print(f\"Test set values for {col}:\", df_test[col].unique())\n    # print(f\"Validation set values for {col}:\", df_val[col].unique())\n    # print(\"\\n\")\n\ndf.head()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.drop(\n    [\"driver_num\", \"time_y\", \"fastestLap\", \"rank\", \"fastestLapTime\", \"max_speed\",\"position_x\"],\n    axis=1,\n    inplace=True,\n)\ndf_test.drop(\n    [\n        \"driver_num\",\n        \"time_y\",\n        \"fastestLap\",\n        \"rank\",\n        \"fastestLapTime\",\n        \"max_speed\",\n        \"position_x\",\n    ],\n    axis=1,\n    inplace=True,\n)\ndf_val.drop(\n    [\n        \"driver_num\",\n        \"time_y\",\n        \"fastestLap\",\n        \"rank\",\n        \"fastestLapTime\",\n        \"max_speed\",\n        \"position_x\",\n    ],\n    axis=1,\n    inplace=True,\n)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # age reduced the accuracy! weather too\n# REMOVE_COLS = [DRIVER_NUM, TIME_Y]\n# # REMOVE_COLS = [DATE]","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# df = df.drop(REMOVE_COLS, axis=1)\n# test_df = test_df.drop(REMOVE_COLS, axis=1)\n# val_df = val_df.drop(REMOVE_COLS, axis=1)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # put position at the end\n# position = df.pop(POSITION)\n# df[POSITION] = position\n\n# position = val_df.pop(POSITION)\n# val_df[POSITION] = position","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# remove outliers\nq1, q3 = df[\"position\"].quantile(0.25), df[\"position\"].quantile(0.75)\niqr = q3 - q1\nlower_bound, upper_bound = q1 - 1.5*iqr, q3 + 1.5*iqr\ndf = df[(df[\"position\"] > lower_bound) & (df[\"position\"] < upper_bound)]","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # remove outliers\n# lo = 0.05\n# hi = 0.95\n# q1,q3 = (df[POSITION].quantile([lo, hi]))\n# o1 = q1-1.5*(q3-q1)\n# o2 = q3+1.5*(q3-q1)\n# df = df[(df.position>=o1) & (df.position<=o2)]\n\n# print(\"Shape before process=\",train_data.shape)\n# print(\"Shape After process=\",df.shape)\n# diff = train_data.shape[0] - df.shape[0]\n# print(\"Total {} rows and {} cols removed\".format(diff,train_data.shape[1]-df.shape[1]))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# train \nX_train = df.drop(columns=['position'])\ny_train = df['position']\nX_val = df_val.drop(columns=['position'])\ny_val = df_val['position']\nX_combined = pd.concat([X_train, X_val])\ny_combined = pd.concat([y_train, y_val])\n# print(X_combined.shape, y_combined.shape)\n# X_train, X_val, y_train, y_val = train_test_split(X_combined, y_combined, test_size=0.2, random_state=42)\n# X_test = df_test.drop(columns=['position'])\nprint(X_train.shape, y_train.shape, X_val.shape, y_val.shape)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from lightgbm import LGBMRegressor as LGBM\n\nlgbm = LGBM(\n    learning_rate=0.05,\n    n_estimators=1000,\n    num_leaves=50,\n    reg_alpha=0.1,\n    reg_lambda=0.1,\n    min_data_in_leaf=1,\n    min_data_in_bin=1,\n)\nlgbm.fit(X_train, y_train)\nprint(lgbm.score(X_val, y_val))\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# lgbm = pickle.loads(open('./model.pkl', 'rb').read())","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lgbm.score(val_df.drop([POSITION], axis=1), val_df[POSITION])","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import mean_squared_error\n\npredicted_val = lgbm.predict(val_df.drop([POSITION], axis=1))\nmse = mean_squared_error(val_df[POSITION], predicted_val)\nprint(f'Mean Squared Error: {mse}')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# feature plot \nplt.figure(figsize=(20, 10))\nplt.bar(df.drop([POSITION], axis=1).columns, lgbm.feature_importances_)\nplt.xticks(rotation=90)\nplt.show()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"prediction = lgbm.predict(df_test)\n\nsubmission = pd.DataFrame(prediction)\nsubmission.columns = [POSITION]\nsubmission = pd.concat([submission, test_data[RESULT_DRIVER_STANDING]], axis=1)\n\nsubmission.to_csv(OUTPUT_PATH + f'lgbm_{mse}.csv', index=False)","metadata":{},"execution_count":null,"outputs":[]}]}