如何将基于Python与余弦相似度算法的推荐系统接入Laravel应用
Laravel 集成 Python 推荐系统的几种可行方案
1. REST API 调用(实时推荐首选)
把 Python 推荐系统封装成独立的 API 服务,Laravel 通过 HTTP 请求调用获取结果,这是最通用的跨语言集成方式。
步骤1:Python 端封装 API
用 FastAPI 或 Flask 快速搭建接口,以下是 FastAPI 示例:
# main.py from fastapi import FastAPI import numpy as np from sklearn.metrics.pairwise import cosine_similarity app = FastAPI() # 替换为你实际的余弦相似度推荐逻辑 def calculate_recommendations(user_id): # 示例:模拟用户/物品特征矩阵 user_features = np.array([[1.2, 3.1, 0.8]]) item_features = np.array([[1.1, 3.0, 0.7], [4.5, 2.2, 1.0], [0.5, 1.8, 3.3]]) similarities = cosine_similarity(user_features, item_features)[0] top_item_indices = similarities.argsort()[-3:][::-1] # 取Top3推荐 return [f"item_{idx+1}" for idx in top_item_indices] @app.get("/api/recommend/{user_id}") async def get_recommendations(user_id: int): recommendations = calculate_recommendations(user_id) return {"user_id": user_id, "items": recommendations}
启动 API 服务:
uvicorn main:app --host 0.0.0.0 --port 8000
步骤2:Laravel 端调用 API
使用 Guzzle HTTP 客户端发起请求,先安装依赖:
composer require guzzlehttp/guzzle
控制器中实现调用逻辑:
// app/Http/Controllers/RecommendationController.php namespace App\Http\Controllers; use GuzzleHttp\Client; use Illuminate\Http\Request; class RecommendationController extends Controller { public function fetch(int $userId) { $client = new Client([ 'base_uri' => 'http://localhost:8000/', 'timeout' => 10.0, ]); try { $response = $client->get("api/recommend/{$userId}"); $data = json_decode($response->getBody(), true); return view('recommendations', ['data' => $data]); } catch (\Exception $e) { return back()->with('error', '推荐服务暂时不可用'); } } }
添加路由:
// routes/web.php Route::get('/recommendations/{userId}', [RecommendationController::class, 'fetch']);
2. 命令行直接调用脚本(轻量离线场景)
如果推荐不需要实时生成,可直接让 Laravel 调用 Python 脚本,适合批量计算或低频率请求场景。
步骤1:Python 脚本支持命令行参数
修改你的推荐脚本,接收用户 ID 参数并输出结果:
# recommend.py import sys import numpy as np from sklearn.metrics.pairwise import cosine_similarity def get_recommendations(user_id): # 替换为你的实际推荐逻辑 user_features = np.array([[1.2, 3.1, 0.8]]) item_features = np.array([[1.1, 3.0, 0.7], [4.5, 2.2, 1.0], [0.5, 1.8, 3.3]]) similarities = cosine_similarity(user_features, item_features)[0] top_item_indices = similarities.argsort()[-3:][::-1] return [f"item_{idx+1}" for idx in top_item_indices] if __name__ == "__main__": if len(sys.argv) != 2: print("Usage: python recommend.py <user_id>") sys.exit(1) user_id = int(sys.argv[1]) print("\n".join(get_recommendations(user_id)))
步骤2:Laravel 调用脚本
使用 Laravel 自带的 Process 类执行脚本(Laravel 9+ 内置,低版本需安装 symfony/process):
// 控制器代码片段 use Illuminate\Support\Facades\Process; public function generate(int $userId) { // 替换为你的脚本绝对路径 $result = Process::run("/usr/bin/python3 /path/to/recommend.py {$userId}"); if ($result->successful()) { $items = explode("\n", trim($result->output())); return view('recommendations', ['items' => $items]); } else { return back()->with('error', '推荐生成失败:' . $result->errorOutput()); } }
注意确保 Laravel 运行用户有脚本执行权限,且 Python 路径正确。
3. 共享数据库(批量离线计算最优解)
提前用 Python 批量计算所有用户的推荐结果,存入 Laravel 共用的数据库,Laravel 直接读取数据,性能最优。
步骤1:Python 写入数据库
安装数据库依赖(以 MySQL 为例):
pip install pymysql
Python 脚本中连接 Laravel 数据库并写入结果:
import pymysql # 配置为 Laravel 的数据库信息 conn = pymysql.connect( host='localhost', user='laravel_db_user', password='your_db_password', database='laravel_database' ) cursor = conn.cursor() # 示例:批量计算用户1的推荐结果 user_id = 1 recommendations = ["item_1", "item_2", "item_3"] # 假设存在 user_recommendations 表(需提前在 Laravel 中创建) sql = "REPLACE INTO user_recommendations (user_id, recommendations) VALUES (%s, %s)" cursor.execute(sql, (user_id, ",".join(recommendations))) conn.commit() cursor.close() conn.close()
步骤2:Laravel 读取数据
直接查询数据库获取推荐结果:
// 控制器代码片段 use Illuminate\Support\Facades\DB; public function show(int $userId) { $recStr = DB::table('user_recommendations') ->where('user_id', $userId) ->value('recommendations'); $items = $recStr ? explode(",", $recStr) : []; return view('recommendations', ['items' => $items]); }
可通过 Linux 定时任务(Cron)每天自动运行 Python 脚本更新推荐数据。
4. 异步队列处理(避免阻塞请求)
如果推荐计算耗时较长,用 Laravel 队列异步调用 Python 服务,防止阻塞用户请求。
示例队列任务
// app/Jobs/GenerateRecommendations.php namespace App\Jobs; use GuzzleHttp\Client; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Facades\DB; class GenerateRecommendations implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; protected $userId; public function __construct(int $userId) { $this->userId = $userId; } public function handle() { $client = new Client([ 'base_uri' => 'http://localhost:8000/', 'timeout' => 30.0, ]); $response = $client->get("api/recommend/{$this->userId}"); $data = json_decode($response->getBody(), true); // 存入数据库 DB::table('user_recommendations')->updateOrInsert( ['user_id' => $this->userId], ['recommendations' => json_encode($data['items'])] ); } }
控制器中分发任务:
use App\Jobs\GenerateRecommendations; public function trigger(int $userId) { GenerateRecommendations::dispatch($userId); return back()->with('message', '推荐正在生成,稍后刷新查看'); }
内容的提问来源于stack exchange,提问作者ElhaYassine
相关产品推荐
相关产品推荐

