{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":3288,"databundleVersionId":31051,"sourceType":"competition"}],"dockerImageVersionId":30788,"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,"execution":{"iopub.status.busy":"2025-02-13T22:37:21.513295Z","iopub.execute_input":"2025-02-13T22:37:21.513686Z","iopub.status.idle":"2025-02-13T22:37:21.521796Z","shell.execute_reply.started":"2025-02-13T22:37:21.513649Z","shell.execute_reply":"2025-02-13T22:37:21.520946Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd \nimport matplotlib.pyplot as plt\nimport numpy as np","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:21.530571Z","iopub.execute_input":"2025-02-13T22:37:21.530829Z","iopub.status.idle":"2025-02-13T22:37:21.534690Z","shell.execute_reply.started":"2025-02-13T22:37:21.530804Z","shell.execute_reply":"2025-02-13T22:37:21.533846Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"users=pd.read_csv(\"/kaggle/input/event-recommendation-engine-challenge/users.csv\")\ntrain_df=pd.read_csv(\"/kaggle/input/event-recommendation-engine-challenge/train.csv\")\ntest_df=pd.read_csv(\"/kaggle/input/event-recommendation-engine-challenge/test.csv\")\nevents_attendees=pd.read_csv(\"/kaggle/input/event-recommendation-engine-challenge/event_attendees.csv.gz\")\nevents = pd.read_csv('/kaggle/input/event-recommendation-engine-challenge/events.csv.gz')\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:21.553539Z","iopub.execute_input":"2025-02-13T22:37:21.553785Z","iopub.status.idle":"2025-02-13T22:37:49.328815Z","shell.execute_reply.started":"2025-02-13T22:37:21.553761Z","shell.execute_reply":"2025-02-13T22:37:49.327779Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"users.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:49.330670Z","iopub.execute_input":"2025-02-13T22:37:49.331387Z","iopub.status.idle":"2025-02-13T22:37:49.342660Z","shell.execute_reply.started":"2025-02-13T22:37:49.331339Z","shell.execute_reply":"2025-02-13T22:37:49.341707Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:49.343809Z","iopub.execute_input":"2025-02-13T22:37:49.344075Z","iopub.status.idle":"2025-02-13T22:37:49.360117Z","shell.execute_reply.started":"2025-02-13T22:37:49.344048Z","shell.execute_reply":"2025-02-13T22:37:49.359246Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"events.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:49.362450Z","iopub.execute_input":"2025-02-13T22:37:49.363096Z","iopub.status.idle":"2025-02-13T22:37:49.383874Z","shell.execute_reply.started":"2025-02-13T22:37:49.363056Z","shell.execute_reply":"2025-02-13T22:37:49.382873Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"events_attendees.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:49.384894Z","iopub.execute_input":"2025-02-13T22:37:49.385191Z","iopub.status.idle":"2025-02-13T22:37:49.398278Z","shell.execute_reply.started":"2025-02-13T22:37:49.385145Z","shell.execute_reply":"2025-02-13T22:37:49.397363Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"events_attendees['num_yes'] = events_attendees['yes'].apply(lambda x: len(str(x).split()) if pd.notnull(x) else 0)\nevents_attendees['num_maybe'] = events_attendees['maybe'].apply(lambda x: len(str(x).split()) if pd.notnull(x) else 0)\nevents_attendees['num_no'] = events_attendees['no'].apply(lambda x: len(str(x).split()) if pd.notnull(x) else 0)\nevents_attendees['num_invited'] = events_attendees['invited'].apply(lambda x: len(str(x).split()) if pd.notnull(x) else 0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:49.399259Z","iopub.execute_input":"2025-02-13T22:37:49.399556Z","iopub.status.idle":"2025-02-13T22:37:50.103097Z","shell.execute_reply.started":"2025-02-13T22:37:49.399530Z","shell.execute_reply":"2025-02-13T22:37:50.102367Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"event_attendees_df = events_attendees[['event', 'num_yes', 'num_maybe', 'num_no', 'num_invited']]\nevent_attendees_df.rename(columns={'event': 'event_id'}, inplace=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.104442Z","iopub.execute_input":"2025-02-13T22:37:50.104825Z","iopub.status.idle":"2025-02-13T22:37:50.111424Z","shell.execute_reply.started":"2025-02-13T22:37:50.104794Z","shell.execute_reply":"2025-02-13T22:37:50.110533Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# train.rename(columns={'user': 'user_id'}, inplace=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.112554Z","iopub.execute_input":"2025-02-13T22:37:50.112804Z","iopub.status.idle":"2025-02-13T22:37:50.125408Z","shell.execute_reply.started":"2025-02-13T22:37:50.112779Z","shell.execute_reply":"2025-02-13T22:37:50.124678Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# # Fusionner train_df avec user_df sur \"user_id\"\n# merged_df = pd.merge(train, users[['user_id', 'location']], on='user_id', how='left')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.126531Z","iopub.execute_input":"2025-02-13T22:37:50.127356Z","iopub.status.idle":"2025-02-13T22:37:50.135019Z","shell.execute_reply.started":"2025-02-13T22:37:50.127327Z","shell.execute_reply":"2025-02-13T22:37:50.134300Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df.rename(columns={'event': 'event_id'}, inplace=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.138344Z","iopub.execute_input":"2025-02-13T22:37:50.138705Z","iopub.status.idle":"2025-02-13T22:37:50.147402Z","shell.execute_reply.started":"2025-02-13T22:37:50.138660Z","shell.execute_reply":"2025-02-13T22:37:50.146561Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# # Fusionner le dataframe précédent avec events_df sur \"event_id\"\n# merged_df = pd.merge(merged_df, events[['event_id', 'start_time', 'city', 'country']], on='event_id', how='left')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.148827Z","iopub.execute_input":"2025-02-13T22:37:50.149258Z","iopub.status.idle":"2025-02-13T22:37:50.160942Z","shell.execute_reply.started":"2025-02-13T22:37:50.149209Z","shell.execute_reply":"2025-02-13T22:37:50.159912Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# event_attendees_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.161795Z","iopub.execute_input":"2025-02-13T22:37:50.162062Z","iopub.status.idle":"2025-02-13T22:37:50.171366Z","shell.execute_reply.started":"2025-02-13T22:37:50.162037Z","shell.execute_reply":"2025-02-13T22:37:50.170643Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# # Fusionner le dataframe précédent avec event_attendees_df sur \"event_id\"\n# merged_df = pd.merge(merged_df,event_attendees_df, on='event_id', how='left')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.172288Z","iopub.execute_input":"2025-02-13T22:37:50.172645Z","iopub.status.idle":"2025-02-13T22:37:50.183128Z","shell.execute_reply.started":"2025-02-13T22:37:50.172602Z","shell.execute_reply":"2025-02-13T22:37:50.182233Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.184115Z","iopub.execute_input":"2025-02-13T22:37:50.184361Z","iopub.status.idle":"2025-02-13T22:37:50.192946Z","shell.execute_reply.started":"2025-02-13T22:37:50.184321Z","shell.execute_reply":"2025-02-13T22:37:50.192138Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.193961Z","iopub.execute_input":"2025-02-13T22:37:50.194318Z","iopub.status.idle":"2025-02-13T22:37:50.207947Z","shell.execute_reply.started":"2025-02-13T22:37:50.194277Z","shell.execute_reply":"2025-02-13T22:37:50.207012Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# print(merged_df.isnull().sum())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.209014Z","iopub.execute_input":"2025-02-13T22:37:50.209259Z","iopub.status.idle":"2025-02-13T22:37:50.217399Z","shell.execute_reply.started":"2025-02-13T22:37:50.209235Z","shell.execute_reply":"2025-02-13T22:37:50.216596Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.218320Z","iopub.execute_input":"2025-02-13T22:37:50.218607Z","iopub.status.idle":"2025-02-13T22:37:50.227653Z","shell.execute_reply.started":"2025-02-13T22:37:50.218567Z","shell.execute_reply":"2025-02-13T22:37:50.226964Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import seaborn as sns\n# sns.pairplot(merged_df)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.228600Z","iopub.execute_input":"2025-02-13T22:37:50.228848Z","iopub.status.idle":"2025-02-13T22:37:50.239067Z","shell.execute_reply.started":"2025-02-13T22:37:50.228823Z","shell.execute_reply":"2025-02-13T22:37:50.238353Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# missing_percentage = merged_df.isnull().mean() * 100\n# print(missing_percentage)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.240220Z","iopub.execute_input":"2025-02-13T22:37:50.240951Z","iopub.status.idle":"2025-02-13T22:37:50.249059Z","shell.execute_reply.started":"2025-02-13T22:37:50.240912Z","shell.execute_reply":"2025-02-13T22:37:50.248169Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df = merged_df.dropna(subset=['location'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.250177Z","iopub.execute_input":"2025-02-13T22:37:50.250421Z","iopub.status.idle":"2025-02-13T22:37:50.260182Z","shell.execute_reply.started":"2025-02-13T22:37:50.250397Z","shell.execute_reply":"2025-02-13T22:37:50.259420Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df['city'].fillna('Unknown', inplace=True)\n# merged_df['country'].fillna('Unknown', inplace=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.261206Z","iopub.execute_input":"2025-02-13T22:37:50.261452Z","iopub.status.idle":"2025-02-13T22:37:50.270882Z","shell.execute_reply.started":"2025-02-13T22:37:50.261427Z","shell.execute_reply":"2025-02-13T22:37:50.270108Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df.isna().sum()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.271940Z","iopub.execute_input":"2025-02-13T22:37:50.272225Z","iopub.status.idle":"2025-02-13T22:37:50.281169Z","shell.execute_reply.started":"2025-02-13T22:37:50.272200Z","shell.execute_reply":"2025-02-13T22:37:50.280402Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df['location'].str.split()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.282187Z","iopub.execute_input":"2025-02-13T22:37:50.282716Z","iopub.status.idle":"2025-02-13T22:37:50.291272Z","shell.execute_reply.started":"2025-02-13T22:37:50.282668Z","shell.execute_reply":"2025-02-13T22:37:50.290505Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df['location'].tail(100) #format not good ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.292323Z","iopub.execute_input":"2025-02-13T22:37:50.292673Z","iopub.status.idle":"2025-02-13T22:37:50.304521Z","shell.execute_reply.started":"2025-02-13T22:37:50.292636Z","shell.execute_reply":"2025-02-13T22:37:50.303712Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df['location'].value_counts()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.305356Z","iopub.execute_input":"2025-02-13T22:37:50.305618Z","iopub.status.idle":"2025-02-13T22:37:50.314897Z","shell.execute_reply.started":"2025-02-13T22:37:50.305594Z","shell.execute_reply":"2025-02-13T22:37:50.314235Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import pandas as pd\n# import re\n# # Fonction pour extraire user_city et user_country\n# def extract_city_country(location):\n#     # Supprimer les chiffres dans la chaîne de caractères\n#     cleaned_location = re.sub(r'\\d+', '', location)\n    \n#     # Séparer les mots\n#     words = cleaned_location.split()\n    \n#     # Gérer les cas selon le nombre de mots après suppression des chiffres\n#     if len(words) > 2:\n#         # Concaténer les deux premiers mots pour user_city et le reste pour user_country\n#         user_city = ' '.join(words[:2])\n#         user_country = ' '.join(words[2:])\n#     elif len(words) == 2:\n#         # Si deux mots, premier pour user_city et second pour user_country\n#         user_city = words[0]\n#         user_country = words[1]\n#     else:\n#         # Cas de moins de deux mots (incomplet)\n#         user_city = words[0] if words else 'Unknown'\n#         user_country = 'Unknown'\n    \n#     return pd.Series([user_city, user_country])\n\n\n\n    ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.315936Z","iopub.execute_input":"2025-02-13T22:37:50.316171Z","iopub.status.idle":"2025-02-13T22:37:50.325243Z","shell.execute_reply.started":"2025-02-13T22:37:50.316147Z","shell.execute_reply":"2025-02-13T22:37:50.324441Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# # Appliquer la fonction à la colonne 'location'\n# merged_df[['user_city', 'user_country']] = merged_df['location'].apply(extract_city_country)\n\n# # Afficher le résultat\n# print(merged_df[['location', 'user_city', 'user_country']])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.326161Z","iopub.execute_input":"2025-02-13T22:37:50.326377Z","iopub.status.idle":"2025-02-13T22:37:50.342937Z","shell.execute_reply.started":"2025-02-13T22:37:50.326356Z","shell.execute_reply":"2025-02-13T22:37:50.342127Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df.tail(100)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.348973Z","iopub.execute_input":"2025-02-13T22:37:50.349268Z","iopub.status.idle":"2025-02-13T22:37:50.353456Z","shell.execute_reply.started":"2025-02-13T22:37:50.349242Z","shell.execute_reply":"2025-02-13T22:37:50.352529Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df['timestamp'] = pd.to_datetime(merged_df['timestamp'], errors='coerce')\n# merged_df['start_time'] = pd.to_datetime(merged_df['start_time'], errors='coerce')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.354539Z","iopub.execute_input":"2025-02-13T22:37:50.354793Z","iopub.status.idle":"2025-02-13T22:37:50.364299Z","shell.execute_reply.started":"2025-02-13T22:37:50.354769Z","shell.execute_reply":"2025-02-13T22:37:50.363639Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df['user_time'] =merged_df['timestamp'].dt.strftime('%Y/%m/%d %H:%M:%S')\n# merged_df['event_time'] = merged_df['start_time'].dt.strftime('%Y/%m/%d %H:%M:%S')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.365327Z","iopub.execute_input":"2025-02-13T22:37:50.365586Z","iopub.status.idle":"2025-02-13T22:37:50.374749Z","shell.execute_reply.started":"2025-02-13T22:37:50.365562Z","shell.execute_reply":"2025-02-13T22:37:50.374028Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.375622Z","iopub.execute_input":"2025-02-13T22:37:50.375875Z","iopub.status.idle":"2025-02-13T22:37:50.385439Z","shell.execute_reply.started":"2025-02-13T22:37:50.375850Z","shell.execute_reply":"2025-02-13T22:37:50.384736Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df.drop(\"location\",axis=1,inplace=True)\n# merged_df.drop(\"timestamp\",axis=1,inplace=True)\n# merged_df.drop(\"start_time\",axis=1,inplace=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.386452Z","iopub.execute_input":"2025-02-13T22:37:50.386768Z","iopub.status.idle":"2025-02-13T22:37:50.396654Z","shell.execute_reply.started":"2025-02-13T22:37:50.386741Z","shell.execute_reply":"2025-02-13T22:37:50.395793Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.397604Z","iopub.execute_input":"2025-02-13T22:37:50.397891Z","iopub.status.idle":"2025-02-13T22:37:50.407332Z","shell.execute_reply.started":"2025-02-13T22:37:50.397866Z","shell.execute_reply":"2025-02-13T22:37:50.406633Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.408408Z","iopub.execute_input":"2025-02-13T22:37:50.408698Z","iopub.status.idle":"2025-02-13T22:37:50.417177Z","shell.execute_reply.started":"2025-02-13T22:37:50.408672Z","shell.execute_reply":"2025-02-13T22:37:50.416439Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df['user_id'].nunique()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.417964Z","iopub.execute_input":"2025-02-13T22:37:50.418171Z","iopub.status.idle":"2025-02-13T22:37:50.431214Z","shell.execute_reply.started":"2025-02-13T22:37:50.418151Z","shell.execute_reply":"2025-02-13T22:37:50.430439Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df[merged_df['user_id'] == 3044012]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.432213Z","iopub.execute_input":"2025-02-13T22:37:50.432448Z","iopub.status.idle":"2025-02-13T22:37:50.441493Z","shell.execute_reply.started":"2025-02-13T22:37:50.432423Z","shell.execute_reply":"2025-02-13T22:37:50.440723Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df['user_time'] = pd.to_datetime(merged_df['user_time'], errors='coerce')\n# merged_df['event_time'] = pd.to_datetime(merged_df['event_time'], errors='coerce')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.442312Z","iopub.execute_input":"2025-02-13T22:37:50.442596Z","iopub.status.idle":"2025-02-13T22:37:50.452440Z","shell.execute_reply.started":"2025-02-13T22:37:50.442551Z","shell.execute_reply":"2025-02-13T22:37:50.451631Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# from datetime import datetime\n\n# users['birthyear']=pd.to_datetime(users['birthyear'], errors='coerce')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.453593Z","iopub.execute_input":"2025-02-13T22:37:50.453854Z","iopub.status.idle":"2025-02-13T22:37:50.465165Z","shell.execute_reply.started":"2025-02-13T22:37:50.453830Z","shell.execute_reply":"2025-02-13T22:37:50.464520Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# # Étape 1 : Fusionner merged_df avec users sur user_id\n# merged_df = merged_df.merge(users[['user_id', 'birthyear']], on='user_id', how='left')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.465987Z","iopub.execute_input":"2025-02-13T22:37:50.466230Z","iopub.status.idle":"2025-02-13T22:37:50.478194Z","shell.execute_reply.started":"2025-02-13T22:37:50.466206Z","shell.execute_reply":"2025-02-13T22:37:50.477486Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# # Étape 2 : Calculer l'âge de l'utilisateur\n# current_year = datetime.now().year\n# merged_df['user_old'] = current_year - merged_df['birthyear'].dt.year\n\n# # Étape 3 : Supprimer la colonne birthyear si tu n'en as plus besoin\n# merged_df.drop(columns=['birthyear'], inplace=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.479116Z","iopub.execute_input":"2025-02-13T22:37:50.479383Z","iopub.status.idle":"2025-02-13T22:37:50.487979Z","shell.execute_reply.started":"2025-02-13T22:37:50.479359Z","shell.execute_reply":"2025-02-13T22:37:50.487222Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# # calculer delai de temps entre temp de l'evenement et l'utilisateur quand l'a vu \n# merged_df['delai']=merged_df['event_time']-merged_df['user_time']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.489120Z","iopub.execute_input":"2025-02-13T22:37:50.489746Z","iopub.status.idle":"2025-02-13T22:37:50.499134Z","shell.execute_reply.started":"2025-02-13T22:37:50.489707Z","shell.execute_reply":"2025-02-13T22:37:50.498241Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.500096Z","iopub.execute_input":"2025-02-13T22:37:50.500364Z","iopub.status.idle":"2025-02-13T22:37:50.512988Z","shell.execute_reply.started":"2025-02-13T22:37:50.500323Z","shell.execute_reply":"2025-02-13T22:37:50.512214Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df.dropna(subset=['user_time', 'user_old', 'delai'], inplace=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.513776Z","iopub.execute_input":"2025-02-13T22:37:50.513985Z","iopub.status.idle":"2025-02-13T22:37:50.524149Z","shell.execute_reply.started":"2025-02-13T22:37:50.513964Z","shell.execute_reply":"2025-02-13T22:37:50.523488Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df.isna().sum()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.525368Z","iopub.execute_input":"2025-02-13T22:37:50.525721Z","iopub.status.idle":"2025-02-13T22:37:50.535400Z","shell.execute_reply.started":"2025-02-13T22:37:50.525683Z","shell.execute_reply":"2025-02-13T22:37:50.534711Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.536408Z","iopub.execute_input":"2025-02-13T22:37:50.536700Z","iopub.status.idle":"2025-02-13T22:37:50.546036Z","shell.execute_reply.started":"2025-02-13T22:37:50.536668Z","shell.execute_reply":"2025-02-13T22:37:50.545322Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# merged_df['user_city'].nunique()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.547003Z","iopub.execute_input":"2025-02-13T22:37:50.547243Z","iopub.status.idle":"2025-02-13T22:37:50.557120Z","shell.execute_reply.started":"2025-02-13T22:37:50.547220Z","shell.execute_reply":"2025-02-13T22:37:50.556225Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport re\nfrom datetime import datetime\nfrom sklearn.base import BaseEstimator, TransformerMixin\n\nclass PreprocessingPipeline(BaseEstimator, TransformerMixin):\n    def __init__(self, train=True):\n        self.train = train  # Indique si on traite un fichier d'entraînement ou de test\n    \n    def fit(self, X, y=None):\n        return self  # Pas d'apprentissage dans la pipeline\n\n    def transform(self, data):\n        # Charger les fichiers externes nécessaires\n        users=pd.read_csv(\"/kaggle/input/event-recommendation-engine-challenge/users.csv\")\n        events_attendees=pd.read_csv(\"/kaggle/input/event-recommendation-engine-challenge/event_attendees.csv.gz\")\n        events = pd.read_csv('/kaggle/input/event-recommendation-engine-challenge/events.csv.gz')\n\n\n\n        # Fusion des datasets\n        data.rename(columns={'user': 'user_id'}, inplace=True)\n        data = pd.merge(data, users[['user_id', 'location', 'birthyear']], on='user_id', how='left')\n        data.rename(columns={'event': 'event_id'}, inplace=True)\n        data = pd.merge(data, events[['event_id', 'start_time', 'city', 'country']], on='event_id', how='left')\n        data = pd.merge(data, event_attendees_df, on='event_id', how='left')\n\n        # Remplir les valeurs manquantes\n        data.dropna(subset=['location'], inplace=True)\n        data['city'].fillna('Unknown', inplace=True)\n        data['country'].fillna('Unknown', inplace=True)\n\n        # Extraire user_city et user_country depuis location\n        data[['user_city', 'user_country']] = data['location'].apply(self.extract_city_country)\n\n        # Convertir les timestamps en format datetime\n        data['timestamp'] = pd.to_datetime(data['timestamp'], errors='coerce')\n        data['start_time'] = pd.to_datetime(data['start_time'], errors='coerce')\n        data['user_time'] = data['timestamp'].dt.strftime('%Y/%m/%d %H:%M:%S')\n        data['event_time'] = data['start_time'].dt.strftime('%Y/%m/%d %H:%M:%S')\n\n        # Supprimer la colonne 'location'\n        data.drop(columns=['location', 'timestamp', 'start_time'], inplace=True)\n\n        # Convertir en datetime\n        data['user_time'] = pd.to_datetime(data['user_time'], errors='coerce')\n        data['event_time'] = pd.to_datetime(data['event_time'], errors='coerce')\n\n        # Calculer l'âge de l'utilisateur\n        data['birthyear'] = pd.to_datetime(data['birthyear'], errors='coerce')\n        current_year = datetime.now().year\n        data['user_old'] = current_year - data['birthyear'].dt.year\n\n        # Supprimer la colonne birthyear\n        data.drop(columns=['birthyear'], inplace=True)\n\n        # Calculer le délai entre l'événement et l'interaction\n        data['delai'] = data['event_time'] - data['user_time']\n\n        # Supprimer les valeurs manquantes\n        data.dropna(subset=['user_time', 'user_old', 'delai'], inplace=True)\n\n        return data\n\n    @staticmethod\n    def extract_city_country(location):\n        \"\"\" Fonction pour extraire user_city et user_country \"\"\"\n        cleaned_location = re.sub(r'\\d+', '', location)\n        words = cleaned_location.split()\n        if len(words) > 2:\n            user_city = ' '.join(words[:2])\n            user_country = ' '.join(words[2:])\n        elif len(words) == 2:\n            user_city = words[0]\n            user_country = words[1]\n        else:\n            user_city = words[0] if words else 'Unknown'\n            user_country = 'Unknown'\n        return pd.Series([user_city, user_country])\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:50.558582Z","iopub.execute_input":"2025-02-13T22:37:50.558911Z","iopub.status.idle":"2025-02-13T22:37:51.014807Z","shell.execute_reply.started":"2025-02-13T22:37:50.558873Z","shell.execute_reply":"2025-02-13T22:37:51.013733Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# Appliquer la pipeline de prétraitement\npreprocessor = PreprocessingPipeline()\n\n# Transformer les données d'entraînement et de test\ntrain_cleaned = preprocessor.fit_transform(train_df)\ntest_cleaned = preprocessor.transform(test_df)  # Pas besoin de `fit` pour le test\n\n# Sauvegarder les fichiers nettoyés\ntrain_cleaned.to_csv(\"train_cleaned.csv\", index=False)\ntest_cleaned.to_csv(\"test_cleaned.csv\", index=False)\n\nprint(\"Prétraitement terminé !\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:37:51.016193Z","iopub.execute_input":"2025-02-13T22:37:51.016778Z","iopub.status.idle":"2025-02-13T22:38:48.219307Z","shell.execute_reply.started":"2025-02-13T22:37:51.016732Z","shell.execute_reply":"2025-02-13T22:38:48.218336Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport tensorflow as tf\nfrom tensorflow.keras.layers import Input, Embedding, Flatten, Concatenate, Dense\nfrom tensorflow.keras.models import Model\nfrom sklearn.preprocessing import LabelEncoder\ndef preprocess_data(df, label_encoders=None, is_train=True):\n    df = df.copy()\n    \n    if is_train:\n        label_encoders = {}\n        for col in ['city', 'country', 'user_city', 'user_country']:\n            le = LabelEncoder()\n            df[col] = le.fit_transform(df[col])\n            label_encoders[col] = le\n    else:\n        for col in ['city', 'country', 'user_city', 'user_country']:\n            # Vérifier si la colonne contient des valeurs inconnues\n            df[col] = df[col].apply(lambda x: x if x in label_encoders[col].classes_ else 'unknown')\n            le_classes = np.append(label_encoders[col].classes_, 'unknown')\n            label_encoders[col].classes_ = le_classes\n            df[col] = label_encoders[col].transform(df[col])\n    \n    X_num = df[['user_id', 'event_id', 'invited', 'num_yes', 'num_maybe', 'num_no', \n                'num_invited', 'user_old']].copy()\n\n    X_num['user_time'] = df['user_time'].astype('int64') // 10**9\n    X_num['event_time'] = df['event_time'].astype('int64') // 10**9\n\n    X_num['delai'] = df['delai'].dt.total_seconds()\n\n    X_cat = df[['city', 'country', 'user_city', 'user_country']]\n    \n    y = df['interested'] if is_train else None\n\n    return X_cat, X_num, y, label_encoders if is_train else None\n\n\n# Preprocessing sur train_cleaned\nX_cat_train, X_num_train, y_train, label_encoders = preprocess_data(train_cleaned, is_train=True)\n\n# Preprocessing sur test_cleaned en utilisant les mêmes encoders\nX_cat_test, X_num_test, _, _ = preprocess_data(test_cleaned, label_encoders, is_train=False)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:38:48.220494Z","iopub.execute_input":"2025-02-13T22:38:48.220796Z","iopub.status.idle":"2025-02-13T22:38:51.287656Z","shell.execute_reply.started":"2025-02-13T22:38:48.220768Z","shell.execute_reply":"2025-02-13T22:38:51.286919Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tensorflow.keras.callbacks import EarlyStopping\n\n# Définir les dimensions d'embedding\nembedding_dim = 40\n\n# Définition des entrées\ninput_city = Input(shape=(1,), name='input_city')\ninput_country = Input(shape=(1,), name='input_country')\ninput_user_city = Input(shape=(1,), name='input_user_city')\ninput_user_country = Input(shape=(1,), name='input_user_country')\n\n# Couches d'embedding\nembedding_city = Embedding(input_dim=len(label_encoders['city'].classes_), output_dim=embedding_dim, name='embedding_city')(input_city)\nembedding_country = Embedding(input_dim=len(label_encoders['country'].classes_), output_dim=embedding_dim, name='embedding_country')(input_country)\nembedding_user_city = Embedding(input_dim=len(label_encoders['user_city'].classes_), output_dim=embedding_dim, name='embedding_user_city')(input_user_city)\nembedding_user_country = Embedding(input_dim=len(label_encoders['user_country'].classes_), output_dim=embedding_dim, name='embedding_user_country')(input_user_country)\n\n# Aplatir les embeddings\nflatten_city = Flatten()(embedding_city)\nflatten_country = Flatten()(embedding_country)\nflatten_user_city = Flatten()(embedding_user_city)\nflatten_user_country = Flatten()(embedding_user_country)\n\n# Entrée pour les caractéristiques numériques\ninput_numeric = Input(shape=(X_num_train.shape[1],), name='input_numeric')\n\n# Concaténation des embeddings et des caractéristiques numériques\nmerged = Concatenate()([flatten_city, flatten_country, flatten_user_city, flatten_user_country, input_numeric])\n\n# Couches cachées du modèle\nx = Dense(128, activation='relu')(merged)\nx = Dense(64, activation='relu')(x)\noutput = Dense(1, activation='sigmoid')(x)  # Prédiction binaire\n\n# Définition du modèle\nmodel = Model(inputs=[input_city, input_country, input_user_city, input_user_country, input_numeric], outputs=output)\nmodel.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])\nmodel.summary()\n\n\nfrom sklearn.model_selection import train_test_split\n\nX_cat_train, X_cat_valid, X_num_train, X_num_valid, y_train, y_valid = train_test_split(\n    X_cat_train, X_num_train, y_train, test_size=0.2, random_state=42\n)\nearly_stopping = EarlyStopping(\n    monitor='val_loss',  # Surveiller la perte de validation\n    patience=6,          # Nombre d'époques sans amélioration avant d'arrêter\n    restore_best_weights=True,  # Restaurer les meilleurs poids du modèle\n    verbose=1\n)\n# Entraînement du modèle sur tout train_cleaned\nhistory = model.fit(\n    x=[X_cat_train['city'], X_cat_train['country'], X_cat_train['user_city'], X_cat_train['user_country'], X_num_train],\n    y=y_train,\n    epochs=100,\n    batch_size=64,\n    validation_data=(\n        [X_cat_valid['city'], X_cat_valid['country'], X_cat_valid['user_city'], X_cat_valid['user_country'], X_num_valid], \n        y_valid\n    ),\n    callbacks=[early_stopping]  # Ajouter le callback pour l'early stopping\n\n)\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:43:05.618251Z","iopub.execute_input":"2025-02-13T22:43:05.619076Z","iopub.status.idle":"2025-02-13T22:43:15.434430Z","shell.execute_reply.started":"2025-02-13T22:43:05.619037Z","shell.execute_reply":"2025-02-13T22:43:15.433525Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import numpy as np\n# import pandas as pd\n# import tensorflow as tf\n# from tensorflow.keras.layers import Input, Embedding, Flatten, Concatenate, Dense\n# from tensorflow.keras.models import Model\n# from sklearn.preprocessing import LabelEncoder\n# from sklearn.model_selection import train_test_split\n\n\n\n# # Encodage des colonnes catégorielles\n# label_encoders = {}\n# for col in ['city', 'country', 'user_city', 'user_country']:\n#     le = LabelEncoder()\n#     merged_df[col] = le.fit_transform(merged_df[col])\n#     label_encoders[col] = le  # Sauvegarde des encodeurs pour plus tard\n\n# # Caractéristiques numériques\n# X_num = merged_df[['user_id', 'event_id', 'invited', 'num_yes', 'num_maybe', 'num_no', \n#                    'num_invited', 'user_old']].copy()\n\n# # Transformation des colonnes datetime en timestamps\n# X_num['user_time'] = merged_df['user_time'].astype('int64') // 10**9\n# X_num['event_time'] = merged_df['event_time'].astype('int64') // 10**9\n\n# # Transformation de timedelta en secondes\n# X_num['delai'] = merged_df['delai'].dt.total_seconds()\n\n# # Cible\n# y = merged_df['interested']\n\n# # Séparation des données catégorielles et numériques\n# X_cat = merged_df[['city', 'country', 'user_city', 'user_country']]\n\n# # Séparation en train/test\n# X_cat_train, X_cat_test, X_num_train, X_num_test, y_train, y_test = train_test_split(\n#     X_cat, X_num, y, test_size=0.2, random_state=42\n# )\n\n# # Définir les dimensions d'embedding\n# embedding_dim = 40\n\n# # Définition des entrées\n# input_city = Input(shape=(1,), name='input_city')\n# input_country = Input(shape=(1,), name='input_country')\n# input_user_city = Input(shape=(1,), name='input_user_city')\n# input_user_country = Input(shape=(1,), name='input_user_country')\n\n# # Couches d'embedding\n# embedding_city = Embedding(input_dim=max(2, len(label_encoders['city'].classes_)), output_dim=embedding_dim, name='embedding_city')(input_city)\n# embedding_country = Embedding(input_dim=max(2, len(label_encoders['country'].classes_)), output_dim=embedding_dim, name='embedding_country')(input_country)\n# embedding_user_city = Embedding(input_dim=max(2, len(label_encoders['user_city'].classes_)), output_dim=embedding_dim, name='embedding_user_city')(input_user_city)\n# embedding_user_country = Embedding(input_dim=max(2, len(label_encoders['user_country'].classes_)), output_dim=embedding_dim, name='embedding_user_country')(input_user_country)\n\n# # Aplatir les embeddings\n# flatten_city = Flatten()(embedding_city)\n# flatten_country = Flatten()(embedding_country)\n# flatten_user_city = Flatten()(embedding_user_city)\n# flatten_user_country = Flatten()(embedding_user_country)\n\n# # Entrée pour les caractéristiques numériques\n# input_numeric = Input(shape=(X_num_train.shape[1],), name='input_numeric')\n\n# # Concaténation des embeddings et des caractéristiques numériques\n# merged = Concatenate()([flatten_city, flatten_country, flatten_user_city, flatten_user_country, input_numeric])\n\n# # Couches cachées du modèle\n# x = Dense(128, activation='relu')(merged)\n# x = Dense(64, activation='relu')(x)\n# output = Dense(1, activation='sigmoid')(x)  # Prédiction binaire\n\n# # Définition du modèle\n# model = Model(inputs=[input_city, input_country, input_user_city, input_user_country, input_numeric], outputs=output)\n# model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])\n# model.summary()\n\n# # Entraînement du modèle\n# history = model.fit(\n#     x=[X_cat_train['city'], X_cat_train['country'], X_cat_train['user_city'], X_cat_train['user_country'], X_num_train],\n#     y=y_train,\n#     validation_data=([X_cat_test['city'], X_cat_test['country'], X_cat_test['user_city'], X_cat_test['user_country'], X_num_test], y_test),\n#     epochs=40,\n#     batch_size=32\n# )\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:43:28.392116Z","iopub.execute_input":"2025-02-13T22:43:28.392973Z","iopub.status.idle":"2025-02-13T22:43:28.398970Z","shell.execute_reply.started":"2025-02-13T22:43:28.392936Z","shell.execute_reply":"2025-02-13T22:43:28.397951Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(X_cat_train.columns)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:43:28.451895Z","iopub.execute_input":"2025-02-13T22:43:28.452182Z","iopub.status.idle":"2025-02-13T22:43:28.457134Z","shell.execute_reply.started":"2025-02-13T22:43:28.452154Z","shell.execute_reply":"2025-02-13T22:43:28.456179Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Récupérer l'historique de l'entraînement\nhistory_dict = history.history\n\n# Tracer la courbe de perte (loss)\nplt.figure(figsize=(12, 5))\nplt.subplot(1, 2, 1)\nplt.plot(history_dict['loss'], label='Train Loss')\nplt.plot(history_dict['val_loss'], label='Validation Loss')\nplt.xlabel('Épochs')\nplt.ylabel('Perte')\nplt.title('Courbe de Perte')\nplt.legend()\n\n# Tracer la courbe d'exactitude (accuracy)\nplt.subplot(1, 2, 2)\nplt.plot(history_dict['accuracy'], label='Train Accuracy')\nplt.plot(history_dict['val_accuracy'], label='Validation Accuracy')\nplt.xlabel('Épochs')\nplt.ylabel('Exactitude')\nplt.title('Courbe d\\'Exactitude')\nplt.legend()\n\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:43:28.629284Z","iopub.execute_input":"2025-02-13T22:43:28.629906Z","iopub.status.idle":"2025-02-13T22:43:29.060504Z","shell.execute_reply.started":"2025-02-13T22:43:28.629861Z","shell.execute_reply":"2025-02-13T22:43:29.059447Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_cat_test.columns","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:43:29.062436Z","iopub.execute_input":"2025-02-13T22:43:29.062919Z","iopub.status.idle":"2025-02-13T22:43:29.069597Z","shell.execute_reply.started":"2025-02-13T22:43:29.062872Z","shell.execute_reply":"2025-02-13T22:43:29.068723Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Prédiction sur le set de test\ny_pred = model.predict([\n    X_cat_test['city'], \n    X_cat_test['country'], \n    X_cat_test['user_city'], \n    X_cat_test['user_country'], \n    X_num_test\n])\n\n# Affichage des premières prédictions\nprint(y_pred[:30])  # Afficher les 10 premières prédictions\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:43:29.070527Z","iopub.execute_input":"2025-02-13T22:43:29.070876Z","iopub.status.idle":"2025-02-13T22:43:30.095719Z","shell.execute_reply.started":"2025-02-13T22:43:29.070838Z","shell.execute_reply":"2025-02-13T22:43:30.094772Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Évaluation du modèle sur les données de validation\nval_loss, val_accuracy = model.evaluate(\n    [X_cat_valid['city'], X_cat_valid['country'], X_cat_valid['user_city'], X_cat_valid['user_country'], X_num_valid], \n    y_valid\n)\n\nprint(f\"Perte sur validation: {val_loss}\")\nprint(f\"Précision sur validation: {val_accuracy}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:43:30.097637Z","iopub.execute_input":"2025-02-13T22:43:30.098301Z","iopub.status.idle":"2025-02-13T22:43:30.364691Z","shell.execute_reply.started":"2025-02-13T22:43:30.098250Z","shell.execute_reply":"2025-02-13T22:43:30.363811Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Faire des prédictions sur les données de validation\ny_pred_proba = model.predict([X_cat_valid['city'], X_cat_valid['country'], X_cat_valid['user_city'], X_cat_valid['user_country'], X_num_valid])\n\n# Convertir les probabilités en classes\ny_pred_classes = (y_pred_proba > 0.5).astype(int)\n\n# Afficher les premières prédictions avec les vraies valeurs\nfor i in range(50):\n    print(f\"Vrai: {y_valid.iloc[i]}, Prédit: {y_pred_classes[i]}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-02-13T22:43:33.648194Z","iopub.execute_input":"2025-02-13T22:43:33.648714Z","iopub.status.idle":"2025-02-13T22:43:33.939257Z","shell.execute_reply.started":"2025-02-13T22:43:33.648668Z","shell.execute_reply":"2025-02-13T22:43:33.938072Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}