本系统是一个基于机器学习和大语言模型的动漫个性化推荐系统。系统结合用户历史数据分析、协同过滤算法、内容推荐以及AI联网搜索,为用户提供精准的动漫推荐服务。
(1)用户画像分析:基于观影历史生成多维度用户画像,包括统计特征、兴趣分布、智能标签等。
(2)混合推荐算法:采用协同过滤(权重60%)和内容推荐(权重40%)加权融合,并使用热门推荐作为兜底策略。
(3)AI智能搜索:利用LLM生成个性化搜索词,通过Exa搜索引擎联网获取最新动漫资讯。
(4)LLM推荐报告:基于搜索结果生成个性化推荐报告,包含8-10部推荐动漫及推荐理由。
| 指标 | 数量 | 说明 |
|---|---|---|
| 动漫总数 | 12,294 | anime.csv数据集 |
| 评分记录 | 6,337,241 | rating.csv数据集,已剔除未打分记录 |
| 有效用户 | 69,600 | 至少有一条有效评分的用户 |
| 类别 | 技术 | 用途 |
|---|---|---|
| 前端框架 | Streamlit | 快速构建数据应用Web界面 |
| 数据处理 | Pandas, NumPy | 数据读取、清洗、统计分析 |
| 机器学习 | Scikit-learn | TF-IDF向量化、余弦相似度计算 |
| 可视化 | Plotly | 交互式雷达图展示用户兴趣分布 |
| 搜索引擎 | Exa AI | 神经语义搜索、AI智能摘要 |
| 大语言模型 | OpenAI Compatible API | 搜索词生成、推荐报告生成 |
系统采用模块化三层架构设计,完整的推荐流程如下:
数据加载 → 用户画像生成 → 混合推荐算法 → AI联网搜索 → LLM推荐报告生成
recommendsys/ ├── app.py 主入口,页面配置、流程控制 ├── config.py 配置管理,API Key、Session State ├── data_loader.py 数据加载,CSV读取、预处理、缓存 ├── user_profile.py 用户画像,统计分析、标签生成 ├── recommender.py 推荐算法,CF、Content、混合策略 ├── search.py Exa搜索,联网检索、智能摘要 ├── llm.py LLM调用,搜索词生成、推荐报告 ├── ui.py UI渲染,侧边栏、结果展示 ├── config.json LLM配置文件(运行时自动生成) ├── anime.csv 动漫数据集 ├── rating.csv 用户评分数据集 └── requirements.txt Python依赖
该模块负责管理系统配置,包括LLM API配置的持久化存储和Streamlit Session State的初始化。
主要功能:
(1)load_config():从config.json加载LLM配置,包括api_key、base_url、model_name
(2)save_config():保存LLM配置到本地文件,实现配置持久化
(3)init_session_state():初始化Streamlit Session State,设置默认值
配置项说明:
| 配置项 | 默认值 | 说明 |
|---|---|---|
| api_key | 空字符串 | LLM服务的API密钥 |
| base_url | https://api.openai.com/v1 | API端点地址 |
| model_name | gpt-3.5-turbo | 模型名称 |
| EXA_API_KEY | 硬编码在代码中 | Exa搜索引擎API Key |
该模块负责加载和预处理动漫数据集和评分数据集,使用Streamlit缓存机制提升性能。
主要功能:
(1)load_anime_data():加载动漫数据,预处理风格标签和HTML实体
(2)load_rating_data():加载评分数据,剔除rating==-1的未打分记录
(3)get_data_stats():计算并缓存数据统计结果
数据预处理步骤:
(1)风格字符串转列表:将逗号分隔的genre字符串转为genre_list列表,便于后续分析
(2)HTML实体清理:替换'为单引号,替换&为&符号
(3)剔除无效评分:过滤rating==-1的记录,这些记录表示用户观看但未打分
缓存策略:
所有数据加载函数都使用@st.cache_data装饰器,首次加载后数据会被缓存,后续请求直接从缓存读取,大幅提升响应速度。
该模块基于用户的观影历史和评分数据,生成多维度的用户画像。
画像生成流程:
获取用户评分数据 → 计算统计特征 → 分析类型偏好 → 生成智能标签 → 输出完整画像
画像字段说明:
| 字段 | 类型 | 说明 |
|---|---|---|
| user_id | int | 用户ID |
| total_watched | int | 观影总数 |
| avg_rating | float | 平均评分 |
| std_rating | float | 评分标准差,反映评分波动程度 |
| max_rating/min_rating | int | 最高/最低评分 |
| rating_distribution | dict | 评分分布,格式为{分数:数量} |
| top_genres | list | 高分动漫的Top5风格 |
| all_genres_weighted | list | 所有风格的加权统计Top8 |
| genre_diversity | int | 类型覆盖数,反映观影多样性 |
| watched_anime_ids | set | 已观看动漫ID集合 |
| top_anime | list | 评分最高的10部动漫 |
| low_anime | list | 评分最低的5部动漫 |
| user_tags | list | 用户标签列表 |
类型偏好计算方法:
使用评分作为权重进行加权统计。对于用户观看的每部动漫,将其评分除以10作为权重(范围0-1),累加到对应的风格类型上。这样高分动漫的风格权重更高,更能代表用户的真实偏好。
智能标签生成规则:
观影量标签:观影数≥200为"资深宅",≥100为"老二次元",≥50为"入坑中",其他为"新人"
评分习惯标签:平均分≥8为"宽容派",≤5为"严格派";标准差≥2.5为"爱憎分明",≤1为"佛系评分"
类型偏好标签:根据主要风格生成,如Action对应"热血党",Romance对应"恋爱脑",Sci-Fi对应"科幻迷"等
多样性标签:类型覆盖≥20种为"杂食党",≤5种为"专一派"
协同过滤基于"相似用户喜欢的动漫,你也可能喜欢"的假设,通过皮尔逊相关系数计算用户相似度。
算法步骤:
第一步,寻找候选用户:找到与目标用户有共同观看记录的用户,要求至少有5部共同观看的作品,最多考虑500个候选用户。
第二步,计算皮尔逊相关系数:对于每个候选用户,提取共同观看动漫的评分,计算皮尔逊相关系数作为相似度。只保留正相关(相似度>0)的用户。
第三步,筛选候选动漫:获取相似用户评分≥7的动漫,排除目标用户已观看的,要求至少有2个相似用户推荐同一部动漫。
第四步,加权评分预测:使用相似度作为权重计算预测评分,并考虑推荐人数的影响。
综合得分公式:
predicted_rating = Σ(similarity × rating) / Σ(similarity) score = predicted_rating × log(recommend_count + 1)
其中similarity为用户相似度,rating为相似用户对该动漫的评分,recommend_count为推荐该动漫的相似用户数量。使用对数函数平滑推荐人数的影响,避免热门动漫过度占优。
内容推荐基于"你喜欢某种类型的动漫,就会喜欢同类型的其他动漫"的假设,使用TF-IDF向量化动漫风格。
算法步骤:
第一步,TF-IDF向量化:将所有动漫的风格标签转换为TF-IDF向量,捕捉每种类型的重要性。
第二步,构建用户偏好向量:根据用户画像中的加权风格统计,构建用户偏好的TF-IDF向量。高权重的风格会被重复多次以增加其影响力。
第三步,余弦相似度计算:计算用户偏好向量与所有动漫向量的余弦相似度,筛选相似度>0.1的动漫作为候选。
第四步,全局评分融合:结合动漫的全局评分,平衡个性化推荐和质量保证。
综合得分公式:
score = similarity × 0.6 + (global_rating / 10) × 0.4
其中similarity为余弦相似度,global_rating为动漫的全局平均评分。相似度权重60%,全局评分权重40%。
混合策略将协同过滤和内容推荐的结果进行加权融合,并在推荐数量不足时使用热门推荐兜底。
融合流程:
第一步,协同过滤生成15条候选推荐
第二步,内容推荐生成15条候选推荐
第三步,对两个列表中的动漫进行加权融合,同时出现在两个列表中的动漫会获得更高的综合得分
第四步,按综合得分排序,取Top15
第五步,如果推荐数量不足5条,使用高评分热门动漫进行补充
最终融合公式:
final_score = CF_score × 0.6 + Content_score × 0.4
协同过滤权重60%,内容推荐权重40%。每条推荐会标记其来源:CF(仅协同过滤)、Content(仅内容推荐)、CF+Content(两者都推荐)、Popular(热门兜底)。
系统使用Exa AI搜索引擎进行联网搜索,获取最新的动漫资讯和推荐信息。
关于Exa:
Exa(原名Metaphor)是专为AI设计的搜索引擎,成立于2021年,总部位于旧金山,已获得超过1.1亿美元融资,投资方包括Lightspeed、NVIDIA、Y Combinator和Benchmark等。与传统搜索引擎依赖关键词匹配不同,Exa使用神经网络进行语义搜索,能够理解查询的真实意图。
搜索配置参数:
| 参数 | 值 | 说明 |
|---|---|---|
| type | auto | 自动选择最优搜索策略 |
| num_results | 10 | 返回结果数量 |
| summary | 自定义提示词 | AI智能摘要配置 |
| exclude_domains | 社交媒体列表 | 排除低质量来源 |
排除的域名:
facebook.com、tiktok.com、twitter.com、x.com、instagram.com、reddit.com、pinterest.com
AI智能摘要提示词:
提取动漫名称、类型、剧情简介、播出时间、制作公司、评分等关键信息,重点关注推荐理由和适合人群
该模块使用大语言模型生成个性化搜索关键词和最终推荐报告。
搜索词生成:
LLM根据用户画像(喜欢的风格、高分动漫、算法推荐结果)生成个性化的英文搜索关键词。输入上下文包括用户喜欢的风格Top5、喜欢的动漫Top5、算法推荐Top5、当前年份。输出为一行英文搜索关键词,例如"2025 anime like Steins;Gate sci-fi thriller recommendations"。
推荐报告生成:
将用户画像和Exa搜索结果输入LLM,生成个性化推荐报告。报告包含两部分:用户侧写(一句话点评用户类型)和新番推荐(8-10部动漫,每部包含中英文名称、类型风格、推荐理由、来源链接)。
LLM配置参数:
| 参数 | 值 | 说明 |
|---|---|---|
| temperature | 0.7 | 生成多样性,适中的创造性 |
| max_tokens | 2500 | 最大输出长度,确保完整输出 |
| system prompt | 专业动漫推荐分析师 | 角色设定,简洁专业风格 |
重要约束:
(1)只推荐搜索结果中明确提到的动漫,不编造信息
(2)使用简洁的商务风格,不使用emoji
(3)每条推荐都附带来源链接,确保可追溯
该模块负责所有Streamlit界面的渲染,包括侧边栏、用户画像、推荐结果和AI搜索结果的展示。
主要函数:
| 函数 | 说明 |
|---|---|
| setup_page_style() | 配置页面CSS样式 |
| render_sidebar() | 渲染侧边栏控制面板,包括用户ID输入、联网搜索开关、AI配置 |
| render_header() | 渲染页面标题 |
| render_data_overview() | 渲染数据概览卡片 |
| render_user_profile() | 渲染用户画像,包括标签、指标、雷达图、喜爱动漫列表 |
| render_recommendations() | 渲染算法推荐结果列表 |
| render_ai_search() | 渲染AI智能搜索部分,显示搜索词和Exa搜索结果 |
| render_ai_recommendation() | 渲染AI最终推荐报告 |
UI设计风格:
配色:黑白商务风格,主色调#1a1a1a
卡片:圆角边框,悬停时显示阴影效果
标签:黑底白字,圆角胶囊形状
图表:使用Plotly绘制交互式雷达图展示用户兴趣分布
Python 3.8及以上版本
pip包管理器
第一步,安装Python依赖:
pip install -r requirements.txt
第二步,准备数据文件:确保anime.csv和rating.csv在项目目录下
第三步,启动应用:
streamlit run app.py
第四步,访问应用:浏览器打开 http://localhost:8501
streamlit>=1.28.0 pandas>=2.0.0 numpy>=1.24.0 scikit-learn>=1.3.0 plotly>=5.18.0 openai>=1.0.0 exa-py>=1.0.0
在侧边栏展开"AI配置",填写以下信息:
| 参数 | 说明 | 示例 |
|---|---|---|
| API Key | LLM服务的API密钥 | sk-xxx |
| Base URL | API端点地址 | https://api.openai.com/v1 |
| Model | 模型名称 | gpt-3.5-turbo |
支持的LLM服务:
| 服务 | Base URL |
|---|---|
| OpenAI | https://api.openai.com/v1 |
| Azure OpenAI | https://your-resource.openai.azure.com |
| DeepSeek | https://api.deepseek.com/v1 |
| Ollama本地部署 | http://localhost:11434/v1 |
(1)首次加载数据需要几秒钟,之后会被缓存,后续访问速度会很快。
(2)AI联网搜索功能需要配置有效的LLM API Key才能使用。
(3)Exa搜索引擎有免费额度限制,超出后需要付费。
(4)新用户(观影数量较少)的推荐效果可能较差,因为缺乏足够的历史数据进行分析。
(5)协同过滤算法要求用户至少有5部共同观看的作品才能计算相似度。
(6)LLM配置会自动保存到config.json文件,刷新页面不会丢失。