recipe-rover-api / app /utils /recommendation_utils.py
garvitcpp's picture
Upload 48 files
c30b4ba verified
import logging
from app.models.recipe import Recipe
from app.utils.feature_engineering import create_query_vector
from app.utils.similarity_calculation import calculate_weighted_similarity
logger = logging.getLogger(__name__)
async def get_top_recommendations(df, combined_matrix, tfidf_vectorizer_ingredients,
tfidf_vectorizer_keywords, tfidf_vectorizer_keywords_name,
category_dummies, scaler, feature_weights, image_search_service,
category=None, dietary_preference=None, ingredients=None,
calories=None, time=None, keywords=None, keywords_name=None, top_n=5):
logger.info(f"Starting recommendation process for category: {category}, dietary_preference: {dietary_preference}")
query_vector = create_query_vector(combined_matrix, tfidf_vectorizer_ingredients,
tfidf_vectorizer_keywords, tfidf_vectorizer_keywords_name,
category_dummies, scaler, feature_weights,
category=category, dietary_preference=dietary_preference,
ingredients=ingredients, calories=calories, time=time,
keywords=keywords, keywords_name=keywords_name)
similarity_scores = calculate_weighted_similarity(query_vector, combined_matrix, df, calories, time)
if category:
similarity_scores *= (df['RecipeCategory'] == category)
top_indices = similarity_scores.argsort()[-top_n*3:][::-1]
logger.info(f"Found {len(top_indices)} potential recommendations")
results = []
async with image_search_service as image_service:
for idx in top_indices:
if len(results) >= top_n:
break
recipe = df.iloc[idx]
if category and recipe['RecipeCategory'] != category:
continue
try:
image_urls = await image_service.search_recipe_images(recipe['Name'], recipe['Images'], 3)
except Exception as e:
logger.error(f"Error searching images for {recipe['Name']}: {str(e)}")
image_urls = []
results.append(Recipe(
RecipeId=int(recipe['RecipeId']),
Name=recipe['Name'],
RecipeCategory=recipe['RecipeCategory'],
RecipeIngredientParts=recipe['RecipeIngredientParts'],
Keywords=recipe['Keywords'],
keywords_name=recipe['keywords_name'],
Calories=float(recipe['Calories']),
TotalTime_minutes=int(recipe['TotalTime_minutes']),
AggregatedRating=float(recipe['AggregatedRating']),
ReviewCount=int(recipe['ReviewCount']),
Description=recipe['Description'],
RecipeIngredientQuantities=recipe['RecipeIngredientQuantities'],
RecipeInstructions=recipe['RecipeInstructions'],
Images=image_urls,
Similarity=float(similarity_scores[idx])
))
logger.info(f"Returning {len(results)} recommendations")
return results[:top_n]