推荐算法实战经验分享:从数据到上线的那些坑

推荐算法不是纸上谈兵

做推荐系统这行几年了,从最早的协同过滤做到现在的深度学习模型,踩过的坑比走过的路还多。很多人一上来就想搞个“完美”模型,结果跑不通、推不准、用户还不买账。今天不讲理论,就说说我实际项目里怎么一步步把推荐系统跑起来的。

数据准备:别急着建模,先看清楚你的“食材”

很多团队一立项就冲着模型去,其实80%的问题出在数据上。我之前接手一个电商项目,日志看着挺全,结果发现用户点击记录里夹杂大量机器人流量,直接拿这种数据训练,推荐出来全是冷门商品。

建议第一步先做简单的统计分析:

import pandas as pd

# 查看用户行为分布
df = pd.read_csv('user_actions.csv')
print(df['user_id'].value_counts().describe())
print(df['item_id'].value_counts().describe())

如果发现少数用户占了大部分行为,或者少数商品被反复点击,就得考虑采样或加权策略,不然模型会被“头部效应”带偏。

从简单模型开始:别一上来就上DeepFM

新项目上线,我一般先用ItemCF(基于物品的协同过滤)跑一轮。虽然老派,但稳定、可解释性强,而且部署成本低。

比如一个视频平台,用户看完一个科技视频,系统就推荐“和这个视频最相似的5个”。实现起来也不复杂:

from sklearn.metrics.pairwise import cosine_similarity

# 假设item_user_matrix是物品-用户交互矩阵
similarity = cosine_similarity(item_user_matrix)

# 获取与物品i最相似的top_k物品
similar_items = similarity[i].argsort()[-top_k-1:-1][::-1]

这个模型上线快,资源消耗小,适合验证推荐逻辑是否成立。等跑通了再逐步升级到矩阵分解或双塔模型。

特征工程比模型结构更重要

有一次我们换了个更复杂的模型,AUC涨了0.02,但线上转化率反而跌了。后来发现是忽略了时间衰减——三天前的点击和三分钟前的点击权重一样,导致推荐一堆旧内容。

加入时间衰减后效果立竿见影:

import numpy as np

# 时间衰减函数
def time_decay(timestamp, base=3600*24):  # 按天衰减
    delta_t = current_time - timestamp
    return np.exp(-delta_t / base)

类似的还有地理位置、设备类型、用户活跃度等特征,往往比换个loss function更管用。

线上服务别忽视延迟和缓存

模型再准,接口响应超过300ms,用户早就划走了。我们有个新闻推荐接口,初期每次请求都实时计算TopN,QPS一高就卡。

后来改成预计算+缓存策略:每小时离线算好每个用户的推荐列表,存入Redis,接口直接查。虽然实时性差一点,但95%的请求都能在50ms内返回,用户体验反而更好。

AB测试才是最终裁判

别信离线指标。AUC高不代表用户爱点,CTR高也不代表能留住人。我们试过一个模型,点击率涨了15%,但次日留存降了3%。最后发现是因为推了一堆标题党内容。

现在我们上任何新策略,至少跑三天AB测试,核心看三个指标:点击率、人均阅读时长、回访率。只有这三个都稳住或提升,才算真正有效。

写在最后

推荐系统不是一锤子买卖,而是持续迭代的过程。用户口味会变,数据分布会漂移,昨天有效的策略今天可能就失效了。保持对数据的敏感,从小处改起,比追求“大招”更靠谱。