1. 项目概述
这个基于协同过滤算法的理财产品推荐系统是我在金融科技领域的一次实践探索。作为一名长期从事Web开发的工程师,我发现传统理财产品推荐方式存在明显的局限性——要么是简单粗暴的热门推荐,要么是完全不考虑用户偏好的随机展示。这促使我决定开发一个能够真正理解用户需求的个性化推荐系统。
系统采用Python 3.8作为开发语言,Flask作为后端框架,配合MySQL 5.7数据库和Vue.js前端技术栈。核心的创新点在于将协同过滤算法应用于理财产品推荐场景,通过分析用户的收藏行为建立推荐模型。整个系统包含用户端和管理端两大模块,实现了从产品展示、个性化推荐到后台管理的完整闭环。
提示:选择Flask而非Django等全功能框架,主要是考虑到理财推荐系统的轻量级需求,Flask的灵活性更适合快速迭代和算法集成。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 系统架构设计
2.1 技术选型解析
后端选择Python+Flask组合主要基于以下考量:
- Python在数据分析和算法实现方面有丰富生态(NumPy、Pandas等)
- Flask轻量灵活,适合快速开发RESTful API
- 与协同过滤算法的Python实现天然契合
数据库选用MySQL 5.7的原因:
- 成熟稳定,社区支持完善
- 事务处理能力强,适合金融场景
- 与Python生态的SQLAlchemy等ORM配合良好
前端采用Vue.js的考虑:
- 组件化开发模式适合复杂交互界面
- 响应式特性提升用户体验
- 与Flask后端API对接简便
2.2 系统模块划分
系统采用经典的三层架构:
- 表现层:Vue.js构建的用户界面
- 业务逻辑层:Flask实现的核心业务和推荐算法
- 数据访问层:SQLAlchemy操作的MySQL数据库
关键功能模块包括:
- 用户认证模块(JWT实现)
- 理财产品管理模块
- 订单处理模块
- 协同过滤推荐模块
- 反馈管理模块
3. 核心算法实现
3.1 协同过滤算法原理
系统采用基于用户的协同过滤(User-based CF)算法,其核心思想是:
- 找到与目标用户兴趣相似的其他用户
- 将这些相似用户喜欢的、但目标用户未接触过的产品推荐给目标用户
相似度计算采用余弦相似度公式:
code复制similarity = sum(a*b for a,b in zip(userA,userB)) /
(sqrt(sum(a² for a in userA)) *
sqrt(sum(b² for b in userB)))
3.2 算法代码详解
python复制# 计算余弦相似度
def cosine_similarity(a, b):
numerator = sum([a[key] * b[key] for key in a if key in b])
denominator = math.sqrt(sum([a[key]**2 for key in a])) * math.sqrt(sum([b[key]**2 for key in b]))
return numerator / denominator
# 推荐接口实现
@main_bp.route("/recommend", methods=['GET'])
def get_recommendations():
# 获取用户收藏数据构建评分矩阵
user_ratings = {}
sql = "SELECT * FROM storeup WHERE type = 1 AND tablename = 'licaichanpin'"
data = db.session.execute(sql)
# 构建用户-产品评分字典
for item in data:
if item["userid"] not in user_ratings:
user_ratings[item["userid"]] = {}
user_ratings[item["userid"]][str(item["refid"])] = 1
# 计算相似用户
target_user = session.get("userid")
similarities = {
user: cosine_similarity(user_ratings[target_user], user_ratings[user])
for user in user_ratings if user != target_user
}
# 生成推荐
most_similar_user = max(similarities, key=similarities.get)
recommendations = [
product for product in user_ratings[most_similar_user]
if product not in user_ratings[target_user]
]
return jsonify(recommendations)
3.3 算法优化实践
在实际应用中,我们发现几个关键优化点:
-
数据稀疏性问题:
- 初始实现中,新用户因缺乏历史数据难以获得准确推荐
- 解决方案:引入混合推荐策略,新用户展示热门产品
-
实时性挑战:
- 用户行为数据更新后,推荐结果不能立即反映变化
- 解决方案:实现增量更新机制,每小时重新计算相似度
-
冷启动问题:
- 新产品上线初期缺乏用户行为数据
- 解决方案:结合产品属性相似度进行补充推荐
4. 系统实现细节
4.1 数据库设计
核心表结构设计:
用户表(users)
sql复制CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) UNIQUE NOT NULL,
password VARCHAR(100) NOT NULL,
phone VARCHAR(20),
email VARCHAR(50),
create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);
理财产品表(licaichanpin)
sql复制CREATE TABLE licaichanpin (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
type VARCHAR(50) NOT NULL,
rate DECIMAL(5,2) NOT NULL,
min_amount DECIMAL(12,2) NOT NULL,
duration INT COMMENT '投资期限(天)',
risk_level VARCHAR(20),
description TEXT,
create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);
收藏表(storeup)
sql复制CREATE TABLE storeup (
id INT PRIMARY KEY AUTO_INCREMENT,
userid INT NOT NULL,
refid INT NOT NULL,
tablename VARCHAR(50) NOT NULL,
type INT DEFAULT 1 COMMENT '1收藏 2点赞',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (userid) REFERENCES users(id)
);
4.2 关键API实现
用户登录接口
python复制@app.route('/api/login', methods=['POST'])
def login():
data = request.get_json()
user = User.query.filter_by(username=data['username']).first()
if not user or not check_password_hash(user.password, data['password']):
return jsonify({'error': 'Invalid credentials'}), 401
# 生成JWT token
token = jwt.encode({
'user_id': user.id,
'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=24)
}, app.config['SECRET_KEY'])
return jsonify({'token': token})
理财产品推荐接口
python复制@app.route('/api/products/recommend', methods=['GET'])
@token_required
def recommend_products(current_user):
# 获取推荐产品ID列表
recommended_ids = get_recommendations(current_user.id)
# 查询产品详情
products = Product.query.filter(Product.id.in_(recommended_ids)).all()
return jsonify([{
'id': p.id,
'name': p.name,
'type': p.type,
'rate': float(p.rate),
'min_amount': float(p.min_amount)
} for p in products])
4.3 前端关键实现
产品推荐组件(Vue)
javascript复制<template>
<div class="recommendations">
<h3>为您推荐</h3>
<div v-if="loading" class="loading">加载中...</div>
<div v-else>
<div v-for="product in products" :key="product.id" class="product-card">
<h4>{{ product.name }}</h4>
<p>预期收益率: {{ product.rate }}%</p>
<button @click="viewDetail(product.id)">查看详情</button>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
products: [],
loading: true
}
},
mounted() {
this.fetchRecommendations()
},
methods: {
async fetchRecommendations() {
try {
const response = await axios.get('/api/products/recommend', {
headers: { Authorization: `Bearer ${localStorage.getItem('token')}` }
})
this.products = response.data
} catch (error) {
console.error('获取推荐失败:', error)
} finally {
this.loading = false
}
},
viewDetail(id) {
this.$router.push(`/product/${id}`)
}
}
}
</script>
5. 部署与性能优化
5.1 系统部署方案
采用Nginx+Gunicorn+Flask的经典部署架构:
- Nginx:作为反向代理和静态文件服务器
- Gunicorn:WSGI应用服务器,运行Flask应用
- MySQL:单独部署在专用服务器
典型Nginx配置:
nginx复制server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /static {
alias /path/to/your/static/files;
}
}
启动Gunicorn:
bash复制gunicorn -w 4 -b 127.0.0.1:8000 wsgi:app
5.2 性能优化实践
-
数据库优化:
- 为常用查询字段添加索引
- 使用SQLAlchemy的批量操作减少数据库请求
- 实现查询结果缓存
-
推荐算法优化:
- 预计算用户相似度矩阵,定期更新
- 实现基于Redis的缓存层,存储临时推荐结果
- 对稀疏矩阵采用压缩存储格式
-
前端性能优化:
- 实现懒加载和分页机制
- 使用Webpack打包压缩静态资源
- 启用HTTP/2和Gzip压缩
6. 测试与问题排查
6.1 关键测试用例
推荐算法准确性测试
python复制def test_recommendation_accuracy():
# 构建测试数据
test_data = {
'user1': {'product1': 1, 'product2': 1, 'product3': 1},
'user2': {'product1': 1, 'product4': 1, 'product5': 1},
'user3': {'product2': 1, 'product3': 1, 'product6': 1}
}
# 测试相似度计算
assert cosine_similarity(test_data['user1'], test_data['user2']) == 0.5
assert cosine_similarity(test_data['user1'], test_data['user3']) == 0.816
# 测试推荐生成
recommendations = generate_recommendations('user1', test_data)
assert 'product4' in recommendations
assert 'product5' in recommendations
6.2 常见问题排查
-
推荐结果不稳定
- 可能原因:用户行为数据不足
- 解决方案:设置最低相似度阈值,低于阈值时回退到热门推荐
-
高并发时响应慢
- 可能原因:相似度计算未缓存
- 解决方案:实现基于Redis的缓存层,设置合理过期时间
-
新用户推荐质量差
- 可能原因:冷启动问题
- 解决方案:收集用户注册时的风险偏好问卷数据作为初始特征
7. 项目总结与改进方向
这个理财推荐系统实现了基于协同过滤算法的个性化推荐核心功能,在实际测试中展现出了不错的推荐准确性。Flask框架的轻量特性使得系统能够快速迭代,而Vue.js前端则提供了良好的用户体验。
几个值得改进的方向:
- 引入更多推荐策略,如基于内容的推荐、混合推荐等
- 增加实时推荐能力,响应用户即时行为
- 优化算法性能,支持更大规模的用户和产品数据
- 加强推荐解释功能,让用户理解推荐理由
在开发过程中,我深刻体会到金融类系统对数据准确性和安全性的高要求。每个数据库操作都需要严格的事务处理,每次算法更新都需要充分的测试验证。这些经验对我后续开发其他金融科技项目大有裨益。
