这个基于双协同过滤算法的商品推荐系统是我在电商推荐领域的一次完整实践。系统采用Python+Django技术栈开发,核心功能是通过基于用户和基于物品的两种协同过滤算法,为电商平台用户提供个性化商品推荐服务。
在电商平台商品数量爆炸式增长的今天,用户面临严重的信息过载问题。传统热门推荐缺乏个性化,无法满足用户多样化需求。这个系统正是为了解决这些痛点而设计,通过算法分析用户行为和商品特征,实现精准推荐。
系统架构上,后端使用Django框架搭建,MySQL存储核心数据,SQLite存储轻量配置信息。前端采用Bootstrap构建响应式界面,并集成Echarts实现数据可视化。整个系统包含完整的用户交互模块和后台管理功能,形成了一个从数据收集、算法推荐到可视化展示的完整闭环。
选择Django作为后端框架主要基于以下考虑:
数据库采用MySQL+SQLite双存储方案:
这种组合既保证了核心数据的高效存取,又简化了配置管理,特别适合中小型推荐系统。
前端技术栈选择基于以下考量:
特别值得一提的是Echarts的集成,它让我们能够直观展示推荐效果和用户行为分析结果,为运营决策提供数据支持。
基于用户的协同过滤(UserCF)是本系统的核心算法之一,其核心思想是"相似用户喜欢相似商品"。算法实现步骤如下:
python复制def pearson(self, user1, user2):
sum_xy = 0.0 # 共同评分项乘积和
n = 0 # 共同评分项数
sum_x = 0.0 # user1评分和
sum_y = 0.0 # user2评分和
sumX2 = 0.0 # user1评分平方和
sumY2 = 0.0 # user2评分平方和
for shop1, score1 in user1.items():
if shop1 in user2.keys():
n += 1
sum_xy += score1 * user2[shop1]
sum_x += score1
sum_y += user2[shop1]
sumX2 += pow(score1, 2)
sumY2 += pow(user2[shop1], 2)
if n == 0:
return 0
molecule = sum_xy - (sum_x * sum_y) / n
denominator = sqrt((sumX2 - pow(sum_x, 2)/n) * (sumY2 - pow(sum_y, 2)/n))
if denominator == 0:
return 0
return molecule / denominator
python复制def nearest_user(self, current_user, n=1):
distances = {}
for user, rate_set in self.all_user.items():
if user != current_user:
distance = self.pearson(self.all_user[current_user], self.all_user[user])
distances[user] = distance
return sorted(distances.items(), key=operator.itemgetter(1), reverse=True)[:n]
python复制def recommend(self, username, n=3):
recommend = {}
nearest_user = self.nearest_user(username, n)
for user, score in dict(nearest_user).items():
for shops, scores in self.all_user[user].items():
if shops not in self.all_user[username].keys():
if shops not in recommend.keys():
recommend[shops] = scores*score
return sorted(recommend.items(), key=operator.itemgetter(1), reverse=True)
基于物品的协同过滤(ItemCF)是本系统的另一个核心算法,其核心思想是"用户喜欢与其历史偏好相似的商品"。算法实现步骤如下:
python复制def similarity(shop1_id, shop2_id):
shop1_set = Rate.objects.filter(shop_id=shop1_id)
shop1_sum = shop1_set.count()
shop2_sum = Rate.objects.filter(shop_id=shop2_id).count()
common = Rate.objects.filter(user_id__in=Subquery(shop1_set.values('user_id')),
shop=shop2_id).values('user_id').count()
if shop1_sum == 0 or shop2_sum == 0:
return 0
return common / sqrt(shop1_sum * shop2_sum)
python复制def recommend_by_item_id(user_id, k=15):
user_prefer = UserTagPrefer.objects.filter(user_id=user_id)
.order_by('-score').values_list('tag_id', flat=True)[:3]
current_user = User.objects.get(id=user_id)
if current_user.rate_set.count() == 0:
if len(user_prefer) != 0:
return shop.objects.filter(tags__in=user_prefer)[:15]
else:
return shop.objects.order_by("-num")[:15]
un_watched = shop.objects.filter(~Q(rate__user_id=user_id),
tags__in=user_prefer).order_by('?')[:30]
watched = Rate.objects.filter(user_id=user_id).values_list('shop_id', 'mark')
distances = []
for un_watched_shop in un_watched:
for watched_shop in watched:
distances.append((similarity(un_watched_shop.id, watched_shop[0])
* watched_shop[1], un_watched_shop))
distances.sort(key=lambda x: x[0], reverse=True)
recommend_list = []
for mark, shop in distances:
if len(recommend_list) >= k:
break
if shop not in recommend_list:
recommend_list.append(shop)
return recommend_list
在实际应用中,我们采用加权融合的方式结合两种算法的推荐结果:
通过AB测试,我们确定在当前的电商场景下,w1=0.4, w2=0.6能取得最佳的推荐效果。
用户交互模块包含完整的电商功能:
关键实现代码片段:
python复制# 商品详情视图
def shop_detail(request, shop_id):
shop = get_object_or_404(Shop, id=shop_id)
# 记录用户浏览行为
if request.user.is_authenticated:
UserBehavior.objects.create(
user=request.user,
shop=shop,
behavior_type='view',
created_time=timezone.now()
)
# 获取基于用户的推荐
user_recommends = recommend_by_user_id(request.user.id)[:5]
# 获取基于物品的推荐
item_recommends = recommend_by_item_id(request.user.id)[:5]
return render(request, 'shop/detail.html', {
'shop': shop,
'user_recommends': user_recommends,
'item_recommends': item_recommends
})
系统集成了四种数据可视化图表:
可视化实现基于Echarts,前端关键代码:
javascript复制// 柱状图初始化
function initBarChart(data) {
var chart = echarts.init(document.getElementById('bar-chart'));
var option = {
title: { text: '商品销量排行' },
tooltip: {},
xAxis: { data: data.categories },
yAxis: {},
series: [{
name: '销量',
type: 'bar',
data: data.values
}]
};
chart.setOption(option);
return chart;
}
// 词云图初始化
function initWordCloud(data) {
var chart = echarts.init(document.getElementById('word-cloud'));
var option = {
series: [{
type: 'wordCloud',
shape: 'circle',
data: data.words
}]
};
chart.setOption(option);
return chart;
}
后台管理功能基于Django Admin二次开发,主要功能包括:
关键实现代码:
python复制# 自定义Admin后台
class ShopAdmin(admin.ModelAdmin):
list_display = ('name', 'price', 'category', 'sales')
list_filter = ('category', 'tags')
search_fields = ('name', 'description')
readonly_fields = ('sales', 'views')
# 自定义操作
actions = ['update_recommend']
def update_recommend(self, request, queryset):
# 批量更新推荐分数
for shop in queryset:
update_item_similarity(shop.id)
self.message_user(request, "推荐分数更新成功")
admin.site.register(Shop, ShopAdmin)
系统采用Nginx+Gunicorn+Django的经典部署架构:
部署关键步骤:
bash复制# 安装依赖
pip install -r requirements.txt
# 数据库迁移
python manage.py migrate
# 收集静态文件
python manage.py collectstatic
# 启动Gunicorn
gunicorn --workers 4 --bind 0.0.0.0:8000 recomend.wsgi:application
# Nginx配置示例
server {
listen 80;
server_name yourdomain.com;
location /static/ {
alias /path/to/static/files;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
针对推荐系统的性能瓶颈,我们实施了以下优化措施:
关键优化代码示例:
python复制# 使用缓存装饰器
from django.core.cache import cache
@cache_page(60 * 30) # 缓存30分钟
def get_user_recommend(request, user_id):
# 获取用户推荐
...
# 使用Celery异步任务
@app.task
def calculate_item_similarity(shop_id):
# 计算商品相似度
...
这个推荐系统项目从技术选型到算法实现,再到最终部署上线,整个过程让我收获颇丰。以下是一些关键的经验总结:
在实际开发过程中,最大的挑战是处理大规模用户行为数据时的性能问题。通过引入缓存、优化数据库查询、实现增量计算等策略,我们最终将推荐响应时间控制在200ms以内,满足了线上服务的性能要求。
这个项目让我深刻体会到,一个好的推荐系统不仅需要优秀的算法,还需要考虑工程实现、性能优化、用户体验等全方位因素。未来,我计划引入深度学习模型来进一步提升推荐效果,同时优化系统的可扩展性,以支持更大规模的用户和商品数据。