Gift-Recommender / .gitignore
noddysnots's picture
Upload 6 files
cf9ac63 verified
raw
history blame
7.44 kB
from transformers import pipeline
from transformers import AutoTokenizer, AutoModelForSequenceClassification
import re
import numpy as np
from typing import Dict, List, Tuple
class GiftRecommender:
def __init__(self):
# Initialize NER pipeline for entity extraction
self.ner = pipeline("ner", model="dbmdz/bert-large-cased-finetuned-conll03-english")
# Initialize sentiment analysis pipeline
self.sentiment = pipeline("sentiment-analysis")
# Initialize zero-shot classification for interest categorization
self.zero_shot = pipeline("zero-shot-classification")
# Define interest categories
self.interest_categories = [
"art", "music", "sports", "technology", "reading",
"travel", "cooking", "gaming", "fashion", "outdoor activities"
]
# Initialize gift rules database
self.gift_rules = {
"art": ["art supplies set", "digital drawing tablet", "museum membership", "art classes"],
"music": ["wireless headphones", "concert tickets", "vinyl records", "music streaming subscription"],
"sports": ["fitness tracker", "sports equipment", "team merchandise", "gym membership"],
"technology": ["smart gadgets", "latest electronics", "tech accessories", "coding courses"],
"reading": ["e-reader", "book subscription", "rare book editions", "bookstore gift card"],
"travel": ["travel accessories", "language learning subscription", "travel guides", "luggage"],
"cooking": ["cooking classes", "premium ingredients set", "kitchen gadgets", "cookbook collection"],
"gaming": ["gaming console", "gaming accessories", "game subscription", "collectible items"],
"fashion": ["designer accessories", "fashion subscription box", "custom jewelry", "premium clothing"],
"outdoor": ["camping gear", "hiking equipment", "outdoor experiences", "adventure gear"]
}
def extract_age(self, text: str) -> int:
"""Extract age from text using regex."""
age_pattern = r'\b(\d{1,2})\s*-?\s*years?\s*-?\s*old\b|\b(\d{1,2})\b'
matches = re.findall(age_pattern, text)
if matches:
# Return the first number found
age = next(int(num) for nums in matches for num in nums if num)
return age if 0 < age < 120 else None
return None
def extract_gender(self, text: str) -> str:
"""Extract gender from text using keywords."""
text = text.lower()
gender_indicators = {
'female': ['she', 'her', 'sister', 'girlfriend', 'wife', 'daughter', 'mom', 'mother'],
'male': ['he', 'him', 'brother', 'boyfriend', 'husband', 'son', 'dad', 'father']
}
for gender, indicators in gender_indicators.items():
if any(indicator in text for indicator in indicators):
return gender
return "unknown"
def extract_interests(self, text: str) -> List[Dict]:
"""Extract and categorize interests using zero-shot classification."""
# First, extract potential interest phrases
interest_pattern = r'loves?\s+([^,.]+)|\blikes?\s+([^,.]+)'
matches = re.findall(interest_pattern, text.lower())
interests = []
for match in matches:
phrase = next(m for m in match if m)
# Classify the interest into predefined categories
result = self.zero_shot(
phrase,
candidate_labels=self.interest_categories,
multi_label=False
)
# Get sentiment score for the interest
sentiment_score = self.sentiment(phrase)[0]
interests.append({
'phrase': phrase,
'category': result['labels'][0],
'confidence': result['scores'][0],
'sentiment': sentiment_score['label'],
'sentiment_score': sentiment_score['score']
})
return interests
def extract_dislikes(self, text: str) -> List[str]:
"""Extract dislikes from text."""
dislike_pattern = r'hates?\s+([^,.]+)|dislikes?\s+([^,.]+)'
matches = re.findall(dislike_pattern, text.lower())
return [next(m for m in match if m) for match in matches]
def get_gift_recommendations(self, text: str) -> Dict:
"""Process text and return gift recommendations."""
# Extract basic information
age = self.extract_age(text)
gender = self.extract_gender(text)
interests = self.extract_interests(text)
dislikes = self.extract_dislikes(text)
# Generate recommendations based on interests
recommendations = []
for interest in interests:
category = interest['category']
if category in self.gift_rules:
# Weight recommendations by sentiment and confidence
weight = interest['confidence'] * (2 if interest['sentiment'] == 'POSITIVE' else 1)
recommendations.extend([
{
'gift': gift,
'category': category,
'weight': weight,
'reason': f"Based on their interest in {interest['phrase']}"
}
for gift in self.gift_rules[category]
])
# Sort recommendations by weight
recommendations.sort(key=lambda x: x['weight'], reverse=True)
return {
'profile': {
'age': age,
'gender': gender,
'interests': interests,
'dislikes': dislikes
},
'recommendations': recommendations[:5] # Return top 5 recommendations
}
def format_recommendations(self, results: Dict) -> str:
"""Format the recommendations into a readable string."""
output = []
output.append("🎁 Gift Recommendations\n")
profile = results['profile']
output.append(f"Profile Summary:")
output.append(f"- Age: {profile['age'] or 'Unknown'}")
output.append(f"- Gender: {profile['gender'].title()}")
output.append("- Interests: " + ", ".join(i['phrase'] for i in profile['interests']))
if profile['dislikes']:
output.append("- Dislikes: " + ", ".join(profile['dislikes']))
output.append("\nTop Recommendations:")
for i, rec in enumerate(results['recommendations'], 1):
output.append(f"{i}. {rec['gift']}")
output.append(f" β€’ {rec['reason']}")
return "\n".join(output)
# Example usage
if __name__ == "__main__":
recommender = GiftRecommender()
# Example input
text = """I'm looking for a gift for my 25-year-old sister.
She loves painting and traveling, especially in Japan.
She hates loud noises and doesn't like spicy food."""
results = recommender.get_gift_recommendations(text)
formatted_output = recommender.format_recommendations(results)
print(formatted_output)