noddysnots commited on
Commit
cf9ac63
Β·
verified Β·
1 Parent(s): 892dda8

Upload 6 files

Browse files
Files changed (6) hide show
  1. .gitignore +165 -0
  2. README.md +42 -13
  3. app.py +47 -0
  4. demo.py +42 -0
  5. requirements.txt +9 -0
  6. test_run.py +6 -0
.gitignore ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import pipeline
2
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification
3
+ import re
4
+ import numpy as np
5
+ from typing import Dict, List, Tuple
6
+
7
+ class GiftRecommender:
8
+ def __init__(self):
9
+ # Initialize NER pipeline for entity extraction
10
+ self.ner = pipeline("ner", model="dbmdz/bert-large-cased-finetuned-conll03-english")
11
+
12
+ # Initialize sentiment analysis pipeline
13
+ self.sentiment = pipeline("sentiment-analysis")
14
+
15
+ # Initialize zero-shot classification for interest categorization
16
+ self.zero_shot = pipeline("zero-shot-classification")
17
+
18
+ # Define interest categories
19
+ self.interest_categories = [
20
+ "art", "music", "sports", "technology", "reading",
21
+ "travel", "cooking", "gaming", "fashion", "outdoor activities"
22
+ ]
23
+
24
+ # Initialize gift rules database
25
+ self.gift_rules = {
26
+ "art": ["art supplies set", "digital drawing tablet", "museum membership", "art classes"],
27
+ "music": ["wireless headphones", "concert tickets", "vinyl records", "music streaming subscription"],
28
+ "sports": ["fitness tracker", "sports equipment", "team merchandise", "gym membership"],
29
+ "technology": ["smart gadgets", "latest electronics", "tech accessories", "coding courses"],
30
+ "reading": ["e-reader", "book subscription", "rare book editions", "bookstore gift card"],
31
+ "travel": ["travel accessories", "language learning subscription", "travel guides", "luggage"],
32
+ "cooking": ["cooking classes", "premium ingredients set", "kitchen gadgets", "cookbook collection"],
33
+ "gaming": ["gaming console", "gaming accessories", "game subscription", "collectible items"],
34
+ "fashion": ["designer accessories", "fashion subscription box", "custom jewelry", "premium clothing"],
35
+ "outdoor": ["camping gear", "hiking equipment", "outdoor experiences", "adventure gear"]
36
+ }
37
+
38
+ def extract_age(self, text: str) -> int:
39
+ """Extract age from text using regex."""
40
+ age_pattern = r'\b(\d{1,2})\s*-?\s*years?\s*-?\s*old\b|\b(\d{1,2})\b'
41
+ matches = re.findall(age_pattern, text)
42
+ if matches:
43
+ # Return the first number found
44
+ age = next(int(num) for nums in matches for num in nums if num)
45
+ return age if 0 < age < 120 else None
46
+ return None
47
+
48
+ def extract_gender(self, text: str) -> str:
49
+ """Extract gender from text using keywords."""
50
+ text = text.lower()
51
+ gender_indicators = {
52
+ 'female': ['she', 'her', 'sister', 'girlfriend', 'wife', 'daughter', 'mom', 'mother'],
53
+ 'male': ['he', 'him', 'brother', 'boyfriend', 'husband', 'son', 'dad', 'father']
54
+ }
55
+
56
+ for gender, indicators in gender_indicators.items():
57
+ if any(indicator in text for indicator in indicators):
58
+ return gender
59
+ return "unknown"
60
+
61
+ def extract_interests(self, text: str) -> List[Dict]:
62
+ """Extract and categorize interests using zero-shot classification."""
63
+ # First, extract potential interest phrases
64
+ interest_pattern = r'loves?\s+([^,.]+)|\blikes?\s+([^,.]+)'
65
+ matches = re.findall(interest_pattern, text.lower())
66
+
67
+ interests = []
68
+ for match in matches:
69
+ phrase = next(m for m in match if m)
70
+ # Classify the interest into predefined categories
71
+ result = self.zero_shot(
72
+ phrase,
73
+ candidate_labels=self.interest_categories,
74
+ multi_label=False
75
+ )
76
+
77
+ # Get sentiment score for the interest
78
+ sentiment_score = self.sentiment(phrase)[0]
79
+
80
+ interests.append({
81
+ 'phrase': phrase,
82
+ 'category': result['labels'][0],
83
+ 'confidence': result['scores'][0],
84
+ 'sentiment': sentiment_score['label'],
85
+ 'sentiment_score': sentiment_score['score']
86
+ })
87
+
88
+ return interests
89
+
90
+ def extract_dislikes(self, text: str) -> List[str]:
91
+ """Extract dislikes from text."""
92
+ dislike_pattern = r'hates?\s+([^,.]+)|dislikes?\s+([^,.]+)'
93
+ matches = re.findall(dislike_pattern, text.lower())
94
+ return [next(m for m in match if m) for match in matches]
95
+
96
+ def get_gift_recommendations(self, text: str) -> Dict:
97
+ """Process text and return gift recommendations."""
98
+ # Extract basic information
99
+ age = self.extract_age(text)
100
+ gender = self.extract_gender(text)
101
+ interests = self.extract_interests(text)
102
+ dislikes = self.extract_dislikes(text)
103
+
104
+ # Generate recommendations based on interests
105
+ recommendations = []
106
+ for interest in interests:
107
+ category = interest['category']
108
+ if category in self.gift_rules:
109
+ # Weight recommendations by sentiment and confidence
110
+ weight = interest['confidence'] * (2 if interest['sentiment'] == 'POSITIVE' else 1)
111
+ recommendations.extend([
112
+ {
113
+ 'gift': gift,
114
+ 'category': category,
115
+ 'weight': weight,
116
+ 'reason': f"Based on their interest in {interest['phrase']}"
117
+ }
118
+ for gift in self.gift_rules[category]
119
+ ])
120
+
121
+ # Sort recommendations by weight
122
+ recommendations.sort(key=lambda x: x['weight'], reverse=True)
123
+
124
+ return {
125
+ 'profile': {
126
+ 'age': age,
127
+ 'gender': gender,
128
+ 'interests': interests,
129
+ 'dislikes': dislikes
130
+ },
131
+ 'recommendations': recommendations[:5] # Return top 5 recommendations
132
+ }
133
+
134
+ def format_recommendations(self, results: Dict) -> str:
135
+ """Format the recommendations into a readable string."""
136
+ output = []
137
+ output.append("🎁 Gift Recommendations\n")
138
+
139
+ profile = results['profile']
140
+ output.append(f"Profile Summary:")
141
+ output.append(f"- Age: {profile['age'] or 'Unknown'}")
142
+ output.append(f"- Gender: {profile['gender'].title()}")
143
+ output.append("- Interests: " + ", ".join(i['phrase'] for i in profile['interests']))
144
+ if profile['dislikes']:
145
+ output.append("- Dislikes: " + ", ".join(profile['dislikes']))
146
+
147
+ output.append("\nTop Recommendations:")
148
+ for i, rec in enumerate(results['recommendations'], 1):
149
+ output.append(f"{i}. {rec['gift']}")
150
+ output.append(f" β€’ {rec['reason']}")
151
+
152
+ return "\n".join(output)
153
+
154
+ # Example usage
155
+ if __name__ == "__main__":
156
+ recommender = GiftRecommender()
157
+
158
+ # Example input
159
+ text = """I'm looking for a gift for my 25-year-old sister.
160
+ She loves painting and traveling, especially in Japan.
161
+ She hates loud noises and doesn't like spicy food."""
162
+
163
+ results = recommender.get_gift_recommendations(text)
164
+ formatted_output = recommender.format_recommendations(results)
165
+ print(formatted_output)
README.md CHANGED
@@ -1,13 +1,42 @@
1
- ---
2
- title: Gift Recommender
3
- emoji: πŸš€
4
- colorFrom: gray
5
- colorTo: yellow
6
- sdk: gradio
7
- sdk_version: 5.14.0
8
- app_file: app.py
9
- pinned: false
10
- short_description: NLP based gift recommender
11
- ---
12
-
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # NLP Gift Recommender
2
+
3
+ An NLP-powered gift recommendation system using Hugging Face transformers.
4
+
5
+ ## Setup
6
+
7
+ 1. Clone the repository:
8
+ ```bash
9
+ git clone https://github.com/yourusername/nlp-gift-recommender.git
10
+ cd nlp-gift-recommender
11
+ ```
12
+
13
+ 2. Install dependencies:
14
+ ```bash
15
+ pip install -r requirements.txt
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ ```python
21
+ from src.recommender import GiftRecommender
22
+
23
+ recommender = GiftRecommender()
24
+ text = "I'm looking for a gift for my 25-year-old sister who loves painting."
25
+ recommendations = recommender.get_gift_recommendations(text)
26
+ print(recommender.format_recommendations(recommendations))
27
+ ```
28
+
29
+ ## Features
30
+
31
+ - Natural language processing for gift preferences
32
+ - Sentiment analysis for interest weighting
33
+ - Customizable gift categories and rules
34
+ - Detailed recommendation explanations
35
+
36
+ ## Contributing
37
+
38
+ 1. Fork the repository
39
+ 2. Create your feature branch (`git checkout -b feature/AmazingFeature`)
40
+ 3. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
41
+ 4. Push to the branch (`git push origin feature/AmazingFeature`)
42
+ 5. Open a Pull Request
app.py ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ from transformers import pipeline
4
+
5
+ # Load NLP model
6
+ zero_shot = pipeline("zero-shot-classification", model="facebook/bart-large-mnli")
7
+
8
+ # 🎁 Web search for gift suggestions
9
+ def search_gifts(query):
10
+ amazon_url = f"https://www.amazon.in/s?k={query.replace(' ', '+')}"
11
+ igp_url = f"https://www.igp.com/search?q={query.replace(' ', '+')}"
12
+ indiamart_url = f"https://dir.indiamart.com/search.mp?ss={query.replace(' ', '+')}"
13
+
14
+ return {"Amazon": amazon_url, "IGP": igp_url, "IndiaMart": indiamart_url}
15
+
16
+ # 🎯 Main function for gift recommendation
17
+ def recommend_gifts(text):
18
+ if not text:
19
+ return "Please enter a description."
20
+
21
+ # NLP Processing
22
+ categories = ["art", "music", "tech", "travel", "books", "fashion", "fitness", "gaming"]
23
+ results = zero_shot(text, categories)
24
+
25
+ # Get top interest
26
+ top_interest = results["labels"][0]
27
+
28
+ # Search for gifts based on interest
29
+ links = search_gifts(top_interest)
30
+
31
+ return {
32
+ "Predicted Interest": top_interest,
33
+ "Gift Suggestions": links
34
+ }
35
+
36
+ # 🎨 Gradio UI for easy interaction
37
+ demo = gr.Interface(
38
+ fn=recommend_gifts,
39
+ inputs="text",
40
+ outputs="json",
41
+ title="🎁 AI Gift Recommender",
42
+ description="Enter details about the person you are buying a gift for, and get personalized suggestions with shopping links!",
43
+ )
44
+
45
+ # πŸš€ Launch Gradio App
46
+ if __name__ == "__main__":
47
+ demo.launch()
demo.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from src.recommender import GiftRecommender
2
+
3
+ def main():
4
+ recommender = GiftRecommender()
5
+ print("\n🎁 Gift Recommendation System")
6
+ print("-" * 30)
7
+ print("Example: '25-year-old sister who loves painting and traveling'")
8
+ print("Or simply enter an interest like 'games' or 'sports'.")
9
+
10
+ while True:
11
+ try:
12
+ text = input("\nWho are you shopping for? ('quit' to exit): ").strip()
13
+ if text.lower() == 'quit':
14
+ break
15
+
16
+ if len(text) < 3:
17
+ print("⚠️ Please provide more details or a valid interest.")
18
+ continue
19
+
20
+ # Get recommendations
21
+ results = recommender.get_gift_recommendations(text)
22
+
23
+ # If no structured interests found, assume the input itself is an interest
24
+ if not results['profile']['interests']:
25
+ print(f"\nπŸ” No specific interests found, assuming '{text}' is the interest.")
26
+ results['profile']['interests'].append({'phrase': text, 'category': text, 'confidence': 1.0, 'sentiment': 'POSITIVE', 'sentiment_score': 1.0})
27
+
28
+ # Fetch new recommendations based on this interest
29
+ results['recommendations'] = recommender.generate_gift_ideas(text)
30
+
31
+ print("\n" + recommender.format_recommendations(results))
32
+
33
+ print("\n🎁 Suggested Gifts:")
34
+ for i, rec in enumerate(results['recommendations'], 1):
35
+ print(f"{i}. {rec['gift']}")
36
+
37
+ except Exception as e:
38
+ print(f"\n❌ Error: {str(e)}")
39
+ print("πŸ”„ Please try again with different wording.")
40
+
41
+ if __name__ == "__main__":
42
+ main()
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ flask
2
+ transformers>=4.30.0
3
+ torch>=2.0.0
4
+ numpy>=1.24.0
5
+ pytest>=7.3.1
6
+ gunicorn
7
+ requests
8
+ sentence-transformers
9
+ gradio
test_run.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from src.recommender import GiftRecommender
2
+
3
+ recommender = GiftRecommender()
4
+ text = "I'm looking for a gift for my 25-year-old sister who loves painting."
5
+ results = recommender.get_gift_recommendations(text)
6
+ print(recommender.format_recommendations(results))