teganmosi commited on
Commit
748b2eb
·
verified ·
1 Parent(s): 519b86c

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +261 -0
app.py ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """app.py.ipynb
3
+
4
+ Automatically generated by Colab.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/1AO89EnPiFQ-JnEpNKwsABc0bj5or_Upn
8
+ """
9
+
10
+ import pandas as pd
11
+ import numpy as np
12
+ from sklearn.ensemble import RandomForestClassifier
13
+ from sklearn.preprocessing import LabelEncoder
14
+ from sklearn.model_selection import train_test_split, GridSearchCV
15
+ import gradio as gr
16
+ import warnings
17
+ warnings.filterwarnings('ignore')
18
+
19
+ # Step 1: Generate dataset and train model
20
+ np.random.seed(42)
21
+ moods = ['happy', 'stressed', 'bored', 'sad', 'excited', 'tired', 'anxious', 'content', 'nostalgic', 'hungry']
22
+ snacks = [
23
+ 'fruit', 'chocolate', 'chips', 'popcorn', 'ice cream', 'pretzels', 'cookies', 'candy',
24
+ 'yogurt', 'granola bar', 'crackers', 'veggies', 'cheese',
25
+ 'chin chin', 'kuli kuli', 'plantain chips', 'puff puff', 'akara', 'coconut candy',
26
+ 'kokoro', 'dodo ikire', 'roasted groundnuts', 'suya', 'boli', 'kilishi',
27
+ 'buns', 'doughnuts', 'meat pie', 'egg rolls'
28
+ ]
29
+ times_of_day = ['morning', 'afternoon', 'evening', 'midnight']
30
+
31
+ # Snack groups
32
+ snack_groups = {
33
+ 'nigerian_fried': ['chin chin', 'puff puff', 'akara', 'buns', 'doughnuts', 'meat pie', 'egg rolls'],
34
+ 'nigerian_savory': ['suya', 'kuli kuli', 'plantain chips', 'boli', 'kilishi', 'roasted groundnuts'],
35
+ 'nigerian_sweet': ['coconut candy', 'dodo ikire', 'chocolate', 'candy', 'cookies', 'ice cream'],
36
+ 'savory_snacks': ['chips', 'popcorn', 'pretzels', 'crackers', 'kokoro'],
37
+ 'healthy_light': ['fruit', 'yogurt', 'veggies', 'granola bar', 'cheese']
38
+ }
39
+ snack_to_group = {snack: group for group, snacks in snack_groups.items() for snack in snacks}
40
+ group_list = list(snack_groups.keys())
41
+
42
+ # Mood-time-snack group affinities
43
+ mood_time_group_probs = {
44
+ 'happy': {
45
+ 'morning': {'nigerian_fried': 0.75, 'nigerian_sweet': 0.2, 'healthy_light': 0.05},
46
+ 'afternoon': {'nigerian_fried': 0.75, 'nigerian_sweet': 0.2, 'healthy_light': 0.05},
47
+ 'evening': {'nigerian_sweet': 0.75, 'healthy_light': 0.2, 'savory_snacks': 0.05},
48
+ 'midnight': {'nigerian_sweet': 0.75, 'nigerian_savory': 0.2, 'savory_snacks': 0.05}
49
+ },
50
+ 'stressed': {
51
+ 'morning': {'nigerian_sweet': 0.75, 'nigerian_fried': 0.2, 'healthy_light': 0.05},
52
+ 'afternoon': {'nigerian_sweet': 0.75, 'nigerian_fried': 0.2, 'savory_snacks': 0.05},
53
+ 'evening': {'nigerian_sweet': 0.75, 'savory_snacks': 0.2, 'nigerian_savory': 0.05},
54
+ 'midnight': {'nigerian_sweet': 0.75, 'nigerian_savory': 0.2, 'savory_snacks': 0.05}
55
+ },
56
+ 'bored': {
57
+ 'morning': {'savory_snacks': 0.75, 'nigerian_fried': 0.2, 'healthy_light': 0.05},
58
+ 'afternoon': {'savory_snacks': 0.75, 'nigerian_savory': 0.2, 'healthy_light': 0.05},
59
+ 'evening': {'savory_snacks': 0.75, 'nigerian_savory': 0.2, 'healthy_light': 0.05},
60
+ 'midnight': {'savory_snacks': 0.75, 'nigerian_savory': 0.2, 'healthy_light': 0.05}
61
+ },
62
+ 'sad': {
63
+ 'morning': {'nigerian_sweet': 0.75, 'nigerian_fried': 0.2, 'healthy_light': 0.05},
64
+ 'afternoon': {'nigerian_sweet': 0.75, 'healthy_light': 0.2, 'nigerian_fried': 0.05},
65
+ 'evening': {'nigerian_sweet': 0.75, 'healthy_light': 0.2, 'savory_snacks': 0.05},
66
+ 'midnight': {'nigerian_sweet': 0.75, 'healthy_light': 0.2, 'nigerian_savory': 0.05}
67
+ },
68
+ 'excited': {
69
+ 'morning': {'nigerian_fried': 0.75, 'nigerian_sweet': 0.2, 'healthy_light': 0.05},
70
+ 'afternoon': {'nigerian_fried': 0.75, 'nigerian_savory': 0.2, 'nigerian_sweet': 0.05},
71
+ 'evening': {'nigerian_sweet': 0.75, 'nigerian_savory': 0.2, 'savory_snacks': 0.05},
72
+ 'midnight': {'nigerian_savory': 0.75, 'nigerian_sweet': 0.2, 'savory_snacks': 0.05}
73
+ },
74
+ 'tired': {
75
+ 'morning': {'healthy_light': 0.75, 'nigerian_fried': 0.2, 'nigerian_sweet': 0.05},
76
+ 'afternoon': {'healthy_light': 0.75, 'nigerian_fried': 0.2, 'savory_snacks': 0.05},
77
+ 'evening': {'healthy_light': 0.75, 'nigerian_sweet': 0.2, 'savory_snacks': 0.05},
78
+ 'midnight': {'healthy_light': 0.75, 'nigerian_savory': 0.2, 'nigerian_sweet': 0.05}
79
+ },
80
+ 'anxious': {
81
+ 'morning': {'savory_snacks': 0.75, 'nigerian_fried': 0.2, 'healthy_light': 0.05},
82
+ 'afternoon': {'savory_snacks': 0.75, 'nigerian_savory': 0.2, 'healthy_light': 0.05},
83
+ 'evening': {'savory_snacks': 0.75, 'nigerian_savory': 0.2, 'healthy_light': 0.05},
84
+ 'midnight': {'savory_snacks': 0.75, 'nigerian_savory': 0.2, 'healthy_light': 0.05}
85
+ },
86
+ 'content': {
87
+ 'morning': {'healthy_light': 0.75, 'nigerian_fried': 0.2, 'nigerian_sweet': 0.05},
88
+ 'afternoon': {'nigerian_savory': 0.75, 'healthy_light': 0.2, 'nigerian_fried': 0.05},
89
+ 'evening': {'healthy_light': 0.75, 'nigerian_sweet': 0.2, 'savory_snacks': 0.05},
90
+ 'midnight': {'healthy_light': 0.75, 'nigerian_savory': 0.2, 'nigerian_sweet': 0.05}
91
+ },
92
+ 'nostalgic': {
93
+ 'morning': {'nigerian_sweet': 0.75, 'nigerian_fried': 0.2, 'healthy_light': 0.05},
94
+ 'afternoon': {'nigerian_sweet': 0.75, 'nigerian_fried': 0.2, 'healthy_light': 0.05},
95
+ 'evening': {'nigerian_sweet': 0.75, 'healthy_light': 0.2, 'savory_snacks': 0.05},
96
+ 'midnight': {'nigerian_sweet': 0.75, 'nigerian_savory': 0.2, 'healthy_light': 0.05}
97
+ },
98
+ 'hungry': {
99
+ 'morning': {'nigerian_fried': 0.75, 'savory_snacks': 0.2, 'healthy_light': 0.05},
100
+ 'afternoon': {'nigerian_savory': 0.75, 'nigerian_fried': 0.2, 'savory_snacks': 0.05},
101
+ 'evening': {'nigerian_savory': 0.75, 'savory_snacks': 0.2, 'nigerian_sweet': 0.05},
102
+ 'midnight': {'nigerian_savory': 0.75, 'savory_snacks': 0.2, 'nigerian_sweet': 0.05}
103
+ }
104
+ }
105
+
106
+ # Generate 1800 samples
107
+ n_samples = 1800
108
+ data = {'mood': [], 'time_of_day': [], 'hunger_level': [], 'sentiment': [], 'snack': [], 'snack_group': []}
109
+
110
+ for _ in range(n_samples):
111
+ mood = np.random.choice(moods, p=[0.15, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.05])
112
+ time = np.random.choice(times_of_day)
113
+ hunger_level = 1.0 if mood == 'hungry' else np.random.uniform(0, 0.8)
114
+ sentiment = round(np.random.uniform(-1, 1), 2)
115
+
116
+ group_probs = [mood_time_group_probs[mood][time].get(g, 0.01) for g in group_list]
117
+ group = np.random.choice(group_list, p=group_probs / np.sum(group_probs))
118
+ group_snacks = snack_groups[group]
119
+ snack_probs = [
120
+ 0.6 if (snack == 'suya' and time in ['evening', 'midnight']) or (snack == 'boli' and time == 'afternoon') or
121
+ (snack in ['puff puff', 'buns', 'doughnuts', 'meat pie', 'egg rolls'] and time in ['morning', 'afternoon']) or
122
+ (snack == 'akara' and time in ['morning', 'midnight']) or
123
+ (snack == 'chin chin' and time in ['morning', 'afternoon', 'midnight'])
124
+ else 0.35 if snack in ['kuli kuli', 'plantain chips', 'popcorn', 'kokoro', 'roasted groundnuts', 'kilishi']
125
+ else 0.2 for snack in group_snacks
126
+ ]
127
+ if time not in ['evening', 'midnight'] and 'suya' in group_snacks:
128
+ snack_probs[group_snacks.index('suya')] = 0
129
+ if time != 'afternoon' and 'boli' in group_snacks:
130
+ snack_probs[group_snacks.index('boli')] = 0
131
+ if time not in ['morning', 'afternoon']:
132
+ for snack in ['puff puff', 'buns', 'doughnuts', 'meat pie', 'egg rolls']:
133
+ if snack in group_snacks:
134
+ snack_probs[group_snacks.index(snack)] = 0
135
+ if time not in ['morning', 'midnight'] and 'akara' in group_snacks:
136
+ snack_probs[group_snacks.index('akara')] = 0
137
+ snack_probs = [p / sum(snack_probs) if sum(snack_probs) > 0 else 0.2 for p in snack_probs]
138
+ snack = np.random.choice(group_snacks, p=snack_probs)
139
+
140
+ data['mood'].append(mood)
141
+ data['time_of_day'].append(time)
142
+ data['hunger_level'].append(hunger_level)
143
+ data['sentiment'].append(sentiment)
144
+ data['snack'].append(snack)
145
+ data['snack_group'].append(group)
146
+
147
+ df = pd.DataFrame(data)
148
+
149
+ # Adjust sentiment
150
+ df.loc[df['mood'].isin(['happy', 'excited', 'content', 'nostalgic']), 'sentiment'] = df.loc[
151
+ df['mood'].isin(['happy', 'excited', 'content', 'nostalgic']), 'sentiment'].clip(lower=0.2)
152
+ df.loc[df['mood'].isin(['stressed', 'sad', 'anxious', 'tired']), 'sentiment'] = df.loc[
153
+ df['mood'].isin(['stressed', 'sad', 'anxious', 'tired']), 'sentiment'].clip(upper=-0.1)
154
+ df.loc[df['mood'].isin(['bored', 'hungry']), 'sentiment'] = df.loc[
155
+ df['mood'].isin(['bored', 'hungry']), 'sentiment'].clip(-0.3, 0.3)
156
+
157
+ # Add snack_type and snack_texture
158
+ snack_types = {
159
+ 'chin chin': 'sweet', 'puff puff': 'sweet', 'akara': 'savory', 'suya': 'spicy',
160
+ 'kuli kuli': 'spicy', 'plantain chips': 'savory', 'coconut candy': 'sweet',
161
+ 'dodo ikire': 'sweet', 'roasted groundnuts': 'savory', 'fruit': 'light',
162
+ 'yogurt': 'light', 'veggies': 'light', 'granola bar': 'light', 'cheese': 'light',
163
+ 'chocolate': 'sweet', 'candy': 'sweet', 'cookies': 'sweet', 'ice cream': 'sweet',
164
+ 'chips': 'savory', 'popcorn': 'savory', 'pretzels': 'savory', 'crackers': 'savory',
165
+ 'kokoro': 'savory', 'boli': 'savory', 'kilishi': 'spicy',
166
+ 'buns': 'sweet', 'doughnuts': 'sweet', 'meat pie': 'savory', 'egg rolls': 'savory'
167
+ }
168
+ snack_textures = {
169
+ 'chin chin': 'crisp', 'puff puff': 'soft', 'akara': 'soft', 'suya': 'chewy',
170
+ 'kuli kuli': 'crisp', 'plantain chips': 'crisp', 'coconut candy': 'chewy',
171
+ 'dodo ikire': 'soft', 'roasted groundnuts': 'crisp', 'fruit': 'soft',
172
+ 'yogurt': 'soft', 'veggies': 'crisp', 'granola bar': 'crisp', 'cheese': 'soft',
173
+ 'chocolate': 'soft', 'candy': 'chewy', 'cookies': 'crisp', 'ice cream': 'soft',
174
+ 'chips': 'crisp', 'popcorn': 'crisp', 'pretzels': 'crisp', 'crackers': 'crisp',
175
+ 'kokoro': 'crisp', 'boli': 'soft', 'kilishi': 'chewy',
176
+ 'buns': 'soft', 'doughnuts': 'soft', 'meat pie': 'soft', 'egg rolls': 'soft'
177
+ }
178
+ df['snack_type'] = df['snack'].map(snack_types)
179
+ df['snack_texture'] = df['snack'].map(snack_textures)
180
+
181
+ # Encode features
182
+ le_mood = LabelEncoder()
183
+ le_time = LabelEncoder()
184
+ le_type = LabelEncoder()
185
+ le_texture = LabelEncoder()
186
+ le_group = LabelEncoder()
187
+
188
+ df['mood_encoded'] = le_mood.fit_transform(df['mood'])
189
+ df['time_encoded'] = le_time.fit_transform(df['time_of_day'])
190
+ df['type_encoded'] = le_type.fit_transform(df['snack_type'])
191
+ df['texture_encoded'] = le_texture.fit_transform(df['snack_texture'])
192
+ df['group_encoded'] = le_group.fit_transform(df['snack_group'])
193
+
194
+ X = df[['mood_encoded', 'time_encoded', 'hunger_level', 'sentiment', 'type_encoded', 'texture_encoded']]
195
+ y = df['group_encoded']
196
+
197
+ X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
198
+
199
+ # Train model
200
+ param_grid = {
201
+ 'n_estimators': [300, 400],
202
+ 'max_depth': [12, 15],
203
+ 'min_samples_split': [5, 10]
204
+ }
205
+ model = RandomForestClassifier(class_weight='balanced', random_state=42)
206
+ grid_search = GridSearchCV(model, param_grid, cv=5, scoring='accuracy', n_jobs=-1)
207
+ grid_search.fit(X_train, y_train)
208
+ best_model = grid_search.best_estimator_
209
+
210
+ # Prediction function with error handling
211
+ def predict_snack(mood, time_of_day, hunger_level, sentiment, snack_type):
212
+ mood_enc = le_mood.transform([mood])[0]
213
+ time_enc = le_time.transform([time_of_day])[0]
214
+ type_enc = le_type.transform([snack_type])[0]
215
+ type_to_texture = {'sweet': 'soft', 'savory': 'crisp', 'spicy': 'chewy', 'light': 'soft'}
216
+ texture_enc = le_texture.transform([type_to_texture[snack_type]])[0]
217
+ input_data = np.array([[mood_enc, time_enc, hunger_level, sentiment, type_enc, texture_enc]])
218
+ pred = best_model.predict(input_data)
219
+ group = le_group.inverse_transform(pred)[0]
220
+ group_snacks = snack_groups[group]
221
+ snack_probs = [
222
+ 0.6 if (snack == 'suya' and time_of_day in ['evening', 'midnight']) or
223
+ (snack == 'boli' and time_of_day == 'afternoon') or
224
+ (snack in ['puff puff', 'buns', 'doughnuts', 'meat pie', 'egg rolls'] and time_of_day in ['morning', 'afternoon']) or
225
+ (snack == 'akara' and time_of_day in ['morning', 'midnight']) or
226
+ (snack == 'chin chin' and time_of_day in ['morning', 'afternoon', 'midnight'])
227
+ else 0.35 if snack in ['kuli kuli', 'plantain chips', 'popcorn', 'kokoro', 'roasted groundnuts', 'kilishi']
228
+ else 0.2 for snack in group_snacks
229
+ ]
230
+ # Only modify probabilities if the snack is in the group
231
+ if time_of_day not in ['evening', 'midnight'] and 'suya' in group_snacks:
232
+ snack_probs[group_snacks.index('suya')] = 0
233
+ if time_of_day != 'afternoon' and 'boli' in group_snacks:
234
+ snack_probs[group_snacks.index('boli')] = 0
235
+ if time_of_day not in ['morning', 'afternoon']:
236
+ for snack in ['puff puff', 'buns', 'doughnuts', 'meat pie', 'egg rolls']:
237
+ if snack in group_snacks:
238
+ snack_probs[group_snacks.index(snack)] = 0
239
+ if time_of_day not in ['morning', 'midnight'] and 'akara' in group_snacks:
240
+ snack_probs[group_snacks.index('akara')] = 0
241
+ snack_probs = [p / sum(snack_probs) if sum(snack_probs) > 0 else 0.2 for p in snack_probs]
242
+ snack = np.random.choice(group_snacks, p=snack_probs)
243
+ return f"You're craving: {snack} (from {group})!"
244
+
245
+ # Gradio interface
246
+ interface = gr.Interface(
247
+ fn=predict_snack,
248
+ inputs=[
249
+ gr.Dropdown(choices=moods, label="Mood", value="happy"),
250
+ gr.Dropdown(choices=times_of_day, label="Time of Day", value="morning"),
251
+ gr.Slider(minimum=0, maximum=1, step=0.1, label="Hunger Level (0 to 1)", value=0.5),
252
+ gr.Slider(minimum=-1, maximum=1, step=0.1, label="Sentiment (-1 to 1)", value=0.0),
253
+ gr.Dropdown(choices=['sweet', 'savory', 'spicy', 'light'], label="Snack Type", value="sweet")
254
+ ],
255
+ outputs=gr.Textbox(label="Prediction"),
256
+ title="Snack Predictor",
257
+ description="Discover your perfect snack based on your mood,time of the day and preferences!"
258
+ )
259
+
260
+ # Launch the app
261
+ interface.launch(share=True)