WSLINMSAI commited on
Commit
58a905c
·
verified ·
1 Parent(s): 43823ee

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +27 -43
app.py CHANGED
@@ -12,11 +12,11 @@ with open(r'vect_values.pickle', 'rb') as file:
12
 
13
  df = pd.read_excel('perfume_database_cleaned.xlsx')
14
 
15
- # Example columns in df:
16
- # - brand
17
- # - perfume
18
- # - notes
19
- # - (optionally) price, gender, season, rating, image_url, etc.
20
 
21
  # Create brand and perfume options for the dropdowns
22
  brand_options = sorted(df['brand'].unique())
@@ -28,7 +28,7 @@ perfume_options = sorted(df['perfume'].unique())
28
 
29
  def perfume_change(brand):
30
  """
31
- When user selects a brand, update the perfume dropdown
32
  with only the perfumes from that brand.
33
  """
34
  filtered_perfumes = df.loc[df['brand'] == brand, 'perfume'].unique()
@@ -36,48 +36,33 @@ def perfume_change(brand):
36
 
37
  def filter_by_perfume(selected_brand, selected_perfume, top_n, note_search):
38
  """
39
- 1) Find the index of the chosen perfume in the DF
40
- 2) Retrieve the top_n most similar perfumes (based on vect_index and vect_values)
41
- 3) If note_search is not empty, filter recommendations by that note
42
- 4) Return a subset of columns + similarity
43
  """
44
- # ----------------------------------------------------------------
45
- # 1) Locate chosen perfume in the DF
46
- # ----------------------------------------------------------------
47
- # We assume there's exactly one row that matches brand+perfume.
48
- # If there's a possibility of duplicates, handle that carefully.
49
  row_idx = df.query("brand == @selected_brand and perfume == @selected_perfume").index[0]
50
 
51
- # ----------------------------------------------------------------
52
- # 2) Retrieve top_n from vect_index, vect_values
53
- # ----------------------------------------------------------------
54
  recommended_indices = vect_index[row_idx][:top_n] # e.g. top_n indices
55
- recommended_sims = vect_values[row_idx][:top_n] # e.g. top_n similarity scores
56
 
57
- # Build a smaller DF of these recommended items
58
  df_recs = df.iloc[recommended_indices].copy().reset_index(drop=True)
59
  df_recs['similarity'] = recommended_sims
60
  df_recs['similarity'] = df_recs['similarity'].map("{:.2%}".format)
61
 
62
- # Clean up notes by sorting & re-joining
63
  df_recs['notes'] = df_recs['notes'].str.split(',').apply(lambda x: sorted(x))
64
  df_recs['notes'] = df_recs['notes'].apply(lambda x: ', '.join([n.strip() for n in x]))
65
 
66
- # ----------------------------------------------------------------
67
- # 3) Optional note search (if user typed something in)
68
- # ----------------------------------------------------------------
69
  if note_search:
70
- # For example, filter for rows that contain that note in the 'notes' column
71
- # Convert both sides to lowercase for a case-insensitive match
72
  note_search_lower = note_search.lower()
73
  df_recs = df_recs[df_recs['notes'].str.lower().str.contains(note_search_lower)]
74
 
75
- # ----------------------------------------------------------------
76
- # 4) Return final DataFrame
77
- # ----------------------------------------------------------------
78
- # You can include any columns you want.
79
- # Example columns: brand, perfume, similarity, notes
80
- # If you have images, you could include them in a separate Gallery component, etc.
81
  return df_recs[['brand', 'perfume', 'similarity', 'notes']]
82
 
83
  # ----------------------------------------------------------------
@@ -121,7 +106,7 @@ button:hover {
121
  font-size: 0.9rem !important;
122
  }
123
 
124
- /* Centered text for the top bar */
125
  #top-header {
126
  text-align: center;
127
  margin-bottom: 20px;
