尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

如何快速构建推荐系统API:Surprise框架的Flask部署完整指南

如何快速构建推荐系统API:Surprise框架的Flask部署完整指南 如何快速构建推荐系统APISurprise框架的Flask部署完整指南【免费下载链接】SurpriseSurprise - 这是一个关于推荐系统和协同过滤的开源项目包含了一些关于推荐算法、协同过滤、Python 语言的示例和教程。适用于推荐系统、协同过滤、Python 语言编程等场景。项目地址: https://gitcode.com/gh_mirrors/su/SurpriseSurprise是一个强大的Python推荐系统库专为处理显式评分数据而设计。本文将详细介绍如何使用Flask框架将Surprise模型部署为REST API服务让您的推荐算法能够快速集成到Web应用和移动应用中。Surprise框架简介与核心功能SurpriseSimple Python RecommendatIon System Engine是一个Python scikit风格的推荐系统库专注于显式评分数据的处理。该框架提供了多种预置算法包括矩阵分解SVD、SVD、NMF、协同过滤k-NN、Slope One、基线算法和聚类算法等。核心模块路径预测算法模块surprise/prediction_algorithms/模型选择模块surprise/model_selection/数据集处理模块surprise/dataset.py训练集处理模块surprise/trainset.py环境准备与项目安装首先我们需要准备Python环境和安装必要的依赖包。推荐使用Python 3.8版本# 克隆Surprise项目 git clone https://gitcode.com/gh_mirrors/su/Surprise cd Surprise # 安装Surprise库 pip install scikit-surprise # 安装Flask和相关依赖 pip install flask flask-cors numpy pandas如果您使用conda环境可以使用以下命令conda install -c conda-forge scikit-surprise flask flask-cors构建推荐模型训练服务1. 创建Flask应用结构首先我们创建一个完整的Flask应用结构来管理推荐系统服务recommendation_api/ ├── app.py # 主应用文件 ├── models/ │ ├── __init__.py │ └── recommendation_model.py # 模型训练和预测逻辑 ├── utils/ │ ├── __init__.py │ └── data_loader.py # 数据加载工具 ├── requirements.txt └── config.py # 配置文件2. 模型训练与保存在models/recommendation_model.py中我们创建一个完整的模型训练类import pickle from surprise import Dataset, Reader, SVD from surprise.model_selection import cross_validate from surprise.dump import dump, load import pandas as pd import os class RecommendationModel: def __init__(self, model_pathmodels/svd_model.pkl): self.model_path model_path self.model None self.trainset None def train_from_dataframe(self, ratings_df, rating_scale(1, 5)): 从DataFrame训练模型 reader Reader(rating_scalerating_scale) data Dataset.load_from_df(ratings_df[[user_id, item_id, rating]], reader) # 使用SVD算法 self.model SVD(n_factors100, n_epochs20, lr_all0.005, reg_all0.02) # 训练模型 trainset data.build_full_trainset() self.model.fit(trainset) self.trainset trainset # 保存模型 self.save_model() return self.model def train_from_builtin(self, dataset_nameml-100k): 使用内置数据集训练模型 data Dataset.load_builtin(dataset_name) self.model SVD() # 交叉验证评估 cv_results cross_validate(self.model, data, measures[RMSE, MAE], cv5, verboseTrue) # 完整训练 trainset data.build_full_trainset() self.model.fit(trainset) self.trainset trainset self.save_model() return cv_results def predict(self, user_id, item_id): 预测用户对物品的评分 if not self.model: self.load_model() return self.model.predict(user_id, item_id).est def get_top_n_recommendations(self, user_id, n10): 获取用户的Top-N推荐 if not self.model or not self.trainset: self.load_model() # 获取用户未评分的物品 user_items set([iid for (uid, iid, _) in self.trainset.all_ratings() if uid user_id]) all_items set([iid for (_, iid, _) in self.trainset.all_ratings()]) unrated_items all_items - user_items # 预测评分并排序 predictions [] for item_id in unrated_items: pred self.model.predict(user_id, item_id) predictions.append((item_id, pred.est)) # 返回Top-N推荐 predictions.sort(keylambda x: x[1], reverseTrue) return predictions[:n] def save_model(self): 保存模型到文件 with open(self.model_path, wb) as f: pickle.dump({ model: self.model, trainset: self.trainset }, f) def load_model(self): 从文件加载模型 if os.path.exists(self.model_path): with open(self.model_path, rb) as f: data pickle.load(f) self.model data[model] self.trainset data[trainset] else: raise FileNotFoundError(fModel file not found: {self.model_path})3. 创建Flask API服务在app.py中我们创建主要的Flask应用from flask import Flask, request, jsonify from flask_cors import CORS from models.recommendation_model import RecommendationModel import pandas as pd import json app Flask(__name__) CORS(app) # 允许跨域请求 # 初始化模型 model RecommendationModel() app.route(/) def home(): return jsonify({ message: Surprise Recommendation API, version: 1.0.0, endpoints: [ /api/train, /api/predict, /api/recommend, /api/health ] }) app.route(/api/health, methods[GET]) def health_check(): 健康检查端点 return jsonify({status: healthy, service: surprise-recommendation}) app.route(/api/train, methods[POST]) def train_model(): 训练推荐模型 try: data request.json if dataset in data and data[dataset] ml-100k: # 使用内置数据集训练 results model.train_from_builtin() return jsonify({ success: True, message: Model trained successfully with built-in dataset, cv_results: results }) elif ratings in data: # 使用自定义数据训练 ratings_df pd.DataFrame(data[ratings]) model.train_from_dataframe(ratings_df) return jsonify({ success: True, message: Model trained successfully with custom data, data_shape: ratings_df.shape }) else: return jsonify({ success: False, error: Invalid request data }), 400 except Exception as e: return jsonify({ success: False, error: str(e) }), 500 app.route(/api/predict, methods[POST]) def predict_rating(): 预测用户对物品的评分 try: data request.json user_id data.get(user_id) item_id data.get(item_id) if not user_id or not item_id: return jsonify({ success: False, error: Missing user_id or item_id }), 400 prediction model.predict(user_id, item_id) return jsonify({ success: True, user_id: user_id, item_id: item_id, predicted_rating: round(prediction, 3), message: Prediction successful }) except Exception as e: return jsonify({ success: False, error: str(e) }), 500 app.route(/api/recommend, methods[POST]) def get_recommendations(): 获取用户推荐列表 try: data request.json user_id data.get(user_id) n data.get(n, 10) # 默认返回10个推荐 if not user_id: return jsonify({ success: False, error: Missing user_id }), 400 recommendations model.get_top_n_recommendations(user_id, n) return jsonify({ success: True, user_id: user_id, recommendations: [ {item_id: item_id, predicted_rating: round(rating, 3)} for item_id, rating in recommendations ], count: len(recommendations) }) except Exception as e: return jsonify({ success: False, error: str(e) }), 500 app.route(/api/batch_predict, methods[POST]) def batch_predict(): 批量预测评分 try: data request.json predictions data.get(predictions, []) if not predictions: return jsonify({ success: False, error: No predictions provided }), 400 results [] for pred in predictions: user_id pred.get(user_id) item_id pred.get(item_id) if user_id and item_id: rating model.predict(user_id, item_id) results.append({ user_id: user_id, item_id: item_id, predicted_rating: round(rating, 3) }) return jsonify({ success: True, predictions: results, count: len(results) }) except Exception as e: return jsonify({ success: False, error: str(e) }), 500 if __name__ __main__: app.run(debugTrue, host0.0.0.0, port5000)4. 创建配置文件在config.py中我们添加配置信息import os class Config: # Flask配置 SECRET_KEY os.environ.get(SECRET_KEY) or surprise-recommendation-secret-key # 模型配置 MODEL_PATH models/svd_model.pkl # 数据集配置 DEFAULT_DATASET ml-100k RATING_SCALE (1, 5) # 算法配置 ALGORITHM_CONFIG { n_factors: 100, n_epochs: 20, lr_all: 0.005, reg_all: 0.02, verbose: False } # API配置 API_HOST 0.0.0.0 API_PORT 5000 DEBUG True部署与运行指南1. 启动API服务创建run.py文件来启动服务from app import app from config import Config if __name__ __main__: app.run( hostConfig.API_HOST, portConfig.API_PORT, debugConfig.DEBUG )运行服务python run.py2. 使用Docker容器化部署创建DockerfileFROM python:3.9-slim WORKDIR /app # 安装系统依赖 RUN apt-get update apt-get install -y \ gcc \ g \ rm -rf /var/lib/apt/lists/* # 复制依赖文件 COPY requirements.txt . # 安装Python依赖 RUN pip install --no-cache-dir -r requirements.txt # 复制应用代码 COPY . . # 创建模型目录 RUN mkdir -p models # 暴露端口 EXPOSE 5000 # 启动应用 CMD [python, run.py]创建docker-compose.ymlversion: 3.8 services: recommendation-api: build: . ports: - 5000:5000 volumes: - ./models:/app/models - ./data:/app/data environment: - FLASK_ENVproduction - SECRET_KEYyour-secret-key-here restart: unless-stopped启动Docker服务docker-compose up -d3. API使用示例训练模型curl -X POST http://localhost:5000/api/train \ -H Content-Type: application/json \ -d {dataset: ml-100k}获取单条预测curl -X POST http://localhost:5000/api/predict \ -H Content-Type: application/json \ -d {user_id: 196, item_id: 302}获取推荐列表curl -X POST http://localhost:5000/api/recommend \ -H Content-Type: application/json \ -d {user_id: 196, n: 5}批量预测curl -X POST http://localhost:5000/api/batch_predict \ -H Content-Type: application/json \ -d { predictions: [ {user_id: 196, item_id: 302}, {user_id: 196, item_id: 303}, {user_id: 196, item_id: 304} ] }性能优化与监控1. 添加缓存机制为了提高API响应速度我们可以添加Redis缓存import redis from functools import wraps import json # 初始化Redis连接 redis_client redis.Redis(hostlocalhost, port6379, db0) def cache_response(expire_time300): 缓存装饰器 def decorator(f): wraps(f) def decorated_function(*args, **kwargs): # 生成缓存键 cache_key fapi:{f.__name__}:{str(kwargs)} # 尝试从缓存获取 cached_data redis_client.get(cache_key) if cached_data: return json.loads(cached_data) # 执行函数 result f(*args, **kwargs) # 缓存结果 redis_client.setex(cache_key, expire_time, json.dumps(result)) return result return decorated_function return decorator # 在API端点使用缓存 app.route(/api/predict, methods[POST]) cache_response(expire_time60) # 缓存1分钟 def predict_rating(): # ... 原有代码2. 添加日志记录创建日志配置import logging from logging.handlers import RotatingFileHandler def setup_logging(app): 配置日志记录 # 创建日志目录 if not os.path.exists(logs): os.mkdir(logs) # 文件处理器 file_handler RotatingFileHandler( logs/recommendation_api.log, maxBytes10240, backupCount10 ) file_handler.setFormatter(logging.Formatter( %(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d] )) file_handler.setLevel(logging.INFO) # 添加到应用 app.logger.addHandler(file_handler) app.logger.setLevel(logging.INFO) app.logger.info(Recommendation API startup)3. 添加监控端点app.route(/api/metrics, methods[GET]) def get_metrics(): 获取API性能指标 import psutil import time return jsonify({ timestamp: time.time(), memory_usage: psutil.Process().memory_info().rss / 1024 / 1024, # MB cpu_percent: psutil.Process().cpu_percent(), active_connections: len(getattr(app, active_connections, [])), uptime: time.time() - app.start_time if hasattr(app, start_time) else 0 })实际应用场景1. 电商推荐系统将Surprise API集成到电商平台为用户提供个性化商品推荐# 电商推荐集成示例 import requests class EcommerceRecommendation: def __init__(self, api_urlhttp://localhost:5000): self.api_url api_url def get_product_recommendations(self, user_id, categoryNone, limit10): 获取商品推荐 # 获取基础推荐 response requests.post( f{self.api_url}/api/recommend, json{user_id: user_id, n: limit * 2} ) if response.status_code 200: recommendations response.json()[recommendations] # 如果指定了类别进行过滤 if category: recommendations self.filter_by_category(recommendations, category) return recommendations[:limit] return [] def filter_by_category(self, recommendations, category): 按类别过滤推荐 # 这里可以添加业务逻辑比如从数据库查询商品类别 filtered [] for rec in recommendations: # 模拟类别过滤逻辑 if self.get_product_category(rec[item_id]) category: filtered.append(rec) return filtered def get_product_category(self, product_id): 获取商品类别示例 # 实际应用中应该从数据库查询 return electronics # 示例2. 内容平台推荐为内容平台新闻、视频、音乐提供个性化内容推荐class ContentRecommendation: def __init__(self, api_urlhttp://localhost:5000): self.api_url api_url def get_personalized_feed(self, user_id, content_typearticle, limit20): 获取个性化内容流 # 获取推荐内容 response requests.post( f{self.api_url}/api/recommend, json{user_id: user_id, n: limit} ) if response.status_code 200: recommendations response.json()[recommendations] # 添加内容元数据 enriched_recommendations [] for rec in recommendations: content_meta self.get_content_metadata(rec[item_id]) enriched_recommendations.append({ **rec, content_meta: content_meta }) return enriched_recommendations return [] def get_content_metadata(self, content_id): 获取内容元数据 # 实际应用中应该从数据库查询 return { title: fContent {content_id}, type: article, author: Author Name, publish_date: 2024-01-01, read_time: 5 min }故障排除与最佳实践常见问题解决模型训练失败检查数据格式是否正确确保评分数据在指定范围内验证用户ID和物品ID的唯一性API响应缓慢启用缓存机制优化数据库查询考虑使用异步处理内存不足使用更小的因子数量分批处理大数据集考虑使用磁盘存储中间结果性能优化建议模型优化调整SVD算法的超参数n_factors、n_epochs等使用更高效的相似度计算方法考虑使用增量学习更新模型API优化使用Gunicorn或uWSGI部署启用HTTP/2和GZIP压缩实施请求限流监控告警设置性能监控配置错误告警定期检查日志总结与扩展通过本文的指南您已经学会了如何使用Flask将Surprise推荐系统框架部署为REST API服务。这种部署方式具有以下优势✅易于集成标准的REST API接口方便各种客户端调用✅高性能支持批量预测和缓存机制✅可扩展支持Docker容器化部署✅易维护模块化设计便于更新和维护下一步扩展方向添加用户认证和授权机制实现A/B测试框架集成实时数据流处理添加模型版本管理实现自动模型重新训练Surprise框架的Flask API部署为推荐系统的实际应用提供了坚实的基础让您能够快速构建和部署个性化推荐服务。相关资源官方文档示例代码测试用例模型选择模块预测算法模块【免费下载链接】SurpriseSurprise - 这是一个关于推荐系统和协同过滤的开源项目包含了一些关于推荐算法、协同过滤、Python 语言的示例和教程。适用于推荐系统、协同过滤、Python 语言编程等场景。项目地址: https://gitcode.com/gh_mirrors/su/Surprise创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表