Spaces:
Sleeping
Sleeping
| import pickle | |
| import streamlit as st | |
| from html_information2 import html2 | |
| st.set_page_config(page_title="My App", page_icon=":money_with_wings:", layout="wide", initial_sidebar_state="auto") | |
| st.header("Frequently Bought Together Recommendations") | |
| def read_pickle_files(pickle_file): | |
| with open(pickle_file, 'rb') as f: | |
| return pickle.load(f) | |
| # Load sephora pickle files | |
| corrected_fp_growth_results_sephora = read_pickle_files("sephora_corrected_fp_growth_results_cleaned.pkl") | |
| all_products_with_names_sephora = read_pickle_files ("item_catalog.pkl") | |
| dictionary_of_transactions_sephora = read_pickle_files("transaction_metadata.pkl") | |
| images_sephora = read_pickle_files("uid_url_map.pkl") | |
| item_costs_sephora_data = read_pickle_files("wavg_item_costs_sephora.pkl") | |
| # Load digital pickle files | |
| corrected_fp_growth_results = read_pickle_files("corrected_fp_growth_results.pkl") | |
| all_products_with_names = read_pickle_files ("all_products_with_names.pkl") | |
| dictionary_of_transactions = read_pickle_files("reliance_digital_transactions.pkl") | |
| item_costs_digital_data = read_pickle_files("avg_item_costs_reliance_digital_wa.pkl") | |
| # Dropdown for selecting the dataset | |
| dataset_choice = st.selectbox( | |
| "Select A Dataset", | |
| ["Sephora Order Complete Dataset", "Reliance Digital Order Complete Dataset"] | |
| ) | |
| if dataset_choice == "Sephora Order Complete Dataset": | |
| list_of_products_to_display = {} | |
| for itemid in (list(all_products_with_names_sephora.keys())): #for items in the total list of items in all transactions | |
| if itemid in (list(corrected_fp_growth_results_sephora.keys())): #if the item has a result from fp-growth | |
| list_of_products_to_display[itemid]= all_products_with_names_sephora[itemid] #show it in the drop down menu | |
| name_to_id = {name: product_id for product_id, name in list_of_products_to_display.items()} # Reverse the dictionary to map product names to IDs | |
| selected_product_name = st.selectbox('Select A Product:', list(name_to_id.keys())) # Create a dropdown menu with the product names | |
| # Get the corresponding product_id | |
| query_id = name_to_id[selected_product_name] | |
| url = "https://www.sephora.com/" | |
| st.write("Created using the clickstream order-completed and catalog data from [Sephora.com](%s)" % url) | |
| st.write("Cost of chosen item:", str(round(item_costs_sephora_data[query_id], 2))) | |
| query_url = images_sephora[int(query_id)] | |
| st.image(query_url, width=500) | |
| if dataset_choice == "Reliance Digital Order Complete Dataset": | |
| list_of_products_to_display = {} | |
| for itemid in (list(all_products_with_names.keys())): #for items in the total list of items in all transactions | |
| if itemid[0:3]!="600": | |
| if itemid in (list(corrected_fp_growth_results.keys())): #if the item has a result from fp-growth | |
| list_of_products_to_display[itemid]= all_products_with_names[itemid] #show it in the drop down menu | |
| name_to_id = {name: product_id for product_id, name in list_of_products_to_display.items()} # Reverse the dictionary to map product names to IDs | |
| selected_product_name = st.selectbox('Select A Product:', list(name_to_id.keys())) # Create a dropdown menu with the product names | |
| # Get the corresponding product_id | |
| query_id = name_to_id[selected_product_name] | |
| url = "https://www.reliancedigital.in/" | |
| st.write("Created using the clickstream order-completed data from [reliancedigital.com](%s)" % url) | |
| st.write("An item is only recommended if it costs less than the chosen item.") | |
| st.write("Cost of chosen item:", str(round(item_costs_digital_data[query_id], 2))) | |
| # Inject custom CSS for the tab headings | |
| st.markdown( | |
| """ | |
| <style> | |
| /* Style the tab container */ | |
| div[data-testid="stTabs"] button { | |
| background-color: #e0e0e0; /* Light grey background */ | |
| color: #333333; /* Dark grey text color */ | |
| font-size: 18px; /* Increase font size */ | |
| font-weight: bold; /* Make text bold */ | |
| padding: 10px 20px; /* Add some padding to the tabs */ | |
| border-radius: 10px; /* Rounded corners */ | |
| border: none; /* Remove default border */ | |
| margin: 5px; /* Add margin between tabs */ | |
| transition: background-color 0.3s ease; /* Add hover effect */ | |
| } | |
| /* Hover effect for tabs */ | |
| div[data-testid="stTabs"] button:hover { | |
| background-color: #b0b0b0; /* Darker grey on hover */ | |
| color: #333333; /* Keep text color the same */ | |
| } | |
| /* Active tab styling */ | |
| div[data-testid="stTabs"] button[aria-selected="true"] { | |
| background-color: #808080; /* Dark grey for active tab */ | |
| color: white; /* White text for active tab */ | |
| font-size: 20px; /* Larger font size for active tab */ | |
| } | |
| </style> | |
| """, | |
| unsafe_allow_html=True | |
| ) | |
| tab2, tab3 = st.tabs(["Frequently Bought Together Demo", "Historical Order Data"]) | |
| with tab2: | |
| if dataset_choice == "Sephora Order Complete Dataset": | |
| if query_id in corrected_fp_growth_results_sephora: | |
| # Separate the sorted items into IDs and counts | |
| item_ids = [item for item in corrected_fp_growth_results_sephora[query_id]] | |
| item_counts = [corrected_fp_growth_results_sephora[query_id][item] for item in corrected_fp_growth_results_sephora[query_id]] | |
| item_costs_sephora = [item_costs_sephora_data.get(item, "cost missing") for item in corrected_fp_growth_results_sephora[query_id]] | |
| item_image = [] | |
| for item in corrected_fp_growth_results_sephora[query_id]: | |
| try: | |
| # Attempt to retrieve the image URL | |
| image_url = images_sephora[int(item)] | |
| if not image_url: # If the URL is empty or None, skip it | |
| raise ValueError("Empty image URL") | |
| item_image.append(image_url) | |
| except (KeyError, ValueError, TypeError): | |
| # Handle missing or invalid image URLs by appending a default image URL | |
| item_image.append("default_image_url") | |
| confidence_list = [] | |
| transactions_list_sephora = [] | |
| for i in dictionary_of_transactions_sephora: | |
| transactions_list_sephora.append(i["transaction"]) | |
| transactions_with_query_item = len([transaction for transaction in transactions_list_sephora if int(query_id) in transaction]) | |
| copurchase_count = [] | |
| # Generate a list of product names to display | |
| product_names = [] | |
| for each_item in corrected_fp_growth_results_sephora[query_id]: | |
| product_names.append(all_products_with_names_sephora.get(each_item, "Unknown Product")) | |
| for recommended_item in item_ids: | |
| transactions_with_item_and_query_item = [] | |
| transactions_with_item_and_query_item.extend([transaction for transaction in transactions_list_sephora if (int(recommended_item) in transaction) and (int(query_id) in transaction)]) | |
| number_of_transactions_with_recommended_item_and_query_item = len(transactions_with_item_and_query_item) | |
| copurchase_count.append(number_of_transactions_with_recommended_item_and_query_item) | |
| confidence_list.append(number_of_transactions_with_recommended_item_and_query_item / transactions_with_query_item) | |
| mid_section = "" | |
| for index, value in enumerate(product_names): | |
| count_info = f"Co-purchased {copurchase_count[index]}/{transactions_with_query_item} times" | |
| item_counts_info = f"item-count {item_counts[index]} " | |
| confidence_info = f"Confidence: {round(confidence_list[index], 3)}" | |
| item_cost_info_sephora = f"Cost: {round(item_costs_sephora[index],2)}" | |
| # Use <br> to display each line separately | |
| mid_section += f"""<div class="item"> | |
| <div id="image-container"><img src='{item_image[index]}' /></div> | |
| <p style="font-size: 16px; font-weight: bold; white-space: normal; word-wrap: break-word;">{str(product_names[index])}</p> | |
| <p>{count_info}<br>{confidence_info}<br>{item_cost_info_sephora}</p> | |
| </div>""" | |
| mid_html = html2 + mid_section + """</div></div></body>""" | |
| st.markdown(mid_html, unsafe_allow_html=True) | |
| else: | |
| st.write("No frequent purchases found for this item.") | |
| if dataset_choice == "Reliance Digital Order Complete Dataset": | |
| if query_id in corrected_fp_growth_results: | |
| # Separate the sorted items into IDs and counts | |
| item_ids = [item for item in corrected_fp_growth_results[query_id]] | |
| item_counts = [corrected_fp_growth_results[query_id][item] for item in corrected_fp_growth_results[query_id]] | |
| item_costs = [item_costs_digital_data.get(item, "cost missing") for item in corrected_fp_growth_results[query_id]] | |
| no_image = "https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg" | |
| confidence_list = [] | |
| transactions_list_digital = [] | |
| for i in dictionary_of_transactions: | |
| transactions_list_digital.append(i["transaction"]) | |
| transactions_with_querry_item = len([transaction for transaction in transactions_list_digital if query_id in transaction]) | |
| copurchase_count = [] | |
| # Generate a list of product names to display | |
| product_names = [] | |
| for each_item in corrected_fp_growth_results[query_id]: | |
| product_names.append(all_products_with_names[each_item]) | |
| for reccomended_item in item_ids: | |
| transactions_with_item_and_query_item = [] | |
| transactions_with_item_and_query_item.extend([transaction for transaction in transactions_list_digital if (reccomended_item in transaction) and (query_id in transaction)]) | |
| number_of_transactions_with_reccomended_item_and_query_item = len(transactions_with_item_and_query_item) | |
| copurchase_count.append(number_of_transactions_with_reccomended_item_and_query_item) | |
| confidence_list.append(number_of_transactions_with_reccomended_item_and_query_item/transactions_with_querry_item) | |
| mid_section = "" | |
| for index, value in enumerate(product_names): | |
| count_info = f"Co-purchased {copurchase_count[index]}/{transactions_with_querry_item} times" | |
| item_counts_info = f"item-count {item_counts[index]} " | |
| confidence_info = f"Confidence: {round(confidence_list[index], 3)}" | |
| item_cost_info = f"Cost: {round(item_costs[index],3)}" | |
| # Use <br> to display each line separately | |
| mid_section += f"""<div class="item"> | |
| <div id="image-container"><img src='{no_image}' /></div> | |
| <p style="font-size: 16px; font-weight: bold; white-space: normal; word-wrap: break-word;">{str(product_names[index])}</p> | |
| <p>{count_info}<br>{confidence_info}<br>{item_cost_info}</p> | |
| </div>""" | |
| mid_html = html2 + mid_section + """</div></div></body>""" | |
| st.markdown(mid_html, unsafe_allow_html=True) | |
| else: | |
| st.write("No frequent purchases found for this item.") | |
| with tab3: # historical transactions tab | |
| if dataset_choice == "Sephora Order Complete Dataset": | |
| st.subheader("Historical Transactions With Chosen Product (shows maximum 20)") | |
| example_transactions = [] | |
| for transaction_dict in dictionary_of_transactions_sephora: | |
| if int(query_id) in transaction_dict["transaction"]: | |
| example_transactions.append(transaction_dict) | |
| if example_transactions: | |
| # Begin constructing the carousel for transactions | |
| for i, transaction in enumerate(example_transactions): | |
| st.markdown(f"**Transaction {i+1}:** Placed on {transaction['event_timestamp']} by {transaction['user_id']}", unsafe_allow_html=True) | |
| transaction_names = [all_products_with_names_sephora.get(str(item), "Unknown Product") for item in transaction["transaction"]] | |
| no_image = "https://upload.wikimedia.org/wikipedia/commons/6/65/No-Image-Placeholder.svg" | |
| item_images = [] | |
| for item in corrected_fp_growth_results_sephora.get(query_id, []): | |
| try: | |
| # Attempt to retrieve the image URL | |
| image_url = images_sephora[int(item)] | |
| if not image_url: # If the URL is empty or None, skip it | |
| raise ValueError("Empty image URL") | |
| item_images.append(image_url) | |
| except (KeyError, ValueError, TypeError): | |
| # Handle missing or invalid image URLs by appending a default image URL | |
| item_images.append("default_image_url") | |
| # Ensure item_images and transaction_names are of the same length | |
| if len(item_images) > len(transaction_names): | |
| item_images = item_images[:len(transaction_names)] | |
| elif len(item_images) < len(transaction_names): | |
| item_images.extend(["default_image_url"] * (len(transaction_names) - len(item_images))) | |
| # Build the HTML for displaying the transaction in a carousel format | |
| transaction_section = "" | |
| for index, image_url in enumerate(item_images): | |
| transaction_section += f"""<div class="item"> | |
| <div id="image-container"><img src='{image_url}' /></div> | |
| <p style="font-size: 16px; font-weight: bold; white-space: normal; word-wrap: break-word;">{transaction_names[index]}</p> | |
| </div>""" | |
| # Complete the carousel HTML structure | |
| transaction_html = html2 + transaction_section + """</div></div></body>""" | |
| # Render the carousel for each transaction | |
| st.markdown(transaction_html, unsafe_allow_html=True) | |
| else: | |
| st.write("No transactions found for this item.") | |
| if dataset_choice == "Reliance Digital Order Complete Dataset": | |
| st.subheader("Historical Transactions With Chosen Product (shows maximum 20)") | |
| example_transactions = [] | |
| for transaction_dict in dictionary_of_transactions: | |
| if query_id in transaction_dict["transaction"]: | |
| example_transactions.append(transaction_dict) | |
| if example_transactions: | |
| # Begin constructing the carousel for transactions | |
| for i, transaction in enumerate(example_transactions): | |
| st.markdown(f"**Transaction {i+1}:** Placed on {transaction['order_date']} by {transaction['customer_id']} from {transaction['delivery_city']}", unsafe_allow_html=True) | |
| transaction_names = [] | |
| for i in transaction["transaction"]: | |
| transaction_names = [all_products_with_names.get(str(item), "Unknown Product") for item in transaction["transaction"]] | |
| # Build the HTML for displaying the transaction in a carousel format | |
| transaction_section = "" | |
| for index, image_url in enumerate(transaction_names): | |
| transaction_section += f"""<div class="item"> | |
| <div id="image-container"><img src='{no_image}' /></div> | |
| <p style="font-size: 16px; font-weight: bold; white-space: normal; word-wrap: break-word;">{str(transaction_names[index])}</p> | |
| </div>""" | |
| # Complete the carousel HTML structure | |
| transaction_html = html2 + transaction_section + """</div></div></body>""" | |
| # Render the carousel for each transaction | |
| st.markdown(transaction_html, unsafe_allow_html=True) | |
| else: | |
| st.write("No transactions found for this item.") | |
| # Inject custom CSS for the 'Know More' button | |
| st.markdown( | |
| """ | |
| <style> | |
| .know-more-button { | |
| background-color: #808080; /* Dark grey background */ | |
| color: white !important; /* Force white text color */ | |
| font-size: 18px; /* Font size */ | |
| font-weight: bold; /* Bold text */ | |
| padding: 10px 20px; /* Padding */ | |
| border-radius: 10px; /* Rounded corners */ | |
| border: none; /* Remove default border */ | |
| cursor: pointer; /* Mouse pointer */ | |
| text-align: center; | |
| text-decoration: none; /* Remove underline */ | |
| display: inline-block; /* Make it inline */ | |
| transition: background-color 0.3s ease; | |
| } | |
| .know-more-button:hover { | |
| background-color: #b0b0b0; /* Lighter grey background on hover */ | |
| color: #333333 !important; /* Dark grey text on hover */ | |
| text-decoration: none; /* Keep underline removed on hover */ | |
| } | |
| </style> | |
| """, | |
| unsafe_allow_html=True | |
| ) | |
| # Add the 'Know More' button with the link and no underline | |
| st.markdown( | |
| '<a href="https://gofynd.quip.com/fOONA5yDkSr2/Frequently-Bought-Together-Recommendations" class="know-more-button">Know More</a>', | |
| unsafe_allow_html=True | |
| ) | |