@@ -132,7 +117,7 @@ button:hover {
132
  # BUILD THE GRADIO INTERFACE
133
  # ----------------------------------------------------------------
134
  with gr.Blocks(css=custom_css) as demo:
135
- # Top header
136
  gr.HTML("""
137
  <div id="top-header">
138
  <h1>🌸 Perfume Recommendation App 🌸</h1>
@@ -141,17 +126,17 @@ with gr.Blocks(css=custom_css) as demo:
141
  """)
142
 
143
  with gr.Row():
144
- # Left column: brand, perfume, note search
145
  with gr.Column():
146
  brand_dropdown = gr.Dropdown(
147
  choices=brand_options,
148
  label="Select Brand",
149
- value=brand_options[0] # or None
150
  )
151
  perfume_dropdown = gr.Dropdown(
152
  choices=perfume_options,
153
  label="Select Perfume",
154
- value=perfume_options[0] # or None
155
  )
156
  brand_dropdown.change(
157
  fn=perfume_change,
@@ -159,12 +144,12 @@ with gr.Blocks(css=custom_css) as demo:
159
  outputs=[perfume_dropdown]
160
  )
161
 
162
- # Textbox to filter by note (optional)
163
  note_search = gr.Textbox(
164
  label="Optional: Search for a specific note (e.g., 'rose', 'vanilla')"
165
  )
166
 
167
- # Slider for how many recommendations to show
168
  top_n_slider = gr.Slider(
169
  minimum=1,
170
  maximum=10,
@@ -173,19 +158,18 @@ with gr.Blocks(css=custom_css) as demo:
173
  label="Number of recommendations to show"
174
  )
175
 
176
- # Button to trigger the search
177
  btn_search = gr.Button("Recommend")
178
 
179
- # Right column: results
180
  with gr.Column():
181
- # The results DataFrame
182
  output_df = gr.Dataframe(
183
  headers=["Brand", "Perfume", "Similarity", "Notes"],
184
  label="Recommended Perfumes",
185
  wrap=True
186
  )
187
 
188
- # Connect button to filter_by_perfume function
189
  btn_search.click(
190
  fn=filter_by_perfume,
191
  inputs=[brand_dropdown, perfume_dropdown, top_n_slider, note_search],
 
12
 
13
  df = pd.read_excel('perfume_database_cleaned.xlsx')
14
 
15
+ # Clean the DataFrame:
16
+ # Drop rows where 'perfume' is missing and convert both 'perfume' and 'brand' to strings
17
+ df.dropna(subset=['perfume'], inplace=True)
18
+ df['perfume'] = df['perfume'].astype(str)
19
+ df['brand'] = df['brand'].astype(str)
20
 
21
  # Create brand and perfume options for the dropdowns
22
  brand_options = sorted(df['brand'].unique())
 
28
 
29
  def perfume_change(brand):
30
  """
31
+ When the user selects a brand, update the perfume dropdown
32
  with only the perfumes from that brand.
33
  """
34
  filtered_perfumes = df.loc[df['brand'] == brand, 'perfume'].unique()
 
36
 
37
  def filter_by_perfume(selected_brand, selected_perfume, top_n, note_search):
38
  """
39
+ 1) Find the index of the chosen perfume in the DataFrame.
40
+ 2) Retrieve the top_n most similar perfumes (based on vect_index and vect_values).
41
+ 3) If note_search is provided, filter recommendations by that note.
42
+ 4) Return a subset of columns plus similarity.
43
  """
44
+ # Locate the chosen perfume in the DataFrame
 
 
 
 
45
  row_idx = df.query("brand == @selected_brand and perfume == @selected_perfume").index[0]
46
 
47
+ # Retrieve top_n indices and similarity values
 
 
48
  recommended_indices = vect_index[row_idx][:top_n] # e.g. top_n indices
49
+ recommended_sims = vect_values[row_idx][:top_n] # e.g. top_n similarity scores
50
 
51
+ # Build a DataFrame of the recommended items
52
  df_recs = df.iloc[recommended_indices].copy().reset_index(drop=True)
53
  df_recs['similarity'] = recommended_sims
54
  df_recs['similarity'] = df_recs['similarity'].map("{:.2%}".format)
55
 
56
+ # Clean up the notes column: split, sort, and join
57
  df_recs['notes'] = df_recs['notes'].str.split(',').apply(lambda x: sorted(x))
58
  df_recs['notes'] = df_recs['notes'].apply(lambda x: ', '.join([n.strip() for n in x]))
59
 
60
+ # Optional filtering by a specific note if provided
 
 
61
  if note_search:
 
 
62
  note_search_lower = note_search.lower()
63
  df_recs = df_recs[df_recs['notes'].str.lower().str.contains(note_search_lower)]
64
 
65
+ # Return the desired columns
 
 
 
 
 
66
  return df_recs[['brand', 'perfume', 'similarity', 'notes']]
67
 
68
  # ----------------------------------------------------------------
 
106
  font-size: 0.9rem !important;
107
  }
108
 
109
+ /* Centered text for the top header */
110
  #top-header {
111
  text-align: center;
112
  margin-bottom: 20px;
 
117
  # BUILD THE GRADIO INTERFACE
118
  # ----------------------------------------------------------------
119
  with gr.Blocks(css=custom_css) as demo:
120
+ # Top header with HTML content
121
  gr.HTML("""
122
  <div id="top-header">
123
  <h1>🌸 Perfume Recommendation App 🌸</h1>
 
126
  """)
127
 
128
  with gr.Row():
129
+ # Left column: user inputs
130
  with gr.Column():
131
  brand_dropdown = gr.Dropdown(
132
  choices=brand_options,
133
  label="Select Brand",
134
+ value=brand_options[0]
135
  )
136
  perfume_dropdown = gr.Dropdown(
137
  choices=perfume_options,
138
  label="Select Perfume",
139
+ value=perfume_options[0]
140
  )
141
  brand_dropdown.change(
142
  fn=perfume_change,
 
144
  outputs=[perfume_dropdown]
145
  )
146
 
147
+ # Optional textbox for note search
148
  note_search = gr.Textbox(
149
  label="Optional: Search for a specific note (e.g., 'rose', 'vanilla')"
150
  )
151
 
152
+ # Slider to select the number of recommendations to show
153
  top_n_slider = gr.Slider(
154
  minimum=1,
155
  maximum=10,
 
158
  label="Number of recommendations to show"
159
  )
160
 
161
+ # Button to trigger the recommendation
162
  btn_search = gr.Button("Recommend")
163
 
164
+ # Right column: display results
165
  with gr.Column():
 
166
  output_df = gr.Dataframe(
167
  headers=["Brand", "Perfume", "Similarity", "Notes"],
168
  label="Recommended Perfumes",
169
  wrap=True
170
  )
171
 
172
+ # Link the Recommend button to our function
173
  btn_search.click(
174
  fn=filter_by_perfume,
175
  inputs=[brand_dropdown, perfume_dropdown, top_n_slider, note_search],