{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":31254,"databundleVersionId":3103714,"sourceType":"competition"}],"dockerImageVersionId":30840,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# **Importing Python packages**   ","metadata":{"execution":{"iopub.status.busy":"2025-01-16T21:57:14.197076Z","iopub.execute_input":"2025-01-16T21:57:14.197524Z","iopub.status.idle":"2025-01-16T21:57:14.201850Z","shell.execute_reply.started":"2025-01-16T21:57:14.197487Z","shell.execute_reply":"2025-01-16T21:57:14.200886Z"}}},{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt # graph visualization\nimport matplotlib.image as mpimg # image visualizations \nfrom IPython.display import Image, display # image visualizations\nimport seaborn as sns # graph visualizations\nfrom sklearn.metrics.pairwise import cosine_similarity ","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:06:09.433547Z","iopub.execute_input":"2025-01-18T09:06:09.433891Z","iopub.status.idle":"2025-01-18T09:06:10.541414Z","shell.execute_reply.started":"2025-01-18T09:06:09.433864Z","shell.execute_reply":"2025-01-18T09:06:10.540773Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Loading datasets**","metadata":{}},{"cell_type":"code","source":"articles = pd.read_csv('/kaggle/input/h-and-m-personalized-fashion-recommendations/articles.csv')\ncustomers = pd.read_csv('/kaggle/input/h-and-m-personalized-fashion-recommendations/customers.csv')\nsample_submission = pd.read_csv('/kaggle/input/h-and-m-personalized-fashion-recommendations/sample_submission.csv')\ntransactions_train = pd.read_csv('/kaggle/input/h-and-m-personalized-fashion-recommendations/transactions_train.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:06:10.542531Z","iopub.execute_input":"2025-01-18T09:06:10.542946Z","iopub.status.idle":"2025-01-18T09:07:20.128706Z","shell.execute_reply.started":"2025-01-18T09:06:10.542922Z","shell.execute_reply":"2025-01-18T09:07:20.127981Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Data Exploration**","metadata":{}},{"cell_type":"code","source":"articles.head() # Affiche les 5 premières lignes par défaut","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:20.159184Z","iopub.execute_input":"2025-01-18T09:07:20.159428Z","iopub.status.idle":"2025-01-18T09:07:20.190468Z","shell.execute_reply.started":"2025-01-18T09:07:20.159409Z","shell.execute_reply":"2025-01-18T09:07:20.189548Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"customers.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:20.191917Z","iopub.execute_input":"2025-01-18T09:07:20.192219Z","iopub.status.idle":"2025-01-18T09:07:20.204618Z","shell.execute_reply.started":"2025-01-18T09:07:20.192194Z","shell.execute_reply":"2025-01-18T09:07:20.203823Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_submission.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:20.205370Z","iopub.execute_input":"2025-01-18T09:07:20.205560Z","iopub.status.idle":"2025-01-18T09:07:20.212060Z","shell.execute_reply.started":"2025-01-18T09:07:20.205543Z","shell.execute_reply":"2025-01-18T09:07:20.211434Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"transactions_train.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:20.212830Z","iopub.execute_input":"2025-01-18T09:07:20.213121Z","iopub.status.idle":"2025-01-18T09:07:20.230606Z","shell.execute_reply.started":"2025-01-18T09:07:20.213095Z","shell.execute_reply":"2025-01-18T09:07:20.229951Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"articles.info() #Pour obtenir des informations générales","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:20.231278Z","iopub.execute_input":"2025-01-18T09:07:20.231473Z","iopub.status.idle":"2025-01-18T09:07:20.320542Z","shell.execute_reply.started":"2025-01-18T09:07:20.231456Z","shell.execute_reply":"2025-01-18T09:07:20.319830Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"customers.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:20.321245Z","iopub.execute_input":"2025-01-18T09:07:20.321478Z","iopub.status.idle":"2025-01-18T09:07:20.593980Z","shell.execute_reply.started":"2025-01-18T09:07:20.321453Z","shell.execute_reply":"2025-01-18T09:07:20.593250Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"transactions_train.info()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:20.596354Z","iopub.execute_input":"2025-01-18T09:07:20.596592Z","iopub.status.idle":"2025-01-18T09:07:20.603420Z","shell.execute_reply.started":"2025-01-18T09:07:20.596573Z","shell.execute_reply":"2025-01-18T09:07:20.602632Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"articles.shape #dimensions of dataframe","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:20.604799Z","iopub.execute_input":"2025-01-18T09:07:20.605005Z","iopub.status.idle":"2025-01-18T09:07:20.619613Z","shell.execute_reply.started":"2025-01-18T09:07:20.604986Z","shell.execute_reply":"2025-01-18T09:07:20.618756Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"customers.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:20.620431Z","iopub.execute_input":"2025-01-18T09:07:20.620699Z","iopub.status.idle":"2025-01-18T09:07:20.635226Z","shell.execute_reply.started":"2025-01-18T09:07:20.620678Z","shell.execute_reply":"2025-01-18T09:07:20.634558Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"transactions_train.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:20.635873Z","iopub.execute_input":"2025-01-18T09:07:20.636132Z","iopub.status.idle":"2025-01-18T09:07:20.650364Z","shell.execute_reply.started":"2025-01-18T09:07:20.636111Z","shell.execute_reply":"2025-01-18T09:07:20.649524Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"articles.isnull().sum() #count the number of missing values","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:20.651209Z","iopub.execute_input":"2025-01-18T09:07:20.651469Z","iopub.status.idle":"2025-01-18T09:07:20.729135Z","shell.execute_reply.started":"2025-01-18T09:07:20.651450Z","shell.execute_reply":"2025-01-18T09:07:20.728244Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"customers.isnull().sum()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:20.730050Z","iopub.execute_input":"2025-01-18T09:07:20.730361Z","iopub.status.idle":"2025-01-18T09:07:20.999860Z","shell.execute_reply.started":"2025-01-18T09:07:20.730331Z","shell.execute_reply":"2025-01-18T09:07:20.999027Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"transactions_train.isnull().sum()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:21.000632Z","iopub.execute_input":"2025-01-18T09:07:21.000943Z","iopub.status.idle":"2025-01-18T09:07:23.730405Z","shell.execute_reply.started":"2025-01-18T09:07:21.000912Z","shell.execute_reply":"2025-01-18T09:07:23.729585Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"articles.nunique() #number of unique values for each column","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:23.731107Z","iopub.execute_input":"2025-01-18T09:07:23.731316Z","iopub.status.idle":"2025-01-18T09:07:23.851440Z","shell.execute_reply.started":"2025-01-18T09:07:23.731298Z","shell.execute_reply":"2025-01-18T09:07:23.850412Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"customers.nunique()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:23.852354Z","iopub.execute_input":"2025-01-18T09:07:23.852591Z","iopub.status.idle":"2025-01-18T09:07:24.891615Z","shell.execute_reply.started":"2025-01-18T09:07:23.852570Z","shell.execute_reply":"2025-01-18T09:07:24.890755Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def tranche_age(age):\n    if age < 20:\n        return 'Moins de 20 ans'\n    elif 20 <= age < 30:\n        return '20-29 ans'\n    elif 30 <= age < 40:\n        return '30-39 ans'\n    elif 40 <= age < 50:\n        return '40-49 ans'\n    elif 50 <= age < 60:\n        return '50-59 ans'\n    else:\n        return '60 ans et plus'\n\ncustomers['tranche_age'] = customers['age'].apply(tranche_age)\n\n# Compter le nombre d'achats par tranche d'âge\nachats_par_tranche = customers['tranche_age'].value_counts()\n\n# Afficher les résultats\nprint(\"Nombre d'achats par tranche d'âge :\")\nprint(achats_par_tranche)\n\n# Visualiser les résultats\nachats_par_tranche.plot(kind='bar', color='blue', title='Nombre d\\'achats par tranche d\\'âge')\nplt.xlabel('Tranche d\\'âge')\nplt.ylabel('Nombre d\\'achats')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:24.892456Z","iopub.execute_input":"2025-01-18T09:07:24.892767Z","iopub.status.idle":"2025-01-18T09:07:25.705293Z","shell.execute_reply.started":"2025-01-18T09:07:24.892720Z","shell.execute_reply":"2025-01-18T09:07:25.704391Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"articles['product_type_name'].value_counts()[:20].plot(kind='barh')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:25.706228Z","iopub.execute_input":"2025-01-18T09:07:25.706545Z","iopub.status.idle":"2025-01-18T09:07:25.969434Z","shell.execute_reply.started":"2025-01-18T09:07:25.706511Z","shell.execute_reply":"2025-01-18T09:07:25.968524Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"articles['product_group_name'].value_counts()[:20].plot(kind='barh')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:25.970352Z","iopub.execute_input":"2025-01-18T09:07:25.970670Z","iopub.status.idle":"2025-01-18T09:07:26.225076Z","shell.execute_reply.started":"2025-01-18T09:07:25.970634Z","shell.execute_reply":"2025-01-18T09:07:26.224211Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"articles['section_name'].value_counts()[:20].plot(kind='barh')  ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:26.225971Z","iopub.execute_input":"2025-01-18T09:07:26.226261Z","iopub.status.idle":"2025-01-18T09:07:26.564798Z","shell.execute_reply.started":"2025-01-18T09:07:26.226236Z","shell.execute_reply":"2025-01-18T09:07:26.563826Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Top 5 des articles les plus chers (Photos avec description et prix)","metadata":{}},{"cell_type":"code","source":"max_price_ids = transactions_train[transactions_train.t_dat==transactions_train.t_dat.max()].sort_values('price', ascending=False).iloc[:5][['article_id', 'price']]\nmin_price_ids = transactions_train[transactions_train.t_dat==transactions_train.t_dat.min()].sort_values('price', ascending=True).iloc[:5][['article_id', 'price']]\n\nf, ax = plt.subplots(1, 5, figsize=(20,10))\ni = 0\nfor _, data in max_price_ids.iterrows():\n    desc = articles[articles['article_id'] == data['article_id']]['detail_desc'].iloc[0]\n    desc_list = desc.split(' ')\n    for j, elem in enumerate(desc_list):\n        if j > 0 and j % 5 == 0:\n            desc_list[j] = desc_list[j] + '\\n'\n    desc = ' '.join(desc_list)\n    img = mpimg.imread(f'../input/h-and-m-personalized-fashion-recommendations/images/0{str(data.article_id)[:2]}/0{int(data.article_id)}.jpg')\n    ax[i].imshow(img)\n    ax[i].set_title(f'price: {data.price:.2f}')\n    ax[i].set_xticks([], [])\n    ax[i].set_yticks([], [])\n    ax[i].grid(False)\n    ax[i].set_xlabel(desc, fontsize=10)\n    i += 1\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:26.565585Z","iopub.execute_input":"2025-01-18T09:07:26.565935Z","iopub.status.idle":"2025-01-18T09:07:35.980664Z","shell.execute_reply.started":"2025-01-18T09:07:26.565896Z","shell.execute_reply":"2025-01-18T09:07:35.979827Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Top 5 des articles les moins chers (Photos avec description et prix)","metadata":{"execution":{"iopub.status.busy":"2025-01-16T19:39:50.621608Z","iopub.execute_input":"2025-01-16T19:39:50.622049Z","iopub.status.idle":"2025-01-16T19:39:50.628356Z","shell.execute_reply.started":"2025-01-16T19:39:50.622013Z","shell.execute_reply":"2025-01-16T19:39:50.626532Z"}}},{"cell_type":"code","source":"f, ax = plt.subplots(1, 5, figsize=(20,10))\ni = 0\nfor _, data in min_price_ids.iterrows():\n    desc = articles[articles['article_id'] == data['article_id']]['detail_desc'].iloc[0]\n    desc_list = desc.split(' ')\n    for j, elem in enumerate(desc_list):\n        if j > 0 and j % 4 == 0:\n            desc_list[j] = desc_list[j] + '\\n'\n    desc = ' '.join(desc_list)\n    img = mpimg.imread(f'../input/h-and-m-personalized-fashion-recommendations/images/0{str(data.article_id)[:2]}/0{int(data.article_id)}.jpg')\n    ax[i].imshow(img)\n    ax[i].set_title(f'price: {data.price:.4f}')\n    ax[i].set_xlabel(desc, fontsize=10)\n    ax[i].set_xticks([], [])\n    ax[i].set_yticks([], [])\n    ax[i].grid(False)\n    i += 1\nplt.axis('off')\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:35.981689Z","iopub.execute_input":"2025-01-18T09:07:35.982016Z","iopub.status.idle":"2025-01-18T09:07:37.479699Z","shell.execute_reply.started":"2025-01-18T09:07:35.981991Z","shell.execute_reply":"2025-01-18T09:07:37.478811Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Recommendation System Using Cosine Similarity**","metadata":{}},{"cell_type":"code","source":"# Chargement des données\ndata = transactions_train.head(10000)  \npurchase_matrix = data.pivot_table(index='customer_id', columns='article_id', aggfunc='size', fill_value=0)  # Supposons que les colonnes soient 'customer_id' et 'product_id' \nsimilarity_matrix = cosine_similarity(purchase_matrix)  # Calcul de la similarité cosinus \nsimilarity_df = pd.DataFrame(similarity_matrix, index=purchase_matrix.index, columns=purchase_matrix.index)  # Création d'un DataFrame pour la similarité \n\ndef recommend_products(customer_id, n_recommendations=5): \n    if customer_id not in similarity_df.index:\n        return []  # Retourne une liste vide si le client n'existe pas\n    \n    similar_scores = similarity_df[customer_id]  # Obtenir les scores de similarité pour le client donné \n    similar_customers = similar_scores.sort_values(ascending=False).index[1:]  # Trier les clients par score de similarité \n    recommended_products = [] \n    \n    for similar_customer in similar_customers: \n        products = purchase_matrix.loc[similar_customer][purchase_matrix.loc[similar_customer] > 0].index.tolist() \n        recommended_products.extend(products) \n        if len(recommended_products) >= n_recommendations: \n            break \n    \n    return list(set(recommended_products))[:n_recommendations]  # Retourner les produits recommandés sans doublons \n\ncustomer_id_example = \"001ea4e9c54f7e9c88811260d954edc059d596147e1cf8adc73323aebf571fd8\"\nrecommended_items = recommend_products(customer_id_example) \n\nprint(f\"Produits recommandés pour le client n° {customer_id_example}: {recommended_items}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:37.480606Z","iopub.execute_input":"2025-01-18T09:07:37.480875Z","iopub.status.idle":"2025-01-18T09:07:38.200184Z","shell.execute_reply.started":"2025-01-18T09:07:37.480854Z","shell.execute_reply":"2025-01-18T09:07:38.199393Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# **Les produits recommandés pour le client n° 001ea4e9c54f7e9c88811260d954edc059d596147e1cf8adc73323aebf571fd8 sont: 557248001, 557248009, 534181007, 624006001, 387843036.**","metadata":{}},{"cell_type":"code","source":"img_1 = mpimg.imread('/kaggle/input/h-and-m-personalized-fashion-recommendations/images/055/0557248001.jpg') \nimg_2 = mpimg.imread('/kaggle/input/h-and-m-personalized-fashion-recommendations/images/055/0557248009.jpg') \nimg_3 = mpimg.imread('/kaggle/input/h-and-m-personalized-fashion-recommendations/images/053/0534181007.jpg') \nimg_4 = mpimg.imread('/kaggle/input/h-and-m-personalized-fashion-recommendations/images/062/0624006001.jpg') \nimg_5 = mpimg.imread('/kaggle/input/h-and-m-personalized-fashion-recommendations/images/038/0387843036.jpg') \n# Titres pour chaque image\ntitles = ['Id = 557248001', 'Id = 557248009', 'Id = 534181007', 'Id = 624006001', 'Id = 387843036']\n# Création de la figure et des axes\nfig, axs = plt.subplots(1, 5, figsize=(15, 5))\n\n# Affichage des images\nfor ax, img, title in zip(axs, [img_1, img_2, img_3, img_4, img_5],titles):\n    ax.imshow(img)\n    ax.set_title(title)  # Ajout du titre à chaque image\n    ax.axis('off')  # Masquer les axes\n\nplt.tight_layout()  # Ajuste l'espacement\nplt.show()  # Afficher les images","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:07:38.201090Z","iopub.execute_input":"2025-01-18T09:07:38.201418Z","iopub.status.idle":"2025-01-18T09:07:39.808661Z","shell.execute_reply.started":"2025-01-18T09:07:38.201384Z","shell.execute_reply":"2025-01-18T09:07:39.807599Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.metrics import precision_score, recall_score, f1_score\n\n# Simulated test dataset with customer purchase history (ground truth)\n# Format: {customer_id: [list_of_actual_purchases]}\nground_truth = {\n    \"001ea4e9c54f7e9c88811260d954edc059d596147e1cf8adc73323aebf571fd8\": [\"P1\", \"P2\", \"P3\"],\n    \"002f4e6c51d5f8c123456789abcdef9876543210fedcba0987654321fedcba00\": [\"P4\", \"P5\"],\n    \"003abcde000123456789fedcba9876543210fedcba9876543210fedcba987654\": [\"P6\", \"P7\", \"P8\", \"P9\"]\n}\n\n# Recommendations generated by the system\n# Format: {customer_id: [list_of_recommended_products]}\nrecommendations = {\n    \"001ea4e9c54f7e9c88811260d954edc059d596147e1cf8adc73323aebf571fd8\": [\"P2\", \"P4\", \"P6\"],\n    \"002f4e6c51d5f8c123456789abcdef9876543210fedcba0987654321fedcba00\": [\"P5\", \"P8\"],\n    \"003abcde000123456789fedcba9876543210fedcba9876543210fedcba987654\": [\"P10\", \"P8\", \"P9\"]\n}\n\n# Function to calculate precision, recall, and F1-score\ndef evaluate_recommendations(ground_truth, recommendations):\n    all_precisions = []\n    all_recalls = []\n    all_f1s = []\n\n    for customer_id, actual_purchases in ground_truth.items():\n        recommended_products = recommendations.get(customer_id, [])\n\n        # Convert to sets for easier comparison\n        actual_set = set(actual_purchases)\n        recommended_set = set(recommended_products)\n\n        # Calculate precision, recall, and F1 for each customer\n        true_positives = len(actual_set & recommended_set)  # Intersection of actual and recommended\n        precision = true_positives / len(recommended_set) if recommended_set else 0\n        recall = true_positives / len(actual_set) if actual_set else 0\n        f1 = (2 * precision * recall) / (precision + recall) if precision + recall > 0 else 0\n\n        all_precisions.append(precision)\n        all_recalls.append(recall)\n        all_f1s.append(f1)\n\n    # Calculate averages across all customers\n    avg_precision = sum(all_precisions) / len(all_precisions)\n    avg_recall = sum(all_recalls) / len(all_recalls)\n    avg_f1 = sum(all_f1s) / len(all_f1s)\n\n    return avg_precision, avg_recall, avg_f1\n\n# Evaluate the recommendations\navg_precision, avg_recall, avg_f1 = evaluate_recommendations(ground_truth, recommendations)\n\nprint(f\"Average Precision: {avg_precision:.2f}\")\nprint(f\"Average Recall: {avg_recall:.2f}\")\nprint(f\"Average F1-Score: {avg_f1:.2f}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:08:04.895222Z","iopub.execute_input":"2025-01-18T09:08:04.895544Z","iopub.status.idle":"2025-01-18T09:08:04.903751Z","shell.execute_reply.started":"2025-01-18T09:08:04.895520Z","shell.execute_reply":"2025-01-18T09:08:04.902800Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nfrom sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay\n\n# Simulated test dataset with customer purchase history (ground truth)\nground_truth = {\n    \"001ea4e9c54f7e9c88811260d954edc059d596147e1cf8adc73323aebf571fd8\": [\"P1\", \"P2\", \"P3\"],\n    \"002f4e6c51d5f8c123456789abcdef9876543210fedcba0987654321fedcba00\": [\"P4\", \"P5\"],\n    \"003abcde000123456789fedcba9876543210fedcba9876543210fedcba987654\": [\"P6\", \"P7\", \"P8\", \"P9\"]\n}\n\n# Recommendations generated by the system\nrecommendations = {\n    \"001ea4e9c54f7e9c88811260d954edc059d596147e1cf8adc73323aebf571fd8\": [\"P2\", \"P4\", \"P6\"],\n    \"002f4e6c51d5f8c123456789abcdef9876543210fedcba0987654321fedcba00\": [\"P5\", \"P8\"],\n    \"003abcde000123456789fedcba9876543210fedcba9876543210fedcba987654\": [\"P10\", \"P8\", \"P9\"]\n}\n\n# Generate the binary vectors for confusion matrix\nall_items = set()  # Collect all unique items across ground truth and recommendations\nfor purchases in ground_truth.values():\n    all_items.update(purchases)\nfor recs in recommendations.values():\n    all_items.update(recs)\n\nall_items = sorted(all_items)  # Sorted list of all unique items\nitem_index = {item: idx for idx, item in enumerate(all_items)}\n\n# Prepare y_true (actual purchases) and y_pred (recommended items)\ny_true = np.zeros(len(all_items))\ny_pred = np.zeros(len(all_items))\n\nfor customer_id, purchases in ground_truth.items():\n    for item in purchases:\n        y_true[item_index[item]] = 1  # Mark actual purchases as 1\n    recommended_items = recommendations.get(customer_id, [])\n    for item in recommended_items:\n        y_pred[item_index[item]] = 1  # Mark recommended items as 1\n\n# Compute confusion matrix\ncm = confusion_matrix(y_true, y_pred)\n\n# Plot confusion matrix\ndisp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=[\"Not Recommended\", \"Recommended\"])\ndisp.plot(cmap=plt.cm.Blues)\nplt.title(\"Confusion Matrix for Recommendation System\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:08:51.257097Z","iopub.execute_input":"2025-01-18T09:08:51.257403Z","iopub.status.idle":"2025-01-18T09:08:51.430506Z","shell.execute_reply.started":"2025-01-18T09:08:51.257380Z","shell.execute_reply":"2025-01-18T09:08:51.429782Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Function to calculate precision, recall, and F1-score for each customer\ndef evaluate_recommendations_per_customer(ground_truth, recommendations):\n    results = {}\n\n    for customer_id, actual_purchases in ground_truth.items():\n        recommended_products = recommendations.get(customer_id, [])\n\n        # Convert to sets for easier comparison\n        actual_set = set(actual_purchases)\n        recommended_set = set(recommended_products)\n\n        # Calculate precision, recall, and F1 for each customer\n        true_positives = len(actual_set & recommended_set)  # Intersection of actual and recommended\n        precision = true_positives / len(recommended_set) if recommended_set else 0\n        recall = true_positives / len(actual_set) if actual_set else 0\n        f1 = (2 * precision * recall) / (precision + recall) if precision + recall > 0 else 0\n\n        results[customer_id] = {\n            \"precision\": precision,\n            \"recall\": recall,\n            \"f1_score\": f1\n        }\n\n    return results\n\n# Evaluate the recommendations per customer\ncustomer_results = evaluate_recommendations_per_customer(ground_truth, recommendations)\n\n# Display the results for each customer\nfor customer_id, metrics in customer_results.items():\n    print(f\"Customer ID: {customer_id}\")\n    print(f\"  Precision: {metrics['precision']:.2f}\")\n    print(f\"  Recall: {metrics['recall']:.2f}\")\n    print(f\"  F1-Score: {metrics['f1_score']:.2f}\")\n    print()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:24:39.890491Z","iopub.execute_input":"2025-01-18T09:24:39.890872Z","iopub.status.idle":"2025-01-18T09:24:39.899622Z","shell.execute_reply.started":"2025-01-18T09:24:39.890843Z","shell.execute_reply":"2025-01-18T09:24:39.898895Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nfrom sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay\n\n# Combine all actual and recommended products into a single list\nall_items = set()\nfor purchases in ground_truth.values():\n    all_items.update(purchases)\nfor recs in recommendations.values():\n    all_items.update(recs)\n\nall_items = sorted(all_items)  # Unique list of all products\nitem_index = {item: idx for idx, item in enumerate(all_items)}\n\n# Prepare binary ground truth (y_true) and predictions (y_pred) for the confusion matrix\ny_true = []\ny_pred = []\n\nfor customer_id, actual_purchases in ground_truth.items():\n    recommended_products = recommendations.get(customer_id, [])\n    actual_set = set(actual_purchases)\n    recommended_set = set(recommended_products)\n\n    for item in all_items:\n        y_true.append(1 if item in actual_set else 0)\n        y_pred.append(1 if item in recommended_set else 0)\n\n# Compute confusion matrix\ncm = confusion_matrix(y_true, y_pred)\n\n# Plot confusion matrix\ndisp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=[\"Not Purchased\", \"Purchased\"])\ndisp.plot(cmap=plt.cm.Blues)\nplt.title(\"Confusion Matrix for Recommendation System\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-18T09:25:09.618051Z","iopub.execute_input":"2025-01-18T09:25:09.618340Z","iopub.status.idle":"2025-01-18T09:25:09.788612Z","shell.execute_reply.started":"2025-01-18T09:25:09.618318Z","shell.execute_reply":"2025-01-18T09:25:09.787828Z"}},"outputs":[],"execution_count":null}]}