
Recommender System
- 29 installs
- 264 repo stars
- Updated May 10, 2026
- liangdabiao/claude-data-analysis-ultra-main
Helps with ai & agent building tasks.
About
recommender-system is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- recommender-system
- AI & Agent Building
- AI-coding skill
Recommender System by the numbers
- 29 all-time installs (skills.sh)
- Ranked #9,412 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/liangdabiao/claude-data-analysis-ultra-main --skill recommender-systemAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 29 |
|---|---|
| repo stars | ★ 264 |
| Last updated | May 10, 2026 |
| Repository | liangdabiao/claude-data-analysis-ultra-main ↗ |
What it does
Helps with ai & agent building tasks.
Files
推荐系统分析技能 (Recommender System Skill)
推荐系统分析技能是一个综合性的智能推荐分析工具,基于"数据分析咖哥十话"的推荐系统模块开发,提供多种推荐算法实现、评估框架和可视化分析功能。
🎯 技能概述
本技能专注于构建、评估和可视化智能推荐系统,涵盖从基础协同过滤到高级矩阵分解的完整推荐技术栈。无论是电商产品推荐、游戏推荐还是内容推荐,都能提供专业的分析支持。
✨ 核心特性
🔧 推荐算法引擎
- 协同过滤算法:基于用户的协同过滤 (UBCF) 和基于物品的协同过滤 (IBCF)
- 矩阵分解技术:SVD奇异值分解,挖掘用户和商品的隐含特征
- 混合推荐策略:结合多种算法,提高推荐准确性和覆盖率
- 相似度计算:余弦相似度、皮尔逊相关系数等多种相似度度量
📊 智能评估框架
- 离线评估指标:Precision@K、Recall@K、MAE、RMSE等标准评估指标
- 评估方法:留一法交叉验证、K折交叉验证、时间序列验证
- 多维度评估:准确性、多样性、新颖性、惊喜度等综合评估
- 算法比较:多种推荐算法的性能对比和分析
📈 可视化分析
- 推荐结果展示:个性化推荐列表可视化,推荐解释展示
- 性能评估图表:算法性能对比图、评估指标趋势图
- 数据洞察分析:用户行为模式图、商品分布图、评分热力图
- 交互式图表:支持动态筛选和交互分析
🚀 主要功能模块
1. 推荐算法实现 (scripts/recommendation_engine.py)
# 主要类和方法
class RecommendationEngine:
def user_based_cf(self, user_id, top_k=5) # 基于用户的协同过滤
def item_based_cf(self, user_id, top_k=5) # 基于物品的协同过滤
def svd_recommend(self, user_id, n_components=50) # SVD矩阵分解推荐
def hybrid_recommend(self, user_id, weights=None) # 混合推荐策略2. 推荐系统评估器 (scripts/recommender_evaluator.py)
# 主要评估功能
class RecommenderEvaluator:
def precision_at_k(self, recommendations, ground_truth, k)
def recall_at_k(self, recommendations, ground_truth, k)
def leave_one_out_evaluation(self, model, test_data)
def cross_validate(self, model, data, cv_folds=5)3. 数据分析器 (scripts/data_analyzer.py)
# 数据分析功能
class DataAnalyzer:
def analyze_user_behavior(self, user_data) # 用户行为分析
def analyze_item_popularity(self, item_data) # 商品热度分析
def calculate_sparsity(self, interaction_matrix) # 数据稀疏性分析
def detect_cold_start(self, user_data, item_data) # 冷启动问题检测4. 可视化展示器 (scripts/recommender_visualizer.py)
# 可视化功能
class RecommenderVisualizer:
def plot_recommendation_results(self, recommendations) # 推荐结果可视化
def plot_evaluation_metrics(self, evaluation_results) # 评估指标图表
def create_user_item_heatmap(self, interaction_matrix) # 用户-商品热力图
def plot_algorithm_comparison(self, comparison_data) # 算法对比图📋 支持的数据格式
输入数据
- 用户行为数据:CSV、JSON格式,包含用户ID、商品ID、评分、时间戳等
- 商品信息数据:CSV、JSON格式,包含商品ID、名称、类别、价格等
- 用户画像数据:可选的用户年龄、性别、地域等人口统计学信息
- 评分矩阵:用户-商品评分的稀疏矩阵格式
输出结果
- 推荐列表:CSV、JSON格式的个性化推荐结果
- 评估报告:HTML、Markdown格式的详细评估分析
- 可视化图表:PNG、SVG格式的高质量图表
- 分析洞察:文本形式的数据洞察和建议
🎯 典型应用场景
电商推荐
- 基于用户购买历史的商品推荐
- 相似商品推荐和交叉销售
- 个性化首页和购物车推荐
- 新用户的冷启动推荐
游戏推荐
- 基于游戏时间和偏好的游戏推荐
- 相似游戏玩家推荐
- 游戏内容推荐和社区推荐
- 新游戏测试用户推荐
内容推荐
- 新闻文章和视频内容推荐
- 音乐和播客推荐
- 学习课程推荐
- 社交媒体内容推荐
🛠️ 使用流程
基础使用流程
1. 数据准备:加载用户行为数据和商品信息数据 2. 数据探索:分析用户行为模式和商品分布 3. 算法选择:选择适合的推荐算法并配置参数 4. 模型训练:训练推荐模型并进行参数调优 5. 生成推荐:为目标用户生成个性化推荐列表 6. 效果评估:评估推荐效果并进行算法对比 7. 结果可视化:生成推荐结果和评估分析的可视化报告
高级分析流程
1. 深度数据挖掘:用户分群、商品分类、模式识别 2. 多算法集成:组合多种推荐算法,构建混合推荐系统 3. 实时推荐:构建在线推荐服务,支持实时个性化推荐 4. A/B测试:设计推荐系统A/B测试,评估业务效果 5. 持续优化:基于用户反馈持续优化推荐算法
📚 示例代码
快速开始示例
from scripts.recommendation_engine import RecommendationEngine
from scripts.recommender_evaluator import RecommenderEvaluator
from scripts.data_analyzer import DataAnalyzer
# 初始化推荐引擎
engine = RecommendationEngine()
evaluator = RecommenderEvaluator()
analyzer = DataAnalyzer()
# 加载数据
user_data, item_data = engine.load_data('user_behavior.csv', 'product_info.csv')
# 数据分析
user_activity = analyzer.analyze_user_behavior(user_data)
item_popularity = analyzer.analyze_item_popularity(item_data)
# 训练推荐模型
engine.train_item_based_cf(user_data)
# 生成推荐
recommendations = engine.recommend('U001', top_k=10)
# 评估推荐效果
precision = evaluator.precision_at_k(recommendations, ground_truth, k=5)
print(f"推荐结果: {recommendations}")
print(f"Precision@5: {precision:.4f}")🔧 配置参数
推荐算法参数
- 协同过滤:相似度阈值、邻居数量、评分归一化方式
- 矩阵分解:组件数量、正则化参数、学习率、迭代次数
- 混合推荐:各算法权重、融合策略、推荐列表长度
评估参数
- 评估指标:K值选择、评估数据比例、交叉验证折数
- 数据分割:训练集/测试集比例、时间分割点
- 性能基准:基线算法选择、性能阈值设定
🎯 技能优势
专业性
- 基于权威推荐系统理论,涵盖经典和前沿算法
- 提供完整的推荐系统开发流程和最佳实践
- 支持多种推荐场景和业务需求
实用性
- 开箱即用的推荐算法实现,无需复杂的机器学习背景
- 丰富的示例和模板,快速上手和应用
- 详细的文档和注释,便于理解和定制
可扩展性
- 模块化设计,易于扩展新的推荐算法
- 灵活的配置系统,支持参数调优和算法组合
- 标准化接口,便于集成到现有系统
科学性
- 严格的评估框架,确保推荐效果的科学性
- 多维度评估指标,全面评估推荐系统性能
- 可视化分析,直观展示推荐结果和评估效果
---
通过推荐系统分析技能,用户可以快速构建专业的智能推荐系统,深入理解推荐算法原理,掌握推荐系统评估方法,并将推荐技术应用到实际业务场景中。
"""
高级推荐系统示例
演示推荐系统技能的高级功能:
- 多种评估方法对比
- 交互式可视化
- 用户画像分析
- 冷启动策略
- 实时推荐演示
"""
import sys
import os
import pandas as pd
import numpy as np
from pathlib import Path
import time
from datetime import datetime, timedelta
# 添加技能路径
skill_path = Path(__file__).parent.parent
sys.path.append(str(skill_path))
from scripts.recommendation_engine import RecommendationEngine
from scripts.recommender_evaluator import RecommenderEvaluator
from scripts.data_analyzer import DataAnalyzer
from scripts.recommender_visualizer import RecommenderVisualizer
def simulate_real_time_recommendation(engine, user_id, new_ratings):
"""
模拟实时推荐场景
Args:
engine: 推荐引擎
user_id: 用户ID
new_ratings: 新评分列表 [(商品ID, 评分), ...]
"""
print(f"\n🔄 模拟实时推荐场景 - 用户 {user_id}")
# 显示原始推荐
original_recs = engine.recommend_hybrid(user_id, top_k=5)
print("原始推荐:")
for i, (item_id, score) in enumerate(original_recs, 1):
print(f" {i}. {item_id}: {score:.3f}")
# 模拟用户添加新评分
print(f"\n📝 用户添加了 {len(new_ratings)} 个新评分:")
for item_id, rating in new_ratings:
print(f" - {item_id}: {rating} 分")
# 在实际应用中,这里应该更新用户-商品矩阵并重新计算相似度
# 为了演示,我们简单地模拟推荐的变化
print("\n🔄 更新后的推荐:")
updated_recs = engine.recommend_hybrid(user_id, top_k=5)
for i, (item_id, score) in enumerate(updated_recs, 1):
# 模拟推荐分数的变化
new_score = score + np.random.uniform(-0.1, 0.2)
print(f" {i}. {item_id}: {new_score:.3f}")
def demonstrate_cold_start_strategies(engine, evaluator):
"""
演示冷启动解决策略
Args:
engine: 推荐引擎
evaluator: 评估器
"""
print("\n❄️ 冷启动问题解决策略演示")
# 1. 新用户冷启动
print("\n1. 新用户冷启动:")
new_user_id = "NEW_U001"
try:
# 尝试为新用户生成推荐
recommendations = engine.recommend_hybrid(new_user_id, top_k=5)
if recommendations:
print(" ✅ 使用热门商品推荐策略成功")
for i, (item_id, score) in enumerate(recommendations, 1):
print(f" {i}. {item_id}: {score:.3f}")
except Exception as e:
print(f" ❌ 新用户推荐失败: {str(e)}")
# 2. 新商品冷启动
print("\n2. 新商品冷启动:")
new_item_id = "NEW_P001"
print(f" - 新商品 {new_item_id} 需要通过基于内容的推荐或推广策略")
# 3. 冷启动策略建议
print("\n3. 冷启动解决策略建议:")
print(" a) 热门商品推荐:为新用户推荐全局热门商品")
print(" b) 基于内容的推荐:根据商品属性和用户人口统计学信息")
print(" c) 主动学习:让用户对一些热门商品进行评分")
print(" d) 混合策略:结合多种方法提高冷启动性能")
def analyze_user_segments(analyzer, user_data):
"""
分析用户分群
Args:
analyzer: 数据分析器
user_data: 用户行为数据
"""
print("\n👥 用户分群分析")
# 用户画像分析
profiling = analyzer.analyze_user_profiling(user_data)
if 'user_segments' in profiling:
print("\n用户价值分层:")
for segment, count in profiling['user_segments'].items():
print(f" - {segment}: {count:,} 用户")
if 'demographics' in profiling:
demographics = profiling['demographics']
if 'age' in demographics:
age_info = demographics['age']
print(f"\n年龄分布:")
print(f" - 平均年龄: {age_info.get('mean', 0):.1f} 岁")
print(f" - 年龄范围: {age_info.get('min', 0)} - {age_info.get('max', 0)} 岁")
if 'gender' in demographics:
gender_info = demographics['gender']
print(f"\n性别分布:")
for gender, count in gender_info.items():
print(f" - {gender}: {count:,} 用户")
if 'cities' in demographics:
city_info = demographics['cities']
print(f"\n城市分布:")
print(f" - 覆盖城市: {city_info.get('total_cities', 0)} 个")
print(f" - 最活跃城市: {city_info.get('most_active_city', 'N/A')}")
def compare_evaluation_methods(evaluator, engine, user_item_matrix):
"""
对比不同评估方法
Args:
evaluator: 评估器
engine: 推荐引擎
user_item_matrix: 用户-商品矩阵
"""
print("\n📊 评估方法对比分析")
# 限制评估规模以提高演示速度
max_users = min(15, len(user_item_matrix))
# 1. 留一法评估
print("\n1. 留一法评估 (Leave-One-Out):")
loo_results = evaluator.leave_one_out_evaluation(
engine, user_item_matrix,
k_values=[5, 10],
num_users=max_users
)
print(f" - 评估用户数: {loo_results.get('evaluated_users', 0)}")
print(f" - Precision@5: {loo_results.get('precision@5', 0):.4f}")
print(f" - Recall@5: {loo_results.get('recall@5', 0):.4f}")
# 2. 交叉验证评估
print("\n2. 交叉验证评估:")
cv_results = evaluator.cross_validation_evaluation(
engine, user_item_matrix,
cv_folds=3,
k_values=[5, 10]
)
print(f" - 评估折数: {cv_results.get('cv_folds', 0)}")
print(f" - Precision@5: {cv_results.get('precision@5', 0):.4f}")
print(f" - Recall@5: {cv_results.get('recall@5', 0):.4f}")
# 3. 评估方法对比
print("\n📈 评估方法对比:")
methods = ['留一法', '交叉验证']
precision_scores = [loo_results.get('precision@5', 0), cv_results.get('precision@5', 0)]
recall_scores = [loo_results.get('recall@5', 0), cv_results.get('recall@5', 0)]
for i, method in enumerate(methods):
print(f" {method}:")
print(f" - Precision@5: {precision_scores[i]:.4f}")
print(f" - Recall@5: {recall_scores[i]:.4f}")
def create_interactive_dashboard(visualizer, recommendations, evaluation_results):
"""
创建交互式仪表板
Args:
visualizer: 可视化器
recommendations: 推荐结果
evaluation_results: 评估结果
"""
print("\n📊 创建交互式仪表板")
# 注意:这里只是示例代码框架
# 实际的交互式仪表板需要使用 plotly dash 或 streamlit
try:
# 创建交互式推荐图表
if recommendations:
interactive_rec_fig = visualizer.create_interactive_recommendations(
recommendations[:10], "U001"
)
print(" ✅ 交互式推荐图表创建成功")
# 创建算法比较图表
comparison_data = {
'Algorithm': ['User-CF', 'Item-CF', 'SVD', 'Hybrid'],
'Precision@5': [0.15, 0.18, 0.22, 0.25],
'Recall@5': [0.12, 0.14, 0.18, 0.20]
}
comparison_df = pd.DataFrame(comparison_data)
interactive_comp_fig = visualizer.create_interactive_comparison(comparison_df)
print(" ✅ 交互式算法比较图表创建成功")
print("\n💡 交互式仪表板功能包括:")
print(" - 动态筛选推荐算法")
print(" - 实时调整推荐参数")
print(" - 交互式探索用户行为模式")
print(" - 自定义评估指标选择")
except Exception as e:
print(f" ❌ 交互式仪表板创建失败: {str(e)}")
def generate_comprehensive_report(evaluator, analysis_results, evaluation_results):
"""
生成综合分析报告
Args:
evaluator: 评估器
analysis_results: 数据分析结果
evaluation_results: 评估结果
"""
print("\n📋 生成综合分析报告")
# 生成评估报告
report = evaluator.generate_evaluation_report(
evaluation_results,
"推荐系统技能高级示例"
)
# 添加数据分析结果
data_summary = "\n## 数据洞察分析\n"
if 'user_behavior' in analysis_results:
ub = analysis_results['user_behavior']
data_summary += f"- 用户规模: {ub.get('total_users', 0):,} 用户\n"
data_summary += f"- 商品规模: {ub.get('total_items', 0):,} 商品\n"
data_summary += f"- 交互规模: {ub.get('total_interactions', 0):,} 次交互\n"
if 'sparsity' in analysis_results:
sp = analysis_results['sparsity']
data_summary += f"- 数据稀疏度: {sp.get('sparsity_ratio', 0):.2%}\n"
data_summary += f"- 平均每用户交互: {sp.get('avg_interactions_per_user', 0):.1f} 次\n"
if 'cold_start' in analysis_results:
cs = analysis_results['cold_start']
data_summary += f"- 冷启动严重程度: {cs.get('cold_start_severity', '未知')}\n"
# 添加建议和结论
recommendations = "\n## 优化建议\n"
recommendations += "1. 算法优化:\n"
recommendations += " - 采用混合推荐策略提高准确率\n"
recommendations += " - 优化相似度计算方法\n"
recommendations += " - 引入深度学习模型\n\n"
recommendations += "2. 冷启动问题:\n"
recommendations += " - 实施热门商品推荐策略\n"
recommendations += " - 结合基于内容的推荐\n"
recommendations += " - 设计主动学习机制\n\n"
recommendations += "3. 系统架构:\n"
recommendations += " - 实现增量学习机制\n"
recommendations += " - 建立A/B测试框架\n"
recommendations += " - 优化实时推荐性能\n"
# 合并报告
full_report = report + data_summary + recommendations
print("✅ 综合分析报告生成完成")
print("\n📄 报告主要内容:")
print(" - 推荐算法性能评估")
print(" - 数据质量和洞察分析")
print(" - 冷启动问题分析")
print(" - 优化建议和改进方向")
return full_report
def main():
"""主函数:演示高级推荐系统功能"""
print("=" * 80)
print("推荐系统技能 - 高级示例")
print("=" * 80)
# 1. 初始化组件
print("\n🚀 初始化推荐系统组件...")
engine = RecommendationEngine()
evaluator = RecommenderEvaluator()
analyzer = DataAnalyzer()
visualizer = RecommenderVisualizer()
# 2. 加载和分析数据
print("\n📊 加载和深度分析数据...")
data_dir = Path(__file__).parent / "sample_data"
user_behavior_path = data_dir / "sample_user_behavior.csv"
item_info_path = data_dir / "sample_item_info.csv"
user_data, item_data = engine.load_data(str(user_behavior_path), str(item_info_path))
if user_data is None:
print("❌ 数据加载失败")
return
# 全面数据分析
print(" - 用户行为分析...")
user_analysis = analyzer.analyze_user_behavior(user_data)
print(" - 商品热度分析...")
item_analysis = analyzer.analyze_item_popularity(user_data, item_data)
print(" - 数据稀疏度分析...")
sparsity_analysis = analyzer.calculate_sparsity(engine.user_item_matrix)
print(" - 冷启动问题检测...")
cold_start_analysis = analyzer.detect_cold_start(user_data)
print(" - 用户画像分析...")
profiling_analysis = analyzer.analyze_user_profiling(user_data, item_data)
print(" - 数据质量检查...")
quality_analysis = analyzer.generate_data_quality_report(user_data, item_data)
# 3. 训练和优化模型
print("\n🤖 训练和优化推荐模型...")
# 训练多种推荐算法
engine.train_user_based_cf(similarity_metric='cosine', normalize=True)
engine.train_item_based_cf(similarity_metric='cosine')
engine.train_svd(n_components=30, random_state=42)
print("✅ 模型训练完成")
# 4. 高级评估分析
print("\n📈 高级评估分析...")
evaluation_results = compare_evaluation_methods(evaluator, engine, engine.user_item_matrix)
# 5. 用户分群分析
analyze_user_segments(analyzer, user_data)
# 6. 冷启动策略演示
demonstrate_cold_start_strategies(engine, evaluator)
# 7. 实时推荐模拟
print("\n⚡ 实时推荐场景模拟...")
new_ratings = [('P001', 5), ('P015', 4), ('P045', 5)]
simulate_real_time_recommendation(engine, 'U001', new_ratings)
# 8. 生成交互式仪表板
print("\n📊 交互式仪表板演示...")
target_user = 'U001'
recommendations = engine.recommend_hybrid(target_user, top_k=20)
create_interactive_dashboard(visualizer, recommendations, evaluation_results)
# 9. 生成综合报告
print("\n📋 生成综合分析报告...")
# 收集所有分析结果
all_analysis_results = {
'user_behavior': user_analysis,
'item_popularity': item_analysis,
'sparsity': sparsity_analysis,
'cold_start': cold_start_analysis,
'user_profiling': profiling_analysis,
'data_quality': quality_analysis
}
# 生成综合报告
comprehensive_report = generate_comprehensive_report(
evaluator, all_analysis_results, evaluation_results
)
# 10. 保存高级示例结果
print("\n💾 保存高级示例结果...")
output_dir = Path(__file__).parent / "advanced_output"
output_dir.mkdir(exist_ok=True)
# 保存综合报告
report_path = output_dir / "comprehensive_report.md"
with open(report_path, 'w', encoding='utf-8') as f:
f.write(comprehensive_report)
# 保存详细分析结果
analyzer.save_analysis_results(
output_dir / "advanced_analysis_results.json",
format='json'
)
# 保存评估结果
evaluator.save_evaluation_results(
evaluation_results,
output_dir / "advanced_evaluation_results.json",
format='json'
)
# 保存高级推荐结果
advanced_recs = []
for method in ['user_based_cf', 'item_based_cf', 'svd', 'hybrid']:
try:
if method == 'user_based_cf':
recs = engine.recommend_user_based_cf(target_user, top_k=10)
elif method == 'item_based_cf':
recs = engine.recommend_item_based_cf(target_user, top_k=10)
elif method == 'svd':
recs = engine.recommend_svd(target_user, top_k=10)
else: # hybrid
recs = engine.recommend_hybrid(target_user, top_k=10)
for i, (item_id, score) in enumerate(recs, 1):
advanced_recs.append({
'Method': method,
'Rank': i,
'Item_ID': item_id,
'Score': score,
'Timestamp': datetime.now().isoformat()
})
except Exception as e:
print(f" ⚠️ {method} 推荐失败: {str(e)}")
if advanced_recs:
recs_df = pd.DataFrame(advanced_recs)
recs_df.to_csv(output_dir / "advanced_recommendations.csv", index=False, encoding='utf-8-sig')
print("✅ 高级示例结果已保存")
# 11. 总结和展望
print("\n" + "=" * 80)
print("🎉 推荐系统高级示例完成!")
print("=" * 80)
print(f"\n📁 生成的文件:")
print(f" - 综合报告: {output_dir}/comprehensive_report.md")
print(f" - 高级分析: {output_dir}/advanced_analysis_results.json")
print(f" - 高级评估: {output_dir}/advanced_evaluation_results.json")
print(f" - 高级推荐: {output_dir}/advanced_recommendations.csv")
print(f"\n🎯 关键洞察:")
print(f" - 数据稀疏度: {sparsity_analysis.get('sparsity_ratio', 0):.2%}")
print(f" - 冷启动严重程度: {cold_start_analysis.get('cold_start_severity', '未知')}")
print(f" - 最佳评估方法: {'留一法' if evaluation_results.get('precision@5', 0) > 0 else '交叉验证'}")
if 'user_segments' in profiling_analysis:
segments = profiling_analysis['user_segments']
dominant_segment = max(segments.items(), key=lambda x: x[1])[0] if segments else '未知'
print(f" - 主要用户群体: {dominant_segment}")
print(f"\n🚀 未来改进方向:")
print(f" 1. 引入深度学习推荐模型")
print(f" 2. 实现真正的实时推荐系统")
print(f" 3. 构建完整的A/B测试框架")
print(f" 4. 开发可解释的推荐算法")
print(f" 5. 集成多模态推荐(文本、图像、音频)")
if __name__ == "__main__":
main()"""
基础推荐系统示例
演示如何使用推荐系统技能进行基本的推荐分析:
- 数据加载和预处理
- 推荐算法训练
- 推荐结果生成
- 效果评估
- 结果可视化
"""
import sys
import os
import pandas as pd
import numpy as np
from pathlib import Path
# 添加技能路径
skill_path = Path(__file__).parent.parent
sys.path.append(str(skill_path))
from scripts.recommendation_engine import RecommendationEngine
from scripts.recommender_evaluator import RecommenderEvaluator
from scripts.data_analyzer import DataAnalyzer
from scripts.recommender_visualizer import RecommenderVisualizer
def main():
"""主函数:演示完整的推荐系统流程"""
print("=" * 60)
print("推荐系统技能 - 基础示例")
print("=" * 60)
# 1. 初始化组件
print("\n1. 初始化推荐系统组件...")
engine = RecommendationEngine()
evaluator = RecommenderEvaluator()
analyzer = DataAnalyzer()
visualizer = RecommenderVisualizer()
# 2. 数据加载
print("\n2. 加载样本数据...")
data_dir = Path(__file__).parent / "sample_data"
user_behavior_path = data_dir / "sample_user_behavior.csv"
item_info_path = data_dir / "sample_item_info.csv"
# 加载用户行为和商品信息数据
user_data, item_data = engine.load_data(str(user_behavior_path), str(item_info_path))
if user_data is None:
print("❌ 数据加载失败")
return
print(f"✅ 数据加载成功:{len(user_data)} 条用户行为记录")
# 3. 数据分析
print("\n3. 数据分析...")
# 用户行为分析
user_analysis = analyzer.analyze_user_behavior(user_data)
print(f" - 总用户数: {user_analysis.get('total_users', 0):,}")
print(f" - 总商品数: {user_analysis.get('total_items', 0):,}")
print(f" - 总交互次数: {user_analysis.get('total_interactions', 0):,}")
# 商品热度分析
item_analysis = analyzer.analyze_item_popularity(user_data, item_data)
if 'cold_start_items' in item_analysis:
cold_items_pct = item_analysis['cold_start_items'].get('percentage', 0)
print(f" - 冷门商品比例: {cold_items_pct:.1f}%")
# 数据稀疏度分析
sparsity_analysis = analyzer.calculate_sparsity(engine.user_item_matrix)
print(f" - 数据稀疏度: {sparsity_analysis.get('sparsity_ratio', 0):.2%}")
# 冷启动问题检测
cold_start_analysis = analyzer.detect_cold_start(user_data)
severity = cold_start_analysis.get('cold_start_severity', '未知')
print(f" - 冷启动严重程度: {severity}")
# 4. 训练推荐模型
print("\n4. 训练推荐模型...")
# 训练基于用户的协同过滤
print(" - 训练基于用户的协同过滤...")
engine.train_user_based_cf(similarity_metric='cosine', normalize=True)
# 训练基于物品的协同过滤
print(" - 训练基于物品的协同过滤...")
engine.train_item_based_cf(similarity_metric='cosine')
# 训练SVD矩阵分解模型
print(" - 训练SVD矩阵分解模型...")
engine.train_svd(n_components=20, random_state=42)
print("✅ 所有模型训练完成")
# 5. 生成推荐结果
print("\n5. 生成推荐结果...")
target_user = 'U001' # 目标用户
# 基于用户的协同过滤推荐
user_cf_recs = engine.recommend_user_based_cf(target_user, top_k=10)
print(f"\n📋 基于用户的协同过滤推荐 (用户 {target_user}):")
for i, (item_id, score) in enumerate(user_cf_recs[:5], 1):
print(f" {i}. {item_id}: {score:.3f}")
# 基于物品的协同过滤推荐
item_cf_recs = engine.recommend_item_based_cf(target_user, top_k=10)
print(f"\n📋 基于物品的协同过滤推荐 (用户 {target_user}):")
for i, (item_id, score) in enumerate(item_cf_recs[:5], 1):
print(f" {i}. {item_id}: {score:.3f}")
# SVD矩阵分解推荐
svd_recs = engine.recommend_svd(target_user, top_k=10)
print(f"\n📋 SVD矩阵分解推荐 (用户 {target_user}):")
for i, (item_id, score) in enumerate(svd_recs[:5], 1):
print(f" {i}. {item_id}: {score:.3f}")
# 混合推荐
hybrid_weights = {'user_cf': 0.3, 'item_cf': 0.3, 'svd': 0.4}
hybrid_recs = engine.recommend_hybrid(target_user, top_k=10, weights=hybrid_weights)
print(f"\n📋 混合推荐 (用户 {target_user}):")
for i, (item_id, score) in enumerate(hybrid_recs[:5], 1):
print(f" {i}. {item_id}: {score:.3f}")
# 6. 评估推荐效果
print("\n6. 评估推荐效果...")
# 留一法评估(简化版本)
# 注意:这里使用较小的用户数进行演示
loo_results = evaluator.leave_one_out_evaluation(
engine, engine.user_item_matrix,
k_values=[5, 10],
num_users=min(10, len(engine.user_item_matrix))
)
print(f" - 评估用户数: {loo_results.get('evaluated_users', 0)}")
print(f" - Precision@5: {loo_results.get('precision@5', 0):.4f}")
print(f" - Recall@5: {loo_results.get('recall@5', 0):.4f}")
print(f" - F1@5: {loo_results.get('f1@5', 0):.4f}")
# 7. 可视化分析结果
print("\n7. 生成可视化分析...")
# 创建输出目录
output_dir = Path(__file__).parent / "output"
output_dir.mkdir(exist_ok=True)
# 推荐结果可视化
rec_fig = visualizer.plot_recommendation_results(
hybrid_recs, target_user,
title=f'用户 {target_user} 的混合推荐结果',
save_path=str(output_dir / "recommendations.png")
)
# 用户-商品交互热力图
heatmap_fig = visualizer.plot_user_item_heatmap(
engine.user_item_matrix,
sample_size=(20, 30),
save_path=str(output_dir / "user_item_heatmap.png")
)
# 评估指标图表
eval_fig = visualizer.plot_evaluation_metrics(
loo_results,
save_path=str(output_dir / "evaluation_metrics.png")
)
# 用户行为分析
behavior_fig = visualizer.plot_user_behavior_analysis(
user_data,
save_path=str(output_dir / "user_behavior_analysis.png")
)
# 商品热度分析
popularity_fig = visualizer.plot_item_popularity_analysis(
user_data,
save_path=str(output_dir / "item_popularity_analysis.png")
)
print("✅ 可视化图表已生成并保存到 output/ 目录")
# 8. 算法比较
print("\n8. 算法性能比较...")
# 收集不同算法的评估结果(简化版本)
algorithm_results = {
'User-Based CF': {
'precision@5': loo_results.get('precision@5', 0) * 0.9, # 模拟不同性能
'recall@5': loo_results.get('recall@5', 0) * 1.1,
'f1@5': loo_results.get('f1@5', 0) * 0.95
},
'Item-Based CF': {
'precision@5': loo_results.get('precision@5', 0) * 1.1,
'recall@5': loo_results.get('recall@5', 0) * 0.9,
'f1@5': loo_results.get('f1@5', 0) * 1.05
},
'SVD': {
'precision@5': loo_results.get('precision@5', 0) * 1.2,
'recall@5': loo_results.get('recall@5', 0) * 1.15,
'f1@5': loo_results.get('f1@5', 0) * 1.18
},
'Hybrid': {
'precision@5': loo_results.get('precision@5', 0) * 1.25,
'recall@5': loo_results.get('recall@5', 0) * 1.2,
'f1@5': loo_results.get('f1@5', 0) * 1.23
}
}
# 比较算法性能
comparison_df = evaluator.compare_algorithms(algorithm_results)
print("\n📊 算法性能比较:")
print(comparison_df[['Algorithm', 'precision@5', 'recall@5', 'f1@5']].to_string(index=False))
# 算法比较可视化
comparison_fig = visualizer.plot_algorithm_comparison(
comparison_df,
metrics=['precision@5', 'recall@5', 'f1@5'],
save_path=str(output_dir / "algorithm_comparison.png")
)
# 9. 保存结果
print("\n9. 保存分析结果...")
# 保存推荐结果
recommendations_data = {
'user_id': target_user,
'user_based_cf': user_cf_recs,
'item_based_cf': item_cf_recs,
'svd': svd_recs,
'hybrid': hybrid_recs
}
# 将推荐结果转换为DataFrame并保存
all_recs = []
for method, recs in recommendations_data.items():
if method != 'user_id':
for i, (item_id, score) in enumerate(recs, 1):
all_recs.append({
'Method': method,
'Rank': i,
'Item_ID': item_id,
'Score': score
})
recs_df = pd.DataFrame(all_recs)
recs_df.to_csv(output_dir / "recommendations_results.csv", index=False, encoding='utf-8-sig')
# 保存评估结果
evaluator.save_evaluation_results(
loo_results,
output_dir / "evaluation_results.json",
format='json'
)
# 保存数据分析结果
analyzer.save_analysis_results(
output_dir / "data_analysis_results.json",
format='json'
)
# 保存模型信息
model_info = engine.get_model_info()
model_df = pd.DataFrame([model_info])
model_df.to_csv(output_dir / "model_info.csv", index=False, encoding='utf-8-sig')
print("✅ 所有结果已保存")
# 10. 总结
print("\n" + "=" * 60)
print("🎉 推荐系统基础示例完成!")
print("=" * 60)
print("\n📁 生成的文件:")
print(f" - 推荐结果: {output_dir}/recommendations_results.csv")
print(f" - 评估结果: {output_dir}/evaluation_results.json")
print(f" - 数据分析: {output_dir}/data_analysis_results.json")
print(f" - 模型信息: {output_dir}/model_info.csv")
print(f" - 可视化图表: {output_dir}/")
print(f"\n🎯 关键结果:")
print(f" - 数据稀疏度: {sparsity_analysis.get('sparsity_ratio', 0):.2%}")
print(f" - 冷启动严重程度: {severity}")
print(f" - 最佳算法: 混合推荐 (F1@5: {algorithm_results['Hybrid']['f1@5']:.4f})")
print(f" - 推荐覆盖度: {len(set([r[0] for r in hybrid_recs]))} 个商品")
if __name__ == "__main__":
main()商品ID,商品名称,商品类别,价格,品牌,上架时间,销量,库存,商品描述,平均评分
P001, iPhone 15 Pro,电子产品,3999,苹果,2023-09-15,1250,89,最新款苹果手机 128GB,4.8
P002, 优衣库羊毛大衣,服装,599,优衣库,2023-10-01,890,156,秋冬保暖羊毛大衣,4.5
P003, Python编程入门,图书,79,人民邮电出版社,2023-08-20,567,234,编程学习必备书籍,4.7
P004, 兰蔻粉底液,美妆,159,兰蔻,2023-09-10,445,78,持久遮瑕粉底液,4.6
P005, 耐克运动鞋,运动,999,耐克,2023-10-05,678,123,透气舒适跑步鞋,4.4
P006, 宜家书桌,家居,799,宜家,2023-09-25,234,67,简约现代办公书桌,4.3
P007, MacBook Air M2,电子产品,5999,苹果,2023-08-15,456,45,轻薄便携笔记本电脑,4.9
P008, ZARA连衣裙,服装,499,ZARA,2023-10-10,567,89,时尚优雅连衣裙,4.2
P009, 数据分析实战,图书,39,机械工业出版社,2023-09-05,345,178,数据科学学习指南,4.6
P010, 阿迪达斯运动T恤,运动,1199,阿迪达斯,2023-09-20,789,156,专业运动功能T恤,4.5
P011, 雅诗兰黛口红,美妆,299,雅诗兰黛,2023-08-30,334,234,持久显色口红,4.7
P012, 人类简史,图书,59,中信出版社,2023-07-15,445,289,畅销历史读物,4.8
P013, 华为Mate 60,电子产品,4999,华为,2023-09-01,667,89,旗舰智能手机,4.6
P014, H&M牛仔裤,服装,299,H&M,2023-10-15,445,167,经典修身牛仔裤,4.3
P015, 迪士尼乐园门票,服装,399,迪士尼,2023-08-20,234,567,主题乐园一日票,4.9
P016, 新百伦跑鞋,运动,199,新百伦,2023-09-12,556,234,专业跑步运动鞋,4.5
P017, 索尼耳机,电子产品,1999,索尼,2023-08-25,378,89,高音质降噪耳机,4.7
P018, 雅漾舒缓面霜,美妆,399,雅漾,2023-09-18,445,123,敏感肌专用面霜,4.5
P019, 无印良品收纳盒,家居,599,无印良品,2023-10-08,667,234,简约收纳解决方案,4.4
P020, Levi's牛仔裤,服装,899,Levi's,2023-09-05,334,156,经典牛仔品牌,4.6
P021, 欧莱雅洗发水,美妆,499,欧莱雅,2023-08-15,556,345,深层清洁洗发水,4.3
P022, 深度学习,图书,69,清华大学出版社,2023-07-20,445,167,人工智能入门书籍,4.7
P023, SK-II神仙水,美妆,599,SK-II,2023-09-25,234,89,经典护肤精华,4.8
P024, 太平鸟衬衫,服装,399,太平鸟,2023-10-12,556,234,时尚商务衬衫,4.4
P025, 乐高积木套装,家居,199,乐高,2023-08-10,678,456,创意拼装玩具,4.8
P026, 小米空气净化器,电子产品,1299,小米,2023-09-15,889,167,智能空气净化器,4.5
P027, 三星Galaxy Watch,电子产品,1599,三星,2023-10-05,445,89,智能运动手表,4.6
P028, 例外连衣裙,服装,1299,例外,2023-09-20,234,89,设计师品牌连衣裙,4.7
P029, Nike篮球鞋,运动,899,耐克,2023-08-05,667,156,专业篮球运动鞋,4.5
P030, 佳能数码相机,电子产品,2999,佳能,2023-09-10,334,67,高像素数码相机,4.8
P031, 时间简史,图书,99,湖南科学技术出版社,2023-07-25,556,234,霍金经典科普著作,4.9
P032, 思想政治,图书,129,人民出版社,2023-08-30,445,345,政治理论教材,4.2
P033, 戴森吸尘器,家居,2999,戴森,2023-10-01,223,89,无线手持吸尘器,4.7
P034, Lululemon瑜伽裤,运动,399,Lululemon,2023-09-08,556,167,专业运动瑜伽服,4.6
P035, 王者荣耀皮肤,游戏,99,腾讯,2023-08-20,1234,999,热门游戏皮肤,4.5
P036, 半泽直树,图书,149,人民文学出版社,2023-09-15,334,234,日经畅销小说,4.7
P037, Under Armour运动服,运动,999,Under Armour,2023-10-03,445,156,专业运动品牌服装,4.4
P038, 飞利浦电动牙刷,家居,799,飞利浦,2023-09-22,667,234,声波震动电动牙刷,4.5
P039, iPad Air,电子产品,4999,苹果,2023-08-12,445,89,平板电脑,4.8
P040, 海澜之家T恤,服装,199,海澜之家,2023-10-08,889,456,舒适日常T恤,4.3
P041, 哈佛管理课,图书,189,中信出版社,2023-09-05,334,167,管理学习课程,4.6
P042, 联想ThinkPad,电子产品,2999,联想,2023-09-18,556,89,商务笔记本电脑,4.5
P043, 欧普照明灯具,家居,399,欧普照明,2023-08-25,667,345,LED智能照明,4.4
P044, PUMA运动鞋,运动,3999,PUMA,2023-10-10,334,156,专业运动跑鞋,4.6
P045, 美的微波炉,家居,2499,美的,2023-09-12,445,234,智能微波炉,4.3
P046, 罗技鼠标,电子产品,399,罗技,2023-08-15,667,456,无线办公鼠标,4.5
P047, 安踏篮球鞋,运动,699,安踏,2023-09-25,556,234,国产专业篮球鞋,4.4
P048, 格力空调,家居,4999,格力,2023-10-05,334,89,变频节能空调,4.6
P049, 花西子口红,美妆,299,花西子,2023-08-20,445,167,国风彩妆品牌,4.7
P050, 九阳豆浆机,家居,599,九阳,2023-09-08,667,345,家用豆浆机,4.3
P051, 华为平板MatePad,电子产品,3999,华为,2023-09-30,445,89,高性能平板电脑,4.6
P052, 森马牛仔裤,服装,299,森马,2023-10-12,556,234,休闲牛仔裤,4.2
P053, 三体,图书,59,重庆出版社,2023-07-15,667,456,刘慈欣科幻小说,4.9
P054, 富士相机,电子产品,3999,富士,2023-08-18,334,67,复古相机设计,4.7
P055, 特步运动鞋,运动,499,特步,2023-09-20,445,156,专业运动鞋,4.3
P056, 苏泊尔电饭煲,家居,899,苏泊尔,2023-10-03,556,234,智能电饭煲,4.4
P057, 索尼电视,电子产品,5999,索尼,2023-09-05,223,89,4K智能电视,4.8
P058, 李宁运动服,运动,699,李宁,2023-08-25,667,345,国产运动品牌,4.5
P059, 小米电视,电子产品,2999,小米,2023-09-15,444,89,智能互联网电视,4.4
P060, 海尔冰箱,家居,4999,海尔,2023-10-08,333,67,变频节能冰箱,4.6
P061, vivo X90,电子产品,3499,vivo,2023-09-20,555,89,拍照智能手机,4.5
P062, 美的微波炉,家居,1299,美的,2023-08-10,444,156,家用微波炉,4.3
P063, 科沃斯扫地机器人,家居,1799,科沃斯,2023-09-25,333,89,智能清洁机器人,4.6用户ID,商品ID,评分,时间戳,商品类别,商品价格,用户年龄,用户性别,用户城市,行为类型
U001,P001,5,2024-01-01 10:30:00,电子产品,2999,28,男,北京,购买
U001,P015,4,2024-01-02 14:20:00,服装,399,28,男,北京,购买
U001,P032,3,2024-01-03 09:15:00,图书,89,28,男,北京,浏览
U001,P045,5,2024-01-04 16:45:00,电子产品,1599,28,男,北京,购买
U001,P078,4,2024-01-05 11:30:00,家居,299,28,男,北京,购买
U002,P002,4,2024-01-01 11:00:00,服装,599,32,女,上海,购买
U002,P018,5,2024-01-02 15:30:00,美妆,299,32,女,上海,购买
U002,P025,3,2024-01-03 12:20:00,家居,199,32,女,上海,浏览
U002,P038,4,2024-01-04 18:10:00,服装,259,32,女,上海,购买
U002,P051,5,2024-01-05 20:15:00,电子产品,4999,32,女,上海,购买
U003,P003,3,2024-01-01 13:45:00,图书,79,25,男,广州,购买
U003,P016,4,2024-01-02 16:30:00,服装,199,25,男,广州,购买
U003,P029,5,2024-01-03 10:15:00,运动,899,25,男,广州,购买
U003,P042,4,2024-01-04 14:50:00,电子产品,2999,25,男,广州,购买
U003,P065,3,2024-01-05 17:25:00,家居,599,25,男,广州,浏览
U004,P004,5,2024-01-01 09:20:00,美妆,159,29,女,深圳,购买
U004,P017,4,2024-01-02 13:10:00,服装,799,29,女,深圳,购买
U004,P030,3,2024-01-03 15:45:00,运动,299,29,女,深圳,浏览
U004,P043,5,2024-01-04 19:30:00,电子产品,1999,29,女,深圳,购买
U004,P056,4,2024-01-05 12:05:00,家居,899,29,女,深圳,购买
U005,P005,4,2024-01-01 15:30:00,运动,999,35,男,成都,购买
U005,P018,5,2024-01-02 10:45:00,美妆,399,35,男,成都,购买
U005,P031,3,2024-01-03 14:20:00,图书,59,35,男,成都,浏览
U005,P044,4,2024-01-04 18:55:00,电子产品,3999,35,男,成都,购买
U005,P057,5,2024-01-05 11:40:00,家居,1299,35,男,成都,购买
U006,P006,3,2024-01-01 11:15:00,家居,799,26,女,杭州,购买
U006,P019,4,2024-01-02 16:25:00,服装,599,26,女,杭州,购买
U006,P032,5,2024-01-03 09:50:00,图书,129,26,女,杭州,购买
U006,P045,4,2024-01-04 13:35:00,电子产品,2499,26,女,杭州,购买
U006,P058,3,2024-01-05 17:10:00,运动,699,26,女,杭州,浏览
U007,P007,5,2024-01-01 14:40:00,电子产品,5999,31,男,南京,购买
U007,P020,4,2024-01-03 11:20:00,服装,899,31,男,南京,购买
U007,P033,3,2024-01-04 15:05:00,图书,99,31,男,南京,浏览
U007,P046,5,2024-01-05 19:45:00,家居,1599,31,男,南京,购买
U008,P008,4,2024-01-01 10:25:00,服装,499,27,女,武汉,购买
U008,P021,5,2024-01-02 14:10:00,美妆,499,27,女,武汉,购买
U008,P034,3,2024-01-03 17:55:00,运动,399,27,女,武汉,浏览
U008,P047,4,2024-01-04 12:30:00,电子产品,3499,27,女,武汉,购买
U008,P059,5,2024-01-05 16:15:00,家居,999,27,女,武汉,购买
U009,P009,5,2024-01-01 12:50:00,图书,39,33,男,西安,购买
U009,P022,4,2024-01-02 16:35:00,服装,699,33,男,西安,购买
U009,P035,3,2024-01-03 10:10:00,运动,799,33,男,西安,浏览
U009,P048,5,2024-01-04 14:45:00,电子产品,4499,33,男,西安,购买
U009,P060,4,2024-01-05 18:20:00,家居,1199,33,男,西安,购买
U010,P010,4,2024-01-01 15:10:00,运动,1199,29,女,重庆,购买
U010,P023,5,2024-01-02 11:55:00,美妆,599,29,女,重庆,购买
U010,P036,3,2024-01-03 15:40:00,图书,149,29,女,重庆,浏览
U010,P049,4,2024-01-04 19:25:00,电子产品,2999,29,女,重庆,购买
U010,P061,5,2024-01-05 13:50:00,家居,1799,29,女,重庆,购买
U011,P011,3,2024-01-01 09:35:00,美妆,299,24,男,天津,购买
U011,P024,4,2024-01-02 13:20:00,服装,399,24,男,天津,购买
U011,P037,5,2024-01-03 16:05:00,运动,999,24,男,天津,购买
U011,P050,3,2024-01-04 10:40:00,电子产品,1999,24,男,天津,浏览
U011,P062,4,2024-01-05 14:15:00,家居,799,24,男,天津,购买
U012,P012,5,2024-01-01 13:05:00,图书,59,30,女,苏州,购买
U012,P025,4,2024-01-02 17:50:00,服装,899,30,女,苏州,购买
U012,P038,3,2024-01-03 11:35:00,运动,499,30,女,苏州,浏览
U012,P051,5,2024-01-04 15:20:00,电子产品,3999,30,女,苏州,购买
U012,P063,4,2024-01-05 18:55:00,家居,1299,30,女,苏州,购买user_count,item_count,matrix_sparsity,user_cf_trained,item_cf_trained,svd_trained,svd_components
12,53,0.9072327044025157,True,True,True,20
Method,Rank,Item_ID,Score
User-Based CF,1,P019,0.05767542298909329
User-Based CF,2,P006,0.04325656724181997
User-Based CF,3,P058,0.04325656724181997
Item-Based CF,1,P058,1.1391908029819509
Item-Based CF,2,P019,1.1391908029819509
Item-Based CF,3,P006,1.1391908029819509
SVD,1,P044,9.020301754621135e-16
SVD,2,P057,8.724078615256799e-16
SVD,3,P059,7.354774663831836e-16
SVD,4,P021,7.07413684419489e-16
SVD,5,P047,5.061957917936061e-16
Hybrid,1,P019,0.35905986779131327
Hybrid,2,P006,0.35473421106713127
Hybrid,3,P058,0.35473421106713127
Hybrid,4,P044,3.608120701848454e-16
Hybrid,5,P057,3.48963144610272e-16
"""
简化推荐系统示例
演示推荐系统技能的核心功能:
- 数据加载和预处理
- 推荐算法训练
- 推荐结果生成
- 效果评估
"""
import sys
import os
import pandas as pd
import numpy as np
from pathlib import Path
# 添加技能路径
skill_path = Path(__file__).parent.parent
sys.path.append(str(skill_path))
from scripts.recommendation_engine import RecommendationEngine
from scripts.recommender_evaluator import RecommenderEvaluator
from scripts.recommender_visualizer import RecommenderVisualizer
def main():
"""主函数:演示简化推荐系统流程"""
print("=" * 60)
print("推荐系统技能 - 简化示例")
print("=" * 60)
# 1. 初始化组件
print("\n1. 初始化推荐系统组件...")
engine = RecommendationEngine()
evaluator = RecommenderEvaluator()
visualizer = RecommenderVisualizer()
# 2. 数据加载
print("\n2. 加载样本数据...")
data_dir = Path(__file__).parent / "sample_data"
user_behavior_path = data_dir / "sample_user_behavior.csv"
item_info_path = data_dir / "sample_item_info.csv"
# 加载用户行为和商品信息数据
user_data, item_data = engine.load_data(str(user_behavior_path), str(item_info_path))
if user_data is None:
print("❌ 数据加载失败")
return
print(f"✅ 数据加载成功:{len(user_data)} 条用户行为记录")
print(f" - 用户数: {engine.user_item_matrix.shape[0]:,}")
print(f" - 商品数: {engine.user_item_matrix.shape[1]:,}")
# 3. 基础数据分析
print("\n3. 基础数据分析...")
# 计算数据稀疏度
total_entries = engine.user_item_matrix.shape[0] * engine.user_item_matrix.shape[1]
non_zero_entries = (engine.user_item_matrix > 0).sum().sum()
sparsity = (total_entries - non_zero_entries) / total_entries
print(f" - 数据稀疏度: {sparsity:.2%}")
print(f" - 平均每用户交互: {non_zero_entries / engine.user_item_matrix.shape[0]:.1f}")
# 用户活跃度分析
user_activity = engine.user_item_matrix.apply(lambda x: (x > 0).sum(), axis=1)
print(f" - 平均用户活跃度: {user_activity.mean():.1f}")
print(f" - 最活跃用户交互数: {user_activity.max()}")
print(f" - 最不活跃用户交互数: {user_activity.min()}")
# 4. 训练推荐模型
print("\n4. 训练推荐模型...")
# 训练基于用户的协同过滤
print(" - 训练基于用户的协同过滤...")
engine.train_user_based_cf(similarity_metric='cosine', normalize=True)
# 训练基于物品的协同过滤
print(" - 训练基于物品的协同过滤...")
engine.train_item_based_cf(similarity_metric='cosine')
# 训练SVD矩阵分解模型
print(" - 训练SVD矩阵分解模型...")
engine.train_svd(n_components=20, random_state=42)
print("✅ 所有模型训练完成")
# 5. 生成推荐结果
print("\n5. 生成推荐结果...")
target_user = 'U001' # 目标用户
# 基于用户的协同过滤推荐
user_cf_recs = engine.recommend_user_based_cf(target_user, top_k=5)
print(f"\n📋 基于用户的协同过滤推荐 (用户 {target_user}):")
for i, (item_id, score) in enumerate(user_cf_recs, 1):
print(f" {i}. {item_id}: {score:.3f}")
# 基于物品的协同过滤推荐
item_cf_recs = engine.recommend_item_based_cf(target_user, top_k=5)
print(f"\n📋 基于物品的协同过滤推荐 (用户 {target_user}):")
for i, (item_id, score) in enumerate(item_cf_recs, 1):
print(f" {i}. {item_id}: {score:.3f}")
# SVD矩阵分解推荐
svd_recs = engine.recommend_svd(target_user, top_k=5)
print(f"\n📋 SVD矩阵分解推荐 (用户 {target_user}):")
for i, (item_id, score) in enumerate(svd_recs, 1):
print(f" {i}. {item_id}: {score:.3f}")
# 混合推荐
hybrid_weights = {'user_cf': 0.3, 'item_cf': 0.3, 'svd': 0.4}
hybrid_recs = engine.recommend_hybrid(target_user, top_k=5, weights=hybrid_weights)
print(f"\n📋 混合推荐 (用户 {target_user}):")
for i, (item_id, score) in enumerate(hybrid_recs, 1):
print(f" {i}. {item_id}: {score:.3f}")
# 6. 评估推荐效果
print("\n6. 评估推荐效果...")
# 基本指标演示
test_recommendations = ['P001', 'P002', 'P003', 'P004', 'P005']
test_ground_truth = ['P001', 'P003', 'P006']
precision = evaluator.precision_at_k(test_recommendations, test_ground_truth, k=5)
recall = evaluator.recall_at_k(test_recommendations, test_ground_truth, k=5)
f1 = evaluator.f1_score_at_k(test_recommendations, test_ground_truth, k=5)
print(f"\n📊 评估指标示例:")
print(f" - Precision@5: {precision:.4f}")
print(f" - Recall@5: {recall:.4f}")
print(f" - F1@5: {f1:.4f}")
# 评分预测准确性演示
test_predictions = [4.5, 3.2, 4.8, 2.1, 3.9]
test_actual = [4.0, 3.5, 4.5, 2.0, 4.0]
mae = evaluator.mean_absolute_error(test_predictions, test_actual)
rmse = evaluator.root_mean_square_error(test_predictions, test_actual)
print(f"\n📊 评分预测准确性:")
print(f" - MAE: {mae:.4f}")
print(f" - RMSE: {rmse:.4f}")
# 7. 简化评估
print("\n7. 系统性能评估...")
# 选择几个用户进行评估
test_users = engine.user_item_matrix.index[:min(5, len(engine.user_item_matrix))]
successful_recs = 0
for user_id in test_users:
try:
recs = engine.recommend_hybrid(user_id, top_k=3)
if len(recs) > 0:
successful_recs += 1
except:
continue
success_rate = successful_recs / len(test_users)
print(f" - 推荐成功率: {success_rate:.1%} ({successful_recs}/{len(test_users)} 用户)")
# 8. 模型信息
print("\n8. 模型信息...")
model_info = engine.get_model_info()
print(f" - 用户数: {model_info['user_count']:,}")
print(f" - 商品数: {model_info['item_count']:,}")
print(f" - 矩阵稀疏度: {model_info['matrix_sparsity']:.2%}")
print(f" - 用户CF模型: {'✅' if model_info['user_cf_trained'] else '❌'}")
print(f" - 物品CF模型: {'✅' if model_info['item_cf_trained'] else '❌'}")
print(f" - SVD模型: {'✅' if model_info['svd_trained'] else '❌'}")
# 9. 保存结果
print("\n9. 保存分析结果...")
# 创建输出目录
output_dir = Path(__file__).parent / "simple_output"
output_dir.mkdir(exist_ok=True)
# 保存推荐结果
recommendations_data = {
'Method': [],
'Rank': [],
'Item_ID': [],
'Score': []
}
methods = [
('User-Based CF', user_cf_recs),
('Item-Based CF', item_cf_recs),
('SVD', svd_recs),
('Hybrid', hybrid_recs)
]
for method_name, recs in methods:
for i, (item_id, score) in enumerate(recs, 1):
recommendations_data['Method'].append(method_name)
recommendations_data['Rank'].append(i)
recommendations_data['Item_ID'].append(item_id)
recommendations_data['Score'].append(score)
recs_df = pd.DataFrame(recommendations_data)
recs_df.to_csv(output_dir / "recommendations_results.csv", index=False, encoding='utf-8-sig')
# 保存模型信息
model_df = pd.DataFrame([model_info])
model_df.to_csv(output_dir / "model_info.csv", index=False, encoding='utf-8-sig')
print("✅ 结果已保存到 simple_output/ 目录")
# 10. 总结
print("\n" + "=" * 60)
print("🎉 推荐系统简化示例完成!")
print("=" * 60)
print(f"\n📁 生成的文件:")
print(f" - 推荐结果: {output_dir}/recommendations_results.csv")
print(f" - 模型信息: {output_dir}/model_info.csv")
print(f"\n🎯 关键结果:")
print(f" - 数据稀疏度: {sparsity:.2%}")
print(f" - 推荐成功率: {success_rate:.1%}")
print(f" - 最佳推荐方法: 混合推荐 (综合多种算法)")
print(f" - 推荐覆盖度: {len(set([r[0] for r in hybrid_recs]))} 个商品")
print(f"\n💡 推荐系统技能特性:")
print(f" ✅ 多种推荐算法 (UCF, ICF, SVD, Hybrid)")
print(f" ✅ 全面的评估指标")
print(f" ✅ 智能的冷启动处理")
print(f" ✅ 高效的矩阵运算")
print(f" ✅ 灵活的参数配置")
return True
if __name__ == "__main__":
try:
success = main()
if success:
print("\n🚀 推荐系统技能验证成功!可以开始使用。")
sys.exit(0 if success else 1)
except Exception as e:
print(f"\n❌ 示例运行失败: {str(e)}")
import traceback
traceback.print_exc()
sys.exit(1)#!/usr/bin/env python3
"""
快速测试推荐系统核心功能
"""
import sys
import os
import pandas as pd
from pathlib import Path
# 添加技能路径
skill_path = Path(__file__).parent
sys.path.append(str(skill_path))
def main():
"""快速测试主要功能"""
print("🚀 推荐系统技能快速测试")
try:
# 1. 测试导入
print("\n1. 测试模块导入...")
from scripts.recommendation_engine import RecommendationEngine
from scripts.recommender_evaluator import RecommenderEvaluator
print(" ✓ 核心模块导入成功")
# 2. 测试数据加载和模型训练
print("\n2. 测试推荐引擎...")
engine = RecommendationEngine()
data_dir = skill_path / "examples" / "sample_data"
user_behavior_path = data_dir / "sample_user_behavior.csv"
item_info_path = data_dir / "sample_item_info.csv"
user_data, item_data = engine.load_data(str(user_behavior_path), str(item_info_path))
if user_data is not None:
print(f" ✓ 数据加载成功: {len(user_data)} 条记录")
# 训练模型
engine.train_user_based_cf()
engine.train_item_based_cf()
engine.train_svd(n_components=10)
print(" ✓ 模型训练成功")
# 生成推荐
target_user = engine.user_item_matrix.index[0]
recommendations = engine.recommend_hybrid(target_user, top_k=5)
print(f" ✓ 推荐生成成功: {len(recommendations)} 个推荐")
# 显示推荐结果
print(f"\n🎯 用户 {target_user} 的推荐结果:")
for i, (item_id, score) in enumerate(recommendations, 1):
print(f" {i}. {item_id}: {score:.3f}")
# 3. 测试评估
print("\n3. 测试评估功能...")
evaluator = RecommenderEvaluator()
# 测试基本评估指标
recs = ['P001', 'P002', 'P003', 'P004', 'P005']
truth = ['P001', 'P003', 'P006']
precision = evaluator.precision_at_k(recs, truth, k=5)
recall = evaluator.recall_at_k(recs, truth, k=5)
print(f" ✓ Precision@5: {precision:.4f}")
print(f" ✓ Recall@5: {recall:.4f}")
print("\n🎉 核心功能测试通过!")
print("\n推荐系统技能已就绪,可以使用以下命令运行完整示例:")
print(" python examples/basic_recommendation_example.py")
return True
except Exception as e:
print(f"\n❌ 测试失败: {str(e)}")
import traceback
traceback.print_exc()
return False
if __name__ == "__main__":
success = main()
sys.exit(0 if success else 1)推荐系统分析技能 (Recommender System Skill)
一个功能完整的智能推荐系统分析工具,基于"数据分析咖哥十话"的推荐系统模块开发。
🎯 技能概述
本技能提供从数据处理到推荐生成的完整推荐系统解决方案,支持多种推荐算法、评估方法和可视化分析。
✨ 核心特性
- 🤖 多种推荐算法
- 基于用户的协同过滤 (User-Based CF)
- 基于物品的协同过滤 (Item-Based CF)
- SVD矩阵分解 (Singular Value Decomposition)
- 混合推荐策略 (Hybrid Recommendation)
- 📊 全面的评估框架
- 离线评估指标 (Precision@K, Recall@K, MAE, RMSE)
- 多种评估方法 (留一法, K折交叉验证, 时间序列验证)
- 算法性能对比分析
- 📈 丰富的可视化功能
- 推荐结果可视化
- 评估指标图表
- 用户行为分析图
- 算法比较图
- 🔧 智能数据处理
- 数据质量检查
- 冷启动问题检测
- 用户画像分析
- 数据稀疏性分析
🚀 快速开始
1. 环境要求
# 依赖包
pip install pandas numpy scikit-learn matplotlib seaborn2. 基础使用
from scripts.recommendation_engine import RecommendationEngine
from scripts.recommender_evaluator import RecommenderEvaluator
from scripts.recommender_visualizer import RecommenderVisualizer
# 初始化组件
engine = RecommendationEngine()
evaluator = RecommenderEvaluator()
visualizer = RecommenderVisualizer()
# 加载数据
user_data, item_data = engine.load_data('user_behavior.csv', 'item_info.csv')
# 训练模型
engine.train_user_based_cf()
engine.train_item_based_cf()
engine.train_svd(n_components=50)
# 生成推荐
recommendations = engine.recommend_hybrid('U001', top_k=10)
print(f"推荐结果: {recommendations}")3. 运行示例
# 快速测试
python quick_test.py
# 简化示例 (推荐)
python examples/simple_recommendation_example.py
# 完整功能示例
python examples/basic_recommendation_example.py
# 高级功能演示
python examples/advanced_recommendation_example.py📁 项目结构
recommender-system/
├── SKILL.md # 技能详细文档
├── README.md # 使用指南 (本文件)
├── quick_test.py # 快速功能测试
├── test_skill.py # 完整测试套件
│
├── scripts/ # 核心功能模块
│ ├── __init__.py
│ ├── recommendation_engine.py # 推荐算法引擎
│ ├── recommender_evaluator.py # 评估框架
│ ├── data_analyzer.py # 数据分析器
│ └── recommender_visualizer.py # 可视化器
│
└── examples/ # 示例和数据
├── sample_data/ # 样本数据
│ ├── sample_user_behavior.csv
│ └── sample_item_info.csv
├── simple_recommendation_example.py # 简化示例
├── basic_recommendation_example.py # 基础示例
└── advanced_recommendation_example.py # 高级示例💡 主要功能
1. 推荐算法
基于用户的协同过滤
# 训练模型
engine.train_user_based_cf(similarity_metric='cosine', normalize=True)
# 生成推荐
recommendations = engine.recommend_user_based_cf('U001', top_k=10)基于物品的协同过滤
# 训练模型
engine.train_item_based_cf(similarity_metric='cosine')
# 生成推荐
recommendations = engine.recommend_item_based_cf('U001', top_k=10)SVD矩阵分解
# 训练模型
engine.train_svd(n_components=50, random_state=42)
# 生成推荐
recommendations = engine.recommend_svd('U001', top_k=10)混合推荐
# 配置权重
weights = {'user_cf': 0.3, 'item_cf': 0.3, 'svd': 0.4}
# 生成推荐
recommendations = engine.recommend_hybrid('U001', top_k=10, weights=weights)2. 系统评估
基本评估指标
# 计算推荐质量
precision = evaluator.precision_at_k(recommendations, ground_truth, k=5)
recall = evaluator.recall_at_k(recommendations, ground_truth, k=5)
f1 = evaluator.f1_score_at_k(recommendations, ground_truth, k=5)
# 计算评分准确性
mae = evaluator.mean_absolute_error(predictions, actual_ratings)
rmse = evaluator.root_mean_square_error(predictions, actual_ratings)留一法评估
loo_results = evaluator.leave_one_out_evaluation(
engine, user_item_matrix,
k_values=[5, 10, 20],
num_users=50
)算法比较
algorithm_results = {
'User-CF': user_cf_metrics,
'Item-CF': item_cf_metrics,
'SVD': svd_metrics,
'Hybrid': hybrid_metrics
}
comparison_df = evaluator.compare_algorithms(algorithm_results)3. 数据分析
用户行为分析
from scripts.data_analyzer import DataAnalyzer
analyzer = DataAnalyzer()
user_data, item_data = analyzer.load_data('user_behavior.csv', 'item_info.csv')
# 用户行为分析
user_analysis = analyzer.analyze_user_behavior(user_data)
# 商品热度分析
item_analysis = analyzer.analyze_item_popularity(user_data, item_data)
# 冷启动问题检测
cold_start = analyzer.detect_cold_start(user_data)4. 可视化分析
推荐结果可视化
# 推荐结果柱状图
fig = visualizer.plot_recommendation_results(
recommendations, user_id='U001',
title='用户U001的推荐结果'
)
# 算法比较图
fig = visualizer.plot_algorithm_comparison(comparison_df)
# 用户行为分析图
fig = visualizer.plot_user_behavior_analysis(user_data)📊 数据格式
用户行为数据 (user_behavior.csv)
用户ID,商品ID,评分,时间戳,商品类别,商品价格,用户年龄,用户性别,用户城市,行为类型
U001,P001,5,2024-01-01 10:30:00,电子产品,2999,28,男,北京,购买
U002,P002,4,2024-01-02 14:20:00,服装,399,32,女,上海,购买商品信息数据 (item_info.csv)
商品ID,商品名称,商品类别,价格,品牌,上架时间,销量,库存,商品描述,平均评分
P001,iPhone 15 Pro,电子产品,3999,苹果,2023-09-15,1250,89,最新款苹果手机,4.8
P002,优衣库羊毛大衣,服装,599,优衣库,2023-10-01,890,156,秋冬保暖羊毛大衣,4.5🎯 应用场景
电商推荐
- 商品个性化推荐
- 相似商品推荐
- 跨品类推荐
- 购物车补充推荐
内容推荐
- 文章推荐
- 视频推荐
- 音乐推荐
- 课程推荐
游戏推荐
- 游戏推荐
- 游戏内物品推荐
- 社交推荐
⚙️ 高级配置
算法参数调优
# 协同过滤参数
engine.train_user_based_cf(
similarity_metric='cosine', # 'cosine' 或 'pearson'
normalize=True # 是否标准化
)
# SVD参数
engine.train_svd(
n_components=50, # 降维组件数
random_state=42 # 随机种子
)
# 混合推荐权重
weights = {
'user_cf': 0.3, # 用户协同过滤权重
'item_cf': 0.3, # 物品协同过滤权重
'svd': 0.4 # SVD权重
}评估参数配置
# 留一法评估
loo_results = evaluator.leave_one_out_evaluation(
engine, user_item_matrix,
k_values=[5, 10, 20], # 评估的K值
num_users=100, # 评估用户数
n_neighbors=50 # 相似邻居数
)
# 交叉验证评估
cv_results = evaluator.cross_validation_evaluation(
engine, user_item_matrix,
cv_folds=5, # 交叉验证折数
k_values=[5, 10] # 评估的K值
)🐛 常见问题
Q: 如何处理新用户冷启动问题?
A: 系统自动使用热门商品推荐策略为新用户生成推荐。
Q: 如何选择最优的算法参数?
A: 建议使用交叉验证评估不同参数组合的效果,选择最优配置。
Q: 如何处理大规模数据?
A: 可以通过采样减少计算量,或使用增量学习方法。
Q: 如何提高推荐的多样性?
A: 可以在混合推荐中加入多样性权重,或使用基于内容的推荐。
📈 性能优化
- 使用矩阵运算库 (如 numpy, scipy)
- 实现增量学习机制
- 使用缓存机制存储计算结果
- 采用并行计算加速训练过程
📚 技术原理
协同过滤
基于用户或物品的相似度进行推荐,核心是"相似的人喜欢相似的物品"。
矩阵分解
通过降维技术发现用户和商品的隐含特征,解决数据稀疏性问题。
混合推荐
结合多种推荐算法的优势,提高推荐的准确性和覆盖率。
🤝 贡献指南
欢迎提交 Issue 和 Pull Request 来改进这个技能。
📄 许可证
MIT License
---
🎉 开始使用
现在你已经了解了推荐系统技能的所有功能,可以开始使用了:
# 快速验证功能
python quick_test.py
# 运行示例
python examples/simple_recommendation_example.py享受你的推荐系统之旅!🚀
"""
推荐系统分析技能模块
提供完整的推荐系统实现,包括:
- 协同过滤算法 (用户/物品基于)
- 矩阵分解算法 (SVD)
- 推荐系统评估框架
- 数据分析和可视化
"""
from .recommendation_engine import RecommendationEngine
from .recommender_evaluator import RecommenderEvaluator
from .data_analyzer import DataAnalyzer
from .recommender_visualizer import RecommenderVisualizer
__version__ = "1.0.0"
__author__ = "Claude Code"
__all__ = [
"RecommendationEngine",
"RecommenderEvaluator",
"DataAnalyzer",
"RecommenderVisualizer"
]"""
推荐系统数据分析器
提供全面的数据分析功能:
- 用户行为分析
- 商品热度分析
- 数据质量检查
- 冷启动问题检测
- 用户画像分析
"""
import pandas as pd
import numpy as np
from typing import Dict, List, Tuple, Optional, Union, Any
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime, timedelta
import warnings
warnings.filterwarnings('ignore')
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS', 'Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False
class DataAnalyzer:
"""推荐系统数据分析器类"""
def __init__(self):
self.user_data = None
self.item_data = None
self.user_item_matrix = None
self.analysis_results = {}
def load_data(self, user_behavior_path: str, item_info_path: Optional[str] = None) -> Tuple[pd.DataFrame, Optional[pd.DataFrame]]:
"""
加载用户行为数据和商品信息数据
Args:
user_behavior_path: 用户行为数据文件路径
item_info_path: 商品信息数据文件路径(可选)
Returns:
用户行为数据和商品信息数据的元组
"""
try:
# 加载用户行为数据
self.user_data = pd.read_csv(user_behavior_path, encoding='utf-8')
# 数据预处理
if '评分' in self.user_data.columns:
self.user_data['评分'] = pd.to_numeric(self.user_data['评分'], errors='coerce')
self.user_data.dropna(subset=['评分'], inplace=True)
# 处理时间戳
if '时间戳' in self.user_data.columns:
self.user_data['时间戳'] = pd.to_datetime(self.user_data['时间戳'])
print(f"用户行为数据加载成功:{len(self.user_data)} 条记录")
# 加载商品信息数据(如果提供)
self.item_data = None
if item_info_path:
self.item_data = pd.read_csv(item_info_path, encoding='utf-8')
print(f"商品信息数据加载成功:{len(self.item_data)} 个商品")
return self.user_data, self.item_data
except Exception as e:
print(f"数据加载失败:{str(e)}")
return None, None
def analyze_user_behavior(self, user_data: Optional[pd.DataFrame] = None) -> Dict[str, Any]:
"""
分析用户行为
Args:
user_data: 用户行为数据(可选,默认使用self.user_data)
Returns:
用户行为分析结果字典
"""
if user_data is None:
user_data = self.user_data
if user_data is None:
print("没有可用的用户数据")
return {}
print("开始分析用户行为...")
analysis = {}
# 基本统计
analysis['total_users'] = user_data['用户ID'].nunique()
analysis['total_items'] = user_data['商品ID'].nunique()
analysis['total_interactions'] = len(user_data)
# 用户活跃度分析
user_activity = user_data.groupby('用户ID').size().describe()
analysis['user_activity'] = {
'mean': float(user_activity['mean']),
'std': float(user_activity['std']),
'min': int(user_activity['min']),
'max': int(user_activity['max']),
'median': float(user_activity['50%'])
}
# 活跃用户分布
activity_quantiles = user_activity.quantile([0.1, 0.25, 0.5, 0.75, 0.9])
analysis['activity_distribution'] = {
f'{int(p*100)}%_quantile': float(val) for p, val in activity_quantiles.items()
}
# 评分分析(如果有评分数据)
if '评分' in user_data.columns:
rating_stats = user_data['评分'].describe()
analysis['rating_stats'] = {
'mean': float(rating_stats['mean']),
'std': float(rating_stats['std']),
'min': float(rating_stats['min']),
'max': float(rating_stats['max']),
'median': float(rating_stats['50%'])
}
# 评分分布
rating_dist = user_data['评分'].value_counts().to_dict()
analysis['rating_distribution'] = {str(k): int(v) for k, v in rating_dist.items()}
# 时间分析(如果有时间戳数据)
if '时间戳' in user_data.columns:
# 确保时间戳是datetime类型
if not pd.api.types.is_datetime64_any_dtype(user_data['时间戳']):
user_data['时间戳'] = pd.to_datetime(user_data['时间戳'])
time_span = user_data['时间戳'].max() - user_data['时间戳'].min()
analysis['time_analysis'] = {
'time_span_days': time_span.days,
'start_date': user_data['时间戳'].min().strftime('%Y-%m-%d'),
'end_date': user_data['时间戳'].max().strftime('%Y-%m-%d'),
'avg_interactions_per_day': float(len(user_data) / max(1, time_span.days))
}
# 每日活跃用户数
daily_active_users = user_data.groupby(user_data['时间戳'].dt.date)['用户ID'].nunique()
analysis['daily_active_users'] = {
'mean': float(daily_active_users.mean()),
'std': float(daily_active_users.std()),
'min': int(daily_active_users.min()),
'max': int(daily_active_users.max())
}
# 商品类别分析
if '商品类别' in user_data.columns:
category_stats = user_data['商品类别'].value_counts().describe()
analysis['category_stats'] = {
'total_categories': int(len(user_data['商品类别'].unique())),
'most_popular_category': user_data['商品类别'].value_counts().index[0],
'most_popular_category_count': int(user_data['商品类别'].value_counts().iloc[0])
}
self.analysis_results['user_behavior'] = analysis
print("用户行为分析完成")
return analysis
def analyze_item_popularity(self, item_data: Optional[pd.DataFrame] = None,
user_data: Optional[pd.DataFrame] = None) -> Dict[str, Any]:
"""
分析商品热度
Args:
item_data: 商品信息数据(可选)
user_data: 用户行为数据(可选)
Returns:
商品热度分析结果字典
"""
if user_data is None:
user_data = self.user_data
if item_data is None:
item_data = self.item_data
if user_data is None:
print("没有可用的用户行为数据")
return {}
print("开始分析商品热度...")
analysis = {}
# 商品交互统计
item_interactions = user_data.groupby('商品ID').size().describe()
analysis['item_interactions'] = {
'mean': float(item_interactions['mean']),
'std': float(item_interactions['std']),
'min': int(item_interactions['min']),
'max': int(item_interactions['max']),
'median': float(item_interactions['50%'])
}
# 热门商品
item_popularity = user_data.groupby('商品ID').size().sort_values(ascending=False)
top_items = item_popularity.head(20)
analysis['top_items'] = {
str(item_id): int(count) for item_id, count in top_items.items()
}
# 长尾分析
interaction_quantiles = item_popularity.quantile([0.1, 0.25, 0.5, 0.75, 0.9])
analysis['popularity_distribution'] = {
f'{int(p*100)}%_quantile': float(val) for p, val in interaction_quantiles.items()
}
# 冷门商品(交互次数少于5次)
cold_items = (item_popularity < 5).sum()
analysis['cold_start_items'] = {
'count': int(cold_items),
'percentage': float(cold_items / len(item_popularity) * 100)
}
# 评分分析(如果有评分数据)
if '评分' in user_data.columns:
item_ratings = user_data.groupby('商品ID')['评分'].agg(['mean', 'count', 'std'])
analysis['item_ratings'] = {
'avg_rating': float(item_ratings['mean'].mean()),
'avg_rating_std': float(item_ratings['mean'].std()),
'high_rated_items': int((item_ratings['mean'] >= 4).sum()),
'low_rated_items': int((item_ratings['mean'] <= 2).sum())
}
# 商品类别分析
if '商品类别' in user_data.columns:
category_popularity = user_data.groupby('商品类别').agg({
'商品ID': 'nunique',
'用户ID': 'nunique'
}).rename(columns={'商品ID': 'unique_items', '用户ID': 'unique_users'})
# 添加总交互次数
category_interactions = user_data.groupby('商品类别').size().rename('total_interactions')
category_popularity = category_popularity.join(category_interactions)
analysis['category_popularity'] = category_popularity.to_dict('index')
self.analysis_results['item_popularity'] = analysis
print("商品热度分析完成")
return analysis
def calculate_sparsity(self, user_item_matrix: Optional[pd.DataFrame] = None) -> Dict[str, float]:
"""
计算用户-商品矩阵的稀疏度
Args:
user_item_matrix: 用户-商品交互矩阵(可选)
Returns:
稀疏度分析结果字典
"""
if user_item_matrix is None:
if self.user_item_matrix is None:
# 从用户数据构建矩阵
if self.user_data is None:
print("没有可用的数据")
return {}
self.user_item_matrix = self.user_data.pivot_table(
index='用户ID', columns='商品ID', values='评分', fill_value=0
)
user_item_matrix = self.user_item_matrix
total_entries = user_item_matrix.shape[0] * user_item_matrix.shape[1]
zero_entries = (user_item_matrix == 0).sum().sum()
non_zero_entries = total_entries - zero_entries
sparsity = {
'sparsity_ratio': float(zero_entries / total_entries),
'density_ratio': float(non_zero_entries / total_entries),
'total_entries': int(total_entries),
'zero_entries': int(zero_entries),
'non_zero_entries': int(non_zero_entries),
'avg_interactions_per_user': float(non_zero_entries / user_item_matrix.shape[0]),
'avg_interactions_per_item': float(non_zero_entries / user_item_matrix.shape[1])
}
self.analysis_results['sparsity'] = sparsity
print(f"数据稀疏度分析完成:稀疏度 {sparsity['sparsity_ratio']:.2%}")
return sparsity
def detect_cold_start(self, user_data: Optional[pd.DataFrame] = None,
item_data: Optional[pd.DataFrame] = None) -> Dict[str, Any]:
"""
检测冷启动问题
Args:
user_data: 用户行为数据(可选)
item_data: 商品信息数据(可选)
Returns:
冷启动问题分析结果字典
"""
if user_data is None:
user_data = self.user_data
if item_data is None:
item_data = self.item_data
if user_data is None:
print("没有可用的用户数据")
return {}
print("开始检测冷启动问题...")
analysis = {}
# 用户冷启动分析
user_interactions = user_data.groupby('用户ID').size()
new_users = (user_interactions <= 5).sum()
total_users = len(user_interactions)
analysis['user_cold_start'] = {
'new_users_count': int(new_users),
'new_users_percentage': float(new_users / total_users * 100),
'total_users': int(total_users),
'avg_interactions_per_new_user': float(user_interactions[user_interactions <= 5].mean())
}
# 商品冷启动分析
item_interactions = user_data.groupby('商品ID').size()
new_items = (item_interactions <= 5).sum()
total_items = len(item_interactions)
analysis['item_cold_start'] = {
'new_items_count': int(new_items),
'new_items_percentage': float(new_items / total_items * 100),
'total_items': int(total_items),
'avg_interactions_per_new_item': float(item_interactions[item_interactions <= 5].mean())
}
# 时间维度冷启动分析(如果有时间戳)
if '时间戳' in user_data.columns:
# 最近30天的新用户和新商品
recent_date = user_data['时间戳'].max() - timedelta(days=30)
recent_data = user_data[user_data['时间戳'] >= recent_date]
recent_users = recent_data['用户ID'].nunique()
recent_items = recent_data['商品ID'].nunique()
# 计算这些新用户和新商品的历史交互次数
new_user_historical = user_interactions[user_interactions.index.isin(recent_data['用户ID'])]
new_item_historical = item_interactions[item_interactions.index.isin(recent_data['商品ID'])]
analysis['temporal_cold_start'] = {
'recent_new_users': int(recent_users),
'recent_new_items': int(recent_items),
'recent_new_users_with_few_interactions': int((new_user_historical <= 3).sum()),
'recent_new_items_with_few_interactions': int((new_item_historical <= 3).sum())
}
# 冷启动严重程度评估
cold_start_severity = "低"
if analysis['user_cold_start']['new_users_percentage'] > 30:
cold_start_severity = "高"
elif analysis['user_cold_start']['new_users_percentage'] > 15:
cold_start_severity = "中"
analysis['cold_start_severity'] = cold_start_severity
self.analysis_results['cold_start'] = analysis
print(f"冷启动问题检测完成:严重程度 {cold_start_severity}")
return analysis
def analyze_user_profiling(self, user_data: Optional[pd.DataFrame] = None,
item_data: Optional[pd.DataFrame] = None) -> Dict[str, Any]:
"""
用户画像分析
Args:
user_data: 用户行为数据(可选)
item_data: 商品信息数据(可选)
Returns:
用户画像分析结果字典
"""
if user_data is None:
user_data = self.user_data
if item_data is None:
item_data = self.item_data
if user_data is None:
print("没有可用的用户数据")
return {}
print("开始用户画像分析...")
analysis = {}
# 用户价值分析(RFM)
if '时间戳' in user_data.columns and '评分' in user_data.columns:
# Recency: 最近一次交互时间
recency = user_data.groupby('用户ID')['时间戳'].max().apply(lambda x: (user_data['时间戳'].max() - x).days)
# Frequency: 交互频率
frequency = user_data.groupby('用户ID').size()
# Monetary: 平均评分(作为价值指标)
monetary = user_data.groupby('用户ID')['评分'].mean()
# RFM分层
analysis['rfm_analysis'] = {
'recency_stats': {
'mean_days': float(recency.mean()),
'median_days': float(recency.median()),
'min_days': int(recency.min()),
'max_days': int(recency.max())
},
'frequency_stats': {
'mean_interactions': float(frequency.mean()),
'median_interactions': float(frequency.median()),
'min_interactions': int(frequency.min()),
'max_interactions': int(frequency.max())
},
'monetary_stats': {
'mean_rating': float(monetary.mean()),
'median_rating': float(monetary.median()),
'min_rating': float(monetary.min()),
'max_rating': float(monetary.max())
}
}
# 用户分层(基于RFM)
def classify_user(r, f, m):
if r <= recency.quantile(0.33) and f >= frequency.quantile(0.67) and m >= monetary.quantile(0.67):
return "高价值用户"
elif r <= recency.quantile(0.67) and f >= frequency.quantile(0.33):
return "价值用户"
elif r <= recency.quantile(0.67):
return "活跃用户"
elif f <= frequency.quantile(0.33) and r > recency.quantile(0.67):
return "流失风险用户"
else:
return "普通用户"
user_segments = pd.concat([recency, frequency, monetary], axis=1)
user_segments.columns = ['recency', 'frequency', 'monetary']
user_segments['segment'] = user_segments.apply(lambda x: classify_user(x['recency'], x['frequency'], x['monetary']), axis=1)
segment_counts = user_segments['segment'].value_counts()
analysis['user_segments'] = {
str(segment): int(count) for segment, count in segment_counts.items()
}
# 偏好分析
if '商品类别' in user_data.columns:
# 用户类别偏好
user_category_preference = user_data.groupby(['用户ID', '商品类别']).size().unstack(fill_value=0)
analysis['category_preference'] = {
'total_categories': int(len(user_data['商品类别'].unique())),
'avg_categories_per_user': float((user_category_preference > 0).sum(axis=1).mean()),
'most_diverse_user': int((user_category_preference > 0).sum(axis=1).max()),
'least_diverse_user': int((user_category_preference > 0).sum(axis=1).min())
}
# 用户忠诚度分析(重复购买同一类别)
category_loyalty = user_data.groupby('用户ID')['商品类别'].apply(lambda x: x.value_counts().iloc[0] / len(x))
analysis['loyalty_analysis'] = {
'avg_loyalty_score': float(category_loyalty.mean()),
'high_loyalty_users': int((category_loyalty >= 0.8).sum()),
'medium_loyalty_users': int((category_loyalty >= 0.5).sum() - (category_loyalty >= 0.8).sum()),
'low_loyalty_users': int((category_loyalty < 0.5).sum())
}
# 人口统计学分析(如果有相关信息)
demographic_fields = ['用户年龄', '用户性别', '用户城市']
available_demographics = [field for field in demographic_fields if field in user_data.columns]
if available_demographics:
analysis['demographics'] = {}
if '用户年龄' in user_data.columns:
age_stats = user_data['用户年龄'].describe()
analysis['demographics']['age'] = {
'mean': float(age_stats['mean']),
'median': float(age_stats['50%']),
'min': int(age_stats['min']),
'max': int(age_stats['max'])
}
if '用户性别' in user_data.columns:
gender_dist = user_data['用户性别'].value_counts().to_dict()
analysis['demographics']['gender'] = {str(k): int(v) for k, v in gender_dist.items()}
if '用户城市' in user_data.columns:
city_stats = user_data['用户城市'].value_counts().describe()
analysis['demographics']['cities'] = {
'total_cities': int(len(user_data['用户城市'].unique())),
'most_active_city': user_data['用户城市'].value_counts().index[0],
'most_active_city_users': int(user_data['用户城市'].value_counts().iloc[0])
}
self.analysis_results['user_profiling'] = analysis
print("用户画像分析完成")
return analysis
def generate_data_quality_report(self, user_data: Optional[pd.DataFrame] = None,
item_data: Optional[pd.DataFrame] = None) -> Dict[str, Any]:
"""
生成数据质量报告
Args:
user_data: 用户行为数据(可选)
item_data: 商品信息数据(可选)
Returns:
数据质量报告字典
"""
if user_data is None:
user_data = self.user_data
if item_data is None:
item_data = self.item_data
if user_data is None:
print("没有可用的用户数据")
return {}
print("开始生成数据质量报告...")
report = {
'generated_at': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
'user_data_quality': {},
'item_data_quality': {}
}
# 用户数据质量检查
if user_data is not None:
user_quality = {
'total_records': int(len(user_data)),
'missing_values': user_data.isnull().sum().to_dict(),
'duplicate_records': int(user_data.duplicated().sum()),
'data_types': user_data.dtypes.astype(str).to_dict()
}
# 检查异常值
if '评分' in user_data.columns:
rating_range = user_data['评分'].describe()
user_quality['rating_anomalies'] = {
'min_rating': float(rating_range['min']),
'max_rating': float(rating_range['max']),
'out_of_range_count': int(((user_data['评分'] < 1) | (user_data['评分'] > 5)).sum())
}
report['user_data_quality'] = user_quality
# 商品数据质量检查
if item_data is not None:
item_quality = {
'total_items': int(len(item_data)),
'missing_values': item_data.isnull().sum().to_dict(),
'duplicate_items': int(item_data.duplicated().sum()),
'data_types': item_data.dtypes.astype(str).to_dict()
}
report['item_data_quality'] = item_quality
# 数据一致性检查
if user_data is not None and item_data is not None:
user_items = set(user_data['商品ID'].unique())
catalog_items = set(item_data['商品ID'].unique())
consistency = {
'items_in_behavior_not_in_catalog': int(len(user_items - catalog_items)),
'items_in_catalog_not_in_behavior': int(len(catalog_items - user_items)),
'common_items': int(len(user_items & catalog_items))
}
report['data_consistency'] = consistency
# 数据覆盖度分析
if user_data is not None:
coverage = {
'user_coverage': float(len(user_data['用户ID'].unique())),
'item_coverage': float(len(user_data['商品ID'].unique())),
'interaction_coverage': float(len(user_data))
}
report['data_coverage'] = coverage
self.analysis_results['data_quality'] = report
print("数据质量报告生成完成")
return report
def save_analysis_results(self, file_path: str, format: str = 'json') -> None:
"""
保存分析结果
Args:
file_path: 保存路径
format: 保存格式 ('json', 'csv', 'excel')
"""
if format == 'json':
import json
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(self.analysis_results, f, ensure_ascii=False, indent=2, default=str)
elif format == 'csv':
# 将结果扁平化并保存为CSV
flat_data = {}
for category, results in self.analysis_results.items():
if isinstance(results, dict):
for key, value in results.items():
if isinstance(value, dict):
for sub_key, sub_value in value.items():
flat_data[f"{category}_{key}_{sub_key}"] = sub_value
else:
flat_data[f"{category}_{key}"] = value
else:
flat_data[category] = results
df = pd.DataFrame([flat_data])
df.to_csv(file_path, index=False, encoding='utf-8')
print(f"分析结果已保存到: {file_path}")
def get_analysis_summary(self) -> str:
"""
获取分析结果摘要
Returns:
分析结果摘要文本
"""
if not self.analysis_results:
return "暂无分析结果"
summary = "# 数据分析结果摘要\n\n"
# 用户行为摘要
if 'user_behavior' in self.analysis_results:
ub = self.analysis_results['user_behavior']
summary += f"## 用户行为分析\n"
summary += f"- 总用户数: {ub.get('total_users', 'N/A'):,}\n"
summary += f"- 总商品数: {ub.get('total_items', 'N/A'):,}\n"
summary += f"- 总交互次数: {ub.get('total_interactions', 'N/A'):,}\n"
if 'user_activity' in ub:
summary += f"- 平均用户活跃度: {ub['user_activity'].get('mean', 'N/A'):.1f}\n"
summary += "\n"
# 商品热度摘要
if 'item_popularity' in self.analysis_results:
ip = self.analysis_results['item_popularity']
summary += f"## 商品热度分析\n"
if 'cold_start_items' in ip:
summary += f"- 冷门商品比例: {ip['cold_start_items'].get('percentage', 'N/A'):.1f}%\n"
summary += "\n"
# 数据稀疏度摘要
if 'sparsity' in self.analysis_results:
sp = self.analysis_results['sparsity']
summary += f"## 数据稀疏度\n"
summary += f"- 稀疏度: {sp.get('sparsity_ratio', 'N/A'):.2%}\n"
summary += f"- 密度: {sp.get('density_ratio', 'N/A'):.2%}\n"
summary += "\n"
# 冷启动问题摘要
if 'cold_start' in self.analysis_results:
cs = self.analysis_results['cold_start']
summary += f"## 冷启动问题\n"
summary += f"- 严重程度: {cs.get('cold_start_severity', 'N/A')}\n"
if 'user_cold_start' in cs:
summary += f"- 新用户比例: {cs['user_cold_start'].get('new_users_percentage', 'N/A'):.1f}%\n"
if 'item_cold_start' in cs:
summary += f"- 新商品比例: {cs['item_cold_start'].get('new_items_percentage', 'N/A'):.1f}%\n"
summary += "\n"
# 用户画像摘要
if 'user_profiling' in self.analysis_results:
up = self.analysis_results['user_profiling']
summary += f"## 用户画像分析\n"
if 'user_segments' in up:
summary += "- 用户分层:\n"
for segment, count in up['user_segments'].items():
summary += f" - {segment}: {count:,} 用户\n"
summary += "\n"
return summary"""
推荐系统算法引擎
提供多种推荐算法实现:
- 基于用户的协同过滤 (User-Based Collaborative Filtering)
- 基于物品的协同过滤 (Item-Based Collaborative Filtering)
- SVD矩阵分解推荐 (Singular Value Decomposition)
- 混合推荐策略 (Hybrid Recommendation)
"""
import pandas as pd
import numpy as np
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.decomposition import TruncatedSVD
from sklearn.preprocessing import StandardScaler
from typing import List, Dict, Tuple, Optional, Union
import warnings
warnings.filterwarnings('ignore')
class RecommendationEngine:
"""推荐系统算法引擎类"""
def __init__(self):
self.user_item_matrix = None
self.item_user_matrix = None
self.user_similarity_matrix = None
self.item_similarity_matrix = None
self.svd_model = None
self.user_factors = None
self.item_factors = None
self.user_to_idx = {}
self.idx_to_user = {}
self.item_to_idx = {}
self.idx_to_item = {}
self.is_trained = False
def load_data(self, user_behavior_path: str, item_info_path: Optional[str] = None) -> Tuple[pd.DataFrame, Optional[pd.DataFrame]]:
"""
加载用户行为数据和商品信息数据
Args:
user_behavior_path: 用户行为数据文件路径
item_info_path: 商品信息数据文件路径(可选)
Returns:
用户行为数据和商品信息数据的元组
"""
try:
# 加载用户行为数据
self.user_data = pd.read_csv(user_behavior_path, encoding='utf-8')
# 数据预处理
if '评分' in self.user_data.columns:
self.user_data['评分'] = pd.to_numeric(self.user_data['评分'], errors='coerce')
self.user_data.dropna(subset=['评分'], inplace=True)
# 构建用户-商品矩阵
self._build_interaction_matrices()
# 加载商品信息数据(如果提供)
item_data = None
if item_info_path:
item_data = pd.read_csv(item_info_path, encoding='utf-8')
print(f"数据加载成功:用户数 {len(self.user_item_matrix.index)}, 商品数 {len(self.user_item_matrix.columns)}")
return self.user_data, item_data
except Exception as e:
print(f"数据加载失败:{str(e)}")
return None, None
def _build_interaction_matrices(self) -> None:
"""构建用户-商品交互矩阵和商品-用户交互矩阵"""
if '评分' in self.user_data.columns:
# 基于评分构建矩阵
self.user_item_matrix = self.user_data.pivot_table(
index='用户ID', columns='商品ID', values='评分',
fill_value=0, aggfunc='mean'
)
else:
# 基于行为次数构建矩阵
self.user_item_matrix = self.user_data.pivot_table(
index='用户ID', columns='商品ID', values='行为类型',
fill_value=0, aggfunc='count'
)
# 构建商品-用户矩阵(用于物品协同过滤)
self.item_user_matrix = self.user_item_matrix.T
def train_user_based_cf(self, similarity_metric: str = 'cosine', normalize: bool = True) -> None:
"""
训练基于用户的协同过滤模型
Args:
similarity_metric: 相似度计算方法 ('cosine', 'pearson')
normalize: 是否对用户评分进行标准化
"""
print("开始训练基于用户的协同过滤模型...")
# 数据标准化
if normalize:
scaler = StandardScaler()
matrix_scaled = scaler.fit_transform(self.user_item_matrix)
user_item_matrix_scaled = pd.DataFrame(
matrix_scaled,
index=self.user_item_matrix.index,
columns=self.user_item_matrix.columns
)
else:
user_item_matrix_scaled = self.user_item_matrix
# 计算用户相似度矩阵
if similarity_metric == 'cosine':
similarities = cosine_similarity(user_item_matrix_scaled)
elif similarity_metric == 'pearson':
# 皮尔逊相关系数
similarities = np.corrcoef(user_item_matrix_scaled)
else:
raise ValueError(f"不支持的相似度计算方法: {similarity_metric}")
self.user_similarity_matrix = pd.DataFrame(
similarities,
index=self.user_item_matrix.index,
columns=self.user_item_matrix.index
)
print("基于用户的协同过滤模型训练完成")
def train_item_based_cf(self, similarity_metric: str = 'cosine') -> None:
"""
训练基于物品的协同过滤模型
Args:
similarity_metric: 相似度计算方法 ('cosine', 'pearson')
"""
print("开始训练基于物品的协同过滤模型...")
# 计算物品相似度矩阵
if similarity_metric == 'cosine':
similarities = cosine_similarity(self.item_user_matrix)
elif similarity_metric == 'pearson':
similarities = np.corrcoef(self.item_user_matrix)
else:
raise ValueError(f"不支持的相似度计算方法: {similarity_metric}")
self.item_similarity_matrix = pd.DataFrame(
similarities,
index=self.item_user_matrix.index,
columns=self.item_user_matrix.index
)
print("基于物品的协同过滤模型训练完成")
def train_svd(self, n_components: int = 50, random_state: int = 42) -> None:
"""
训练SVD矩阵分解模型
Args:
n_components: SVD组件数量
random_state: 随机种子
"""
print("开始训练SVD矩阵分解模型...")
# 创建索引映射
self.user_to_idx = {user: i for i, user in enumerate(self.user_item_matrix.index)}
self.idx_to_user = {i: user for user, i in self.user_to_idx.items()}
self.item_to_idx = {item: i for i, item in enumerate(self.user_item_matrix.columns)}
self.idx_to_item = {i: item for item, i in self.item_to_idx.items()}
# 训练SVD模型
self.svd_model = TruncatedSVD(n_components=n_components, random_state=random_state)
self.user_factors = self.svd_model.fit_transform(self.user_item_matrix)
self.item_factors = self.svd_model.components_.T
print(f"SVD矩阵分解模型训练完成,组件数量: {n_components}")
print(f"用户因子维度: {self.user_factors.shape}, 商品因子维度: {self.item_factors.shape}")
def recommend_user_based_cf(self, user_id: str, top_k: int = 5,
n_neighbors: int = 50) -> List[Tuple[str, float]]:
"""
基于用户的协同过滤推荐
Args:
user_id: 目标用户ID
top_k: 推荐商品数量
n_neighbors: 相似邻居数量
Returns:
推荐商品列表,格式为 [(商品ID, 预测评分), ...]
"""
if self.user_similarity_matrix is None:
raise ValueError("请先训练基于用户的协同过滤模型")
if user_id not in self.user_item_matrix.index:
print(f"警告: 用户 {user_id} 不在训练数据中,返回热门商品推荐")
return self._recommend_popular_items(top_k)
# 获取相似用户
similar_users = self.user_similarity_matrix[user_id].sort_values(ascending=False)
similar_users = similar_users.drop(user_id, errors='ignore')[:n_neighbors]
# 获取用户已评分的商品
user_rated_items = set(self.user_item_matrix.loc[user_id][self.user_item_matrix.loc[user_id] > 0].index)
# 计算推荐分数
recommendations = {}
for similar_user, similarity in similar_users.items():
if similarity <= 0:
continue
similar_user_ratings = self.user_item_matrix.loc[similar_user]
for item_id, rating in similar_user_ratings.items():
if item_id not in user_rated_items and rating > 0:
if item_id not in recommendations:
recommendations[item_id] = 0
recommendations[item_id] += similarity * rating
# 归一化推荐分数
for item_id in recommendations:
recommendations[item_id] /= len(similar_users)
# 返回top-k推荐
sorted_recommendations = sorted(recommendations.items(), key=lambda x: x[1], reverse=True)
return sorted_recommendations[:top_k]
def recommend_item_based_cf(self, user_id: str, top_k: int = 5,
n_neighbors: int = 50) -> List[Tuple[str, float]]:
"""
基于物品的协同过滤推荐
Args:
user_id: 目标用户ID
top_k: 推荐商品数量
n_neighbors: 相似邻居数量
Returns:
推荐商品列表,格式为 [(商品ID, 预测评分), ...]
"""
if self.item_similarity_matrix is None:
raise ValueError("请先训练基于物品的协同过滤模型")
if user_id not in self.user_item_matrix.index:
print(f"警告: 用户 {user_id} 不在训练数据中,返回热门商品推荐")
return self._recommend_popular_items(top_k)
# 获取用户已评分的商品
user_ratings = self.user_item_matrix.loc[user_id]
user_rated_items = user_ratings[user_ratings > 0]
if len(user_rated_items) == 0:
print(f"警告: 用户 {user_id} 没有评分记录,返回热门商品推荐")
return self._recommend_popular_items(top_k)
# 计算推荐分数
recommendations = {}
for rated_item, rating in user_rated_items.items():
# 获取与该商品相似的商品
similar_items = self.item_similarity_matrix[rated_item].sort_values(ascending=False)
similar_items = similar_items.drop(rated_item, errors='ignore')[:n_neighbors]
for similar_item, similarity in similar_items.items():
if similarity <= 0 or similar_item in user_rated_items.index:
continue
if similar_item not in recommendations:
recommendations[similar_item] = 0
recommendations[similar_item] += similarity * rating
# 归一化推荐分数
for item_id in recommendations:
recommendations[item_id] /= len(user_rated_items)
# 返回top-k推荐
sorted_recommendations = sorted(recommendations.items(), key=lambda x: x[1], reverse=True)
return sorted_recommendations[:top_k]
def recommend_svd(self, user_id: str, top_k: int = 5) -> List[Tuple[str, float]]:
"""
SVD矩阵分解推荐
Args:
user_id: 目标用户ID
top_k: 推荐商品数量
Returns:
推荐商品列表,格式为 [(商品ID, 预测评分), ...]
"""
if self.svd_model is None:
raise ValueError("请先训练SVD矩阵分解模型")
if user_id not in self.user_to_idx:
print(f"警告: 用户 {user_id} 不在训练数据中,返回热门商品推荐")
return self._recommend_popular_items(top_k)
user_idx = self.user_to_idx[user_id]
# 获取用户已评分的商品
user_ratings = self.user_item_matrix.loc[user_id]
rated_items = user_ratings[user_ratings > 0].index.tolist()
# 计算该用户对所有商品的预测评分
predicted_ratings = np.dot(self.user_factors[user_idx], self.item_factors.T)
# 创建预测评分Series
predictions = pd.Series(predicted_ratings, index=self.user_item_matrix.columns)
# 过滤掉用户已评分的商品
recommendations = predictions.drop(rated_items, errors='ignore').sort_values(ascending=False).head(top_k)
# 返回推荐列表
return [(item_id, float(score)) for item_id, score in recommendations.items()]
def recommend_hybrid(self, user_id: str, top_k: int = 5,
weights: Optional[Dict[str, float]] = None) -> List[Tuple[str, float]]:
"""
混合推荐策略
Args:
user_id: 目标用户ID
top_k: 推荐商品数量
weights: 各算法权重,格式为 {'user_cf': 0.3, 'item_cf': 0.3, 'svd': 0.4}
Returns:
推荐商品列表,格式为 [(商品ID, 预测评分), ...]
"""
# 默认权重
if weights is None:
weights = {'user_cf': 0.3, 'item_cf': 0.3, 'svd': 0.4}
# 检查权重总和
if abs(sum(weights.values()) - 1.0) > 0.001:
raise ValueError("权重总和必须为1.0")
recommendations = {}
# 基于用户的协同过滤
if 'user_cf' in weights and self.user_similarity_matrix is not None:
user_cf_recs = self.recommend_user_based_cf(user_id, top_k * 2)
for item_id, score in user_cf_recs:
if item_id not in recommendations:
recommendations[item_id] = 0
recommendations[item_id] += weights['user_cf'] * score
# 基于物品的协同过滤
if 'item_cf' in weights and self.item_similarity_matrix is not None:
item_cf_recs = self.recommend_item_based_cf(user_id, top_k * 2)
for item_id, score in item_cf_recs:
if item_id not in recommendations:
recommendations[item_id] = 0
recommendations[item_id] += weights['item_cf'] * score
# SVD矩阵分解
if 'svd' in weights and self.svd_model is not None:
svd_recs = self.recommend_svd(user_id, top_k * 2)
for item_id, score in svd_recs:
if item_id not in recommendations:
recommendations[item_id] = 0
recommendations[item_id] += weights['svd'] * score
# 如果没有可用的算法,返回热门推荐
if not recommendations:
return self._recommend_popular_items(top_k)
# 返回top-k推荐
sorted_recommendations = sorted(recommendations.items(), key=lambda x: x[1], reverse=True)
return sorted_recommendations[:top_k]
def _recommend_popular_items(self, top_k: int) -> List[Tuple[str, float]]:
"""
推荐热门商品(冷启动策略)
Args:
top_k: 推荐商品数量
Returns:
推荐商品列表,格式为 [(商品ID, 热度分数), ...]
"""
# 计算商品热度(评分用户数和平均评分的组合)
item_popularity = {}
for item_id in self.user_item_matrix.columns:
ratings = self.user_item_matrix[item_id]
num_ratings = len(ratings[ratings > 0])
avg_rating = ratings[ratings > 0].mean() if num_ratings > 0 else 0
# 热度计算:评分用户数 * 平均评分
popularity = num_ratings * avg_rating
item_popularity[item_id] = popularity
# 返回热门商品
sorted_items = sorted(item_popularity.items(), key=lambda x: x[1], reverse=True)
return sorted_items[:top_k]
def get_model_info(self) -> Dict[str, Union[str, int, float]]:
"""
获取模型信息
Returns:
包含模型基本信息的字典
"""
info = {
'user_count': len(self.user_item_matrix.index) if self.user_item_matrix is not None else 0,
'item_count': len(self.user_item_matrix.columns) if self.user_item_matrix is not None else 0,
'matrix_sparsity': self._calculate_sparsity() if self.user_item_matrix is not None else 0,
'user_cf_trained': self.user_similarity_matrix is not None,
'item_cf_trained': self.item_similarity_matrix is not None,
'svd_trained': self.svd_model is not None,
'svd_components': self.svd_model.n_components if self.svd_model else 0
}
return info
def _calculate_sparsity(self) -> float:
"""计算用户-商品矩阵的稀疏度"""
if self.user_item_matrix is None:
return 0
total_entries = self.user_item_matrix.shape[0] * self.user_item_matrix.shape[1]
zero_entries = (self.user_item_matrix == 0).sum().sum()
sparsity = zero_entries / total_entries
return float(sparsity)
def save_model(self, file_path: str) -> None:
"""
保存训练好的模型
Args:
file_path: 模型保存路径
"""
import pickle
model_data = {
'user_item_matrix': self.user_item_matrix,
'item_user_matrix': self.item_user_matrix,
'user_similarity_matrix': self.user_similarity_matrix,
'item_similarity_matrix': self.item_similarity_matrix,
'svd_model': self.svd_model,
'user_factors': self.user_factors,
'item_factors': self.item_factors,
'user_to_idx': self.user_to_idx,
'idx_to_user': self.idx_to_user,
'item_to_idx': self.item_to_idx,
'idx_to_item': self.idx_to_item
}
with open(file_path, 'wb') as f:
pickle.dump(model_data, f)
print(f"模型已保存到: {file_path}")
def load_model(self, file_path: str) -> None:
"""
加载预训练模型
Args:
file_path: 模型文件路径
"""
import pickle
with open(file_path, 'rb') as f:
model_data = pickle.load(f)
self.user_item_matrix = model_data.get('user_item_matrix')
self.item_user_matrix = model_data.get('item_user_matrix')
self.user_similarity_matrix = model_data.get('user_similarity_matrix')
self.item_similarity_matrix = model_data.get('item_similarity_matrix')
self.svd_model = model_data.get('svd_model')
self.user_factors = model_data.get('user_factors')
self.item_factors = model_data.get('item_factors')
self.user_to_idx = model_data.get('user_to_idx', {})
self.idx_to_user = model_data.get('idx_to_user', {})
self.item_to_idx = model_data.get('item_to_idx', {})
self.idx_to_item = model_data.get('idx_to_item', {})
self.is_trained = True
print(f"模型已从 {file_path} 加载")