event-recomendation / server.py
CampVerse CI
Deploy recommendation from GitHub Actions
c5e5f2b
Raw History Blame Contribute Delete
6.1 kB
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)