Spaces:
Paused
Paused
File size: 6,097 Bytes
4f92a9b c5e5f2b 4f92a9b c5e5f2b 7dfabe3 4f92a9b 7dfabe3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | from flask import Flask, request, jsonify
from flask_cors import CORS
import pickle
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
import json
app = Flask(__name__)
CORS(app)
import os
similarity_matrix = None
model_path = 'model/events_similarity.pkl'
if os.path.exists(model_path):
try:
with open(model_path, 'rb') as f:
similarity_matrix = pickle.load(f)
print("Loaded pre-trained similarity matrix")
except Exception as e:
similarity_matrix = None
print(f"Error loading similarity matrix: {e}")
else:
print("No pre-trained model found, using dynamic calculation")
@app.route('/recommend', methods=['POST'])
def recommend_events():
try:
data = request.json
user_profile = data.get('userProfile', {})
available_events = data.get('availableEvents', [])
limit = data.get('limit', 10)
if not available_events:
return jsonify({
'recommendations': [],
'message': 'No events available for recommendation'
})
# Extract user interests and event features
user_interests = user_profile.get('interests', [])
user_skills = user_profile.get('skills', [])
attended_events = user_profile.get('attendedEvents', [])
# Create user profile vector
user_profile_text = ' '.join(user_interests + user_skills)
# Create event feature vectors
event_features = []
for event in available_events:
event_text = f"{event.get('title', '')} {event.get('description', '')} {' '.join(event.get('tags', []))} {event.get('type', '')} {event.get('organizer', '')}"
event_features.append(event_text)
# Calculate similarity using TF-IDF and cosine similarity
if event_features:
vectorizer = TfidfVectorizer(stop_words='english', max_features=1000)
event_vectors = vectorizer.fit_transform(event_features)
# Add user profile to the vector space
user_vector = vectorizer.transform([user_profile_text])
# Calculate similarities
similarities = cosine_similarity(user_vector, event_vectors).flatten()
# Create recommendations
recommendations = []
for i, event in enumerate(available_events):
similarity_score = float(similarities[i])
# Boost score based on user history
if event.get('organizer') in [e.get('organizer') for e in attended_events]:
similarity_score += 0.2
if event.get('type') in user_interests:
similarity_score += 0.3
# Add common tags bonus
event_tags = set(event.get('tags', []))
user_interest_tags = set(user_interests)
common_tags = event_tags.intersection(user_interest_tags)
similarity_score += len(common_tags) * 0.1
recommendations.append({
'eventId': event.get('eventId'),
'similarityScore': round(similarity_score, 3),
'reason': _get_recommendation_reason(event, user_profile, similarity_score)
})
# Sort by similarity score and return top recommendations
recommendations.sort(key=lambda x: x['similarityScore'], reverse=True)
recommendations = recommendations[:limit]
return jsonify({
'recommendations': recommendations,
'message': 'Recommendations generated successfully'
})
else:
return jsonify({
'recommendations': [],
'message': 'No event features available'
})
except Exception as e:
return jsonify({
'error': f'Error generating recommendations: {str(e)}',
'recommendations': []
}), 500
def _get_recommendation_reason(event, user_profile, similarity_score):
reasons = []
user_interests = user_profile.get('interests', [])
attended_events = user_profile.get('attendedEvents', [])
# Check for interest matches
event_tags = set(event.get('tags', []))
user_interest_tags = set(user_interests)
common_tags = event_tags.intersection(user_interest_tags)
if common_tags:
reasons.append(f"Matches your interests: {', '.join(common_tags)}")
if event.get('type') in user_interests:
reasons.append(f"Matches your preferred event type: {event.get('type')}")
# Check for organizer preference
if event.get('organizer') in [e.get('organizer') for e in attended_events]:
reasons.append(f"From organizer you've attended before: {event.get('organizer')}")
if similarity_score > 0.5:
reasons.append("High similarity to your profile")
elif similarity_score > 0.2:
reasons.append("Moderate similarity to your profile")
else:
reasons.append("Popular event")
return '; '.join(reasons) if reasons else "Recommended for you"
@app.route('/health', methods=['GET'])
def health_check():
return jsonify({
'status': 'healthy',
'service': 'ML Recommendation API',
'model_loaded': similarity_matrix is not None
})
@app.route('/', methods=['GET'])
def root():
return jsonify({
'message': 'ML Recommendation API',
'version': '1.0.0',
'status': 'healthy'
})
if __name__ == '__main__':
port = int(os.environ.get('PORT', 7860))
print(f"Starting ML Recommendation API server on port {port}...")
print("Available endpoints:")
print("- POST /recommend: Generate event recommendations")
print("- GET /health: Health check")
app.run(host='0.0.0.0', port=port, debug=False) |