ArunSR/Product-RecSys
0
1import streamlit as st2import re3import altair as alt4st.set_page_config('Product Recommendation Application', layout='wide')5 6# Functions/Pages7def intro():8 import streamlit as st9 10 st.markdown("## Welcome to the Product Recommendation Application! ๐")11 st.sidebar.success("Select a page from above.")12 13 st.markdown(14 """15 **๐ Select a page from the navigation bar to the left**16 17### Functionality of Pages18#### Generate Recommendations Page19- This page allows you to generate recommendations for a particular keyword/publisherid combo.20- The recommendations for each keyword/publisherid combo, are stored in a separate SQLite Database Table.21- Ideally, for each keyword/publisherid combo, the recommendations should only be generated once per day. To mock this, you are only allowed to generate recommendations for a specific keyword/publisherid combo once.22#### Product Recommendations Page23- This page displays the Product Recommendations for each keyword/publisherid combo for which the recommendations were generated in the previous page.24- You can currently select the available keywords from the dropdown provided in the side bar.25- For the time being, the Publisher ID is restricted to a single known value. This can be easily updated later.26- Note: Since the click tracker I was using had issues, as a workaround I had to use a Button instead. So now, to register a click against a product, you need to click on the 'Select' button provided below each product. 27- For each session, once a product is clicked on, it is no longer displayed.28- You can choose the number of recommendations to be displayed, between 1 & 5.29- The maximum number of recommendations that are available for display for each keyword/publisherid combo is restricted to 50.30- The minumum number depends on the products available from bizrate.31- If/when all available recommendations for a keyword/publisherid combo has been clicked on, you can either choose a different keyword, reload the application or navigate to a different page. The last two options creates a new session.32#### Analytics Page33- Displays a Line Chart and a Bar Chart, to show the distribution of clicks across Session ID, Keyword, Publisher ID, SKU or Date.34- Displays a table of the most clicked SKU's35 """36 )37 38def generate_recommendations():39 import os40 import string41 import random42 import streamlit as st43 import warnings44 warnings.filterwarnings('ignore')45 46 # custom module47 #from clickcounter import clickcounter48 from folder_management import create_folder, remove_files_folder49 from sqlite_database import create_insert_table, query_table, insert_clickdata_table, check_for_table50 from recommend import query_bizrate, recommend51 52 # Functions53 def random_string(N=7):54 res = ''.join(random.choices(string.ascii_lowercase + string.digits, k=N))55 return str(res)56 57 def query_and_recommend(keyword, publisherid):58 query_bizrate(keyword, publisherid)59 recommend(keyword, publisherid)60 61 # Main Program62 # st.set_page_config('Generate Recommendations', layout='wide')63 64 st.title('Generate Recommendations')65 st.markdown('''<pre style="text-align:center">66 <strong><span style="color:#6a8759">67 Generate Recommendations for any Keyword - Publisher ID Combo. <br><br> </span></strong></pre>''',68 unsafe_allow_html=True)69 70 col1, col2 = st.columns(2)71 72 selected_keyword = ''73 publisher_id = ''74 75 with col1:76 selected_keyword = st.text_input('Enter a single word as keyword:', 'aquaman')77 selected_keyword = selected_keyword.lower()78 selected_keyword = ''.join(re.split(r"[ \|\\\/,.-]", selected_keyword))79 #selected_keyword = ''.join(selected_keyword.split())80 st.write(selected_keyword)81 82 with col2:83 publisher_id = st.text_input("Enter a Publisher ID: ", '725895')84 # st.write(publisher_id)85 86 keyword_pubid_list = []87 for file in os.listdir('bizrate'):88 keyword_pubid_list.append(file.replace(".xml", ""))89 90 if selected_keyword + "_" + publisher_id in keyword_pubid_list:91 st.error('Keyword - Publisher ID Combo Exists!')92 else:93 st.info("Keyword - Publisher ID Combo doesn't exist. Must be queried")94 st.button('Generate Recommendations', key=random_string(), on_click=query_and_recommend,95 args=([selected_keyword, publisher_id]))96 97def display_recommendations():98 import pandas as pd99 import numpy as np100 import requests101 from bs4 import BeautifulSoup102 import urllib.parse103 import os104 import string105 import random106 107 import time108 109 import streamlit as st110 import uuid111 112 import warnings113 import sys114 115 warnings.filterwarnings('ignore')116 117 # custom module118 # from clickcounter import clickcounter119 from folder_management import create_folder, remove_files_folder120 from sqlite_database import create_insert_table, query_table, insert_clickdata_table, check_for_table121 122 # Functions123 def random_string(N=7):124 res = ''.join(random.choices(string.ascii_lowercase + string.digits, k=N))125 return str(res)126 127 # def display_products(dfp):128 # product_list = list(dfp['title'])129 # image_list = list(dfp['Image'])130 # price_list = list(dfp['price'])131 # org_price = list(dfp['originalPrice'])132 # disc_list = list(dfp['markdownPercent'])133 # dfp['Skus'] = dfp['Skus'].astype('object')134 # sku_list = list(dfp['Skus'])135 # url_list = list(dfp['url'])136 # clicked_sku, counter_dict = clickcounter(image_list, sku_list, price_list, disc_list, org_price, url_list, product_list)137 # return clicked_sku, counter_dict138 139 # Main Program140 #st.set_page_config('Product Recommender System', layout='wide')141 st.title('Product Recommender System')142 st.markdown('''<pre style="text-align:center">143 <strong><span style="color:#6a8759">144 It will take as inputs: Keyword and Publisher ID. 145 Displays (upto) Top 5 Recommendations & Collects Click Information. <br><br> </span></strong></pre>''',146 unsafe_allow_html=True)147 148 # Generating Session ID:149 if 'store' not in st.session_state:150 st.session_state.store = False151 152 try:153 df_session = pd.read_excel('df_session.xlsx')154 df_row = pd.DataFrame({'ID': uuid.uuid4()}, index=[0])155 df_session = pd.concat([df_session, df_row], ignore_index=True)156 df_session.to_excel('df_session.xlsx', index=False)157 df_sku = pd.DataFrame({'SessionID': pd.Series(dtype='object'), 'Keyword': pd.Series(dtype='object'),158 'Skus': pd.Series(dtype='object'),159 'Count': pd.Series(dtype='int')}) # Initializing the SKU-Count DataFrame160 df_sku.to_excel('df_sku.xlsx', index=False)161 162 except FileNotFoundError:163 df_session = pd.DataFrame({'ID': uuid.uuid4()}, index=[0]) # Initializing the SKU-Count DataFrame164 df_session.to_excel('df_session.xlsx', index=False)165 166 df_session = pd.read_excel('df_session.xlsx')167 session_id = list(df_session['ID'])[-1]168 # st.sidebar.write(session_id) # Uncomment to display the Session ID169 170 # Inputs171 172 # selected_keyword = st.sidebar.text_input("Enter a single word as Keyword: ", 'aquaman')173 # publisher_id = st.sidebar.text_input("Enter Publisher ID: ", '725895')174 list_keywords = []175 list_publisherid = []176 for file in os.listdir('bizrate'):177 keyword_publisherid = file.replace(".xml", "")178 list_keywords.append(keyword_publisherid.split("_")[0])179 list_publisherid.append(keyword_publisherid.split("_")[1])180 # list_keywords = ['aquaman', 'superman', 'batman', 'shoes', 'electronics', 'wallet', 'movies', 'books'] # Temporary181 list_publisherid = ['725895'] # For the time being Publisher ID is being HardCoded.182 selected_keyword = st.sidebar.selectbox("Select a Keyword:", set(list_keywords))183 publisher_id = st.sidebar.selectbox("Select a Publisher ID:", set(list_publisherid))184 185 # st.write(selected_keyword)186 # st.write(publisher_id)187 188 # Query Recommended Data as per Keyword and Publisher ID189 190 try:191 rec_df = query_table('RecSysData', selected_keyword + "_" + publisher_id)192 except pd.errors.DatabaseError:193 # st.error('This Keyword Publisher ID Combo Doesnt Exist!')194 rec_df = pd.DataFrame({}, columns=['title', 'Brand', 'url', 'Image', 'Skus', 'price', 'originalPrice',195 'markdownPercent', 'totalPrice', 'condition', 'stock', 'relevancy'])196 197 # Logic to Decide which SKU's to Display198 199 # 1. If a SKU has already been clicked on. It cannot be displayed again.200 201 try:202 click_data_df = query_table('session_data', 'session_data')203 204 if click_data_df.empty:205 df_top_rec = rec_df.head(5)206 else:207 displayed_skus = list(click_data_df[click_data_df['session_id'] == session_id][208 'Skus']) # List of SKU's already displayed in the current session209 # st.write(displayed_skus)210 rec_df = rec_df[~rec_df['Skus'].isin(displayed_skus)]211 except pd.errors.DatabaseError as e:212 print(e)213 214 # Top 5 Recommendations215 #top_df = rec_df.head(5).reset_index()216 top_df = rec_df.sample(5).reset_index() # random 5 recommendations217 218 recs_to_display = 0219 if len(top_df) > 5:220 recs_to_display = st.sidebar.slider('Recommendations to Display', 1, 5)221 elif len(top_df) > 1:222 recs_to_display = st.sidebar.slider('Recommendations to Display', 1, len(top_df), len(top_df))223 else:224 recs_to_display = 1225 226 # recs_to_display image width dictionary227 image_width_dictionary = {228 5: 200,229 4: 240,230 3: 280,231 2: 320,232 1: 400}233 234 if recs_to_display > 0:235 idx = 0236 cols = st.columns(recs_to_display)237 for col in cols:238 with col:239 try:240 title = top_df['title'][idx]241 img_link = top_df['url'][idx]242 sku = top_df['Skus'][idx]243 list_price = top_df['originalPrice'][idx]244 selling_price = top_df['price'][idx]245 discount = top_df['markdownPercent'][idx]246 st.image(top_df['Image'][idx], width=image_width_dictionary[recs_to_display])247 # st.write('SKU: {}'.format(sku))248 # st.write('SKU: {}'.format(sku))249 # st.write('SKU: {}'.format(sku))250 content = '''<p><strong> <a href={}>{}</a> </strong> <br>251 <strong>SKU:</strong> {} <br>252 <strong>S.P:</strong> $ {}<br>253 <strong>Discount:</strong> % {} <br>254 <strong>L.P:</strong> $ {} <br>255 </p>'''.format(img_link, title, sku, selling_price, discount, list_price)256 st.markdown(content, unsafe_allow_html=True)257 st.button('Select', key=random_string(), on_click=insert_clickdata_table,258 args=([session_id, selected_keyword, publisher_id, sku, 1]))259 except KeyError:260 st.info('No more recommendations to display for this Keyword-PublisherID Combo!')261 st.info('You can search for another keyword or reload the page!')262 idx += 1263 else:264 st.text(265 'No more recommendations to display for this Keyword-PublisherID Combo! You can search for another keyword or reload the page!')266 267 268def display_analytics():269 import pandas as pd270 import numpy as np271 import requests272 from bs4 import BeautifulSoup273 import urllib.parse274 import os275 import string276 import random277 278 import time279 280 import streamlit as st281 import uuid282 283 import warnings284 285 warnings.filterwarnings('ignore')286 287 # custom module288 # from clickcounter import clickcounter289 from folder_management import create_folder, remove_files_folder290 from sqlite_database import create_insert_table, query_table, insert_clickdata_table, check_for_table291 292 # Main Program293 #st.set_page_config('Analytics', layout='wide')294 st.title('Analytics')295 296 df = query_table('session_data', 'session_data')297 # print(pd.Timestamp(df['clicked_at'][0]).date())298 df['date'] = df['clicked_at'].map(lambda x: pd.Timestamp(x).date())299 x_col_list = list(df.columns)300 x_col_list.remove('count')301 x_col_list.remove('clicked_at')302 print(x_col_list)303 column = st.selectbox('Select a Dimension:', x_col_list)304 305 # Grouping the DataFrame306 if column:307 grouped_df = df.groupby([column]).sum().reset_index()308 grouped_df.rename(columns={'count': 'clicks'}, inplace=True)309 # st.dataframe(grouped_df.head())310 col1, col2 = st.columns(2)311 with col1:312 # st.line_chart(grouped_df, x=column, y='clicks')313 alt_line_chart = alt.Chart(grouped_df).mark_line(color='#3ac81e').encode(x=column, y='clicks')314 st.altair_chart(alt_line_chart, use_container_width=True)315 316 with col2:317 #st.bar_chart(grouped_df, x=column, y='clicks')318 alt_bar_chart = alt.Chart(grouped_df).mark_bar(color='#3ac81e').encode(x=column, y='clicks')319 st.altair_chart(alt_bar_chart, use_container_width=True)320 321 st.title("Top Products")322 agg_df = df[['keyword', 'publisherid', 'Skus', 'count']]323 agg_df.rename(columns={'keyword': 'Keywords', 'publisherid': 'PublisherID', 'count': 'Clicks'}, inplace=True)324 agg_df = agg_df.groupby(['Skus', 'Keywords', 'PublisherID']).sum().reset_index()325 agg_df = agg_df.sort_values(by='Clicks', ascending=False).reset_index(drop=True)326 st.dataframe(agg_df.head(20), width=1000)327 328page_names_to_funcs = {329 "โ": intro,330 "Generate Recommendations": generate_recommendations,331 "Product Recommendations": display_recommendations,332 "Analytics": display_analytics333}334 335page_name = st.sidebar.selectbox("Choose a Page", page_names_to_funcs.keys())336page_names_to_funcs[page_name]()