共计 2729 个字符,预计需要花费 7 分钟才能阅读完成。
为什么服装推荐是个技术难题?
推荐系统在电商领域已经非常成熟,但服装品类却始终是个特殊的存在。这主要源于以下几个特性:

- 多模态特征:一件衣服同时包含颜色、材质、款式、季节等多个维度的信息
- 主观偏好强:用户对 ” 好看 ” 的判断标准差异巨大
- 场景依赖性:同一件衣服在通勤、约会等不同场合的适配度完全不同
- 季节性波动:羽绒服在夏天推荐得再精准也没人买
传统协同过滤(Collaborative Filtering)在这里会遭遇两个致命伤:
- 冷启动问题:新商品或新用户没有历史交互数据
- 特征利用不足:无法有效结合服装本身的属性特征
为什么选择 CART 决策树?
在对比了几种主流方案后,CART 决策树 (Classification and Regression Tree) 展现出独特优势:
- 特征重要性:自动评估颜色、材质等特征的影响权重
- 可解释性:决策路径清晰可见,便于产品经理理解
- 处理混合类型数据:同时支持数值型和类别型特征
- 计算效率高:线上推理速度极快
与矩阵分解 (Matrix Factorization) 相比,决策树更适合处理服装这类富含结构化特征的场景。下面是简单的对比实验数据:
| 指标 | 协同过滤 | 矩阵分解 | CART 决策树 |
|---|---|---|---|
| 新商品覆盖率 | 12% | 18% | 63% |
| 推荐多样性 | 0.32 | 0.41 | 0.58 |
| 响应时间(ms) | 120 | 85 | 23 |
核心实现四步走
第一步:特征工程实战
服装特征可以划分为三大类,需要分别处理:
- 基础属性(类别型):
- 颜色:映射到 HSV 色彩空间的色调值
- 材质:使用 LabelEncoder 编码
-
风格:” 商务 ”、” 休闲 ” 等标签转为 one-hot
-
视觉特征(数值型):
- 通过 CNN 提取的 4096 维特征向量
-
使用 PCA 降维到 50 维
-
上下文特征:
- 季节:sin/cosin 编码处理周期性
- 价格:对数变换后标准化
关键代码示例:
from sklearn.preprocessing import OneHotEncoder, LabelEncoder
# 材质编码示例
material_encoder = LabelEncoder()
df['material_encoded'] = material_encoder.fit_transform(df['material'])
# 风格 one-hot
style_encoder = OneHotEncoder()
style_features = style_encoder.fit_transform(df[['style']]).toarray()
第二步:模型构建
使用 scikit-learn 的 DecisionTreeClassifier:
- 关键参数说明:
- max_depth:控制树深度,防止过拟合
- min_samples_split:节点继续分裂的最小样本数
- class_weight:处理用户行为数据的天然不平衡
完整训练代码:
from sklearn.tree import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
# 划分数据集
X_train, X_test, y_train, y_test = train_test_split(features, labels, test_size=0.2, random_state=42)
# 初始化模型
tree = DecisionTreeClassifier(
max_depth=8,
min_samples_split=50,
class_weight='balanced'
)
# 训练与评估
tree.fit(X_train, y_train)
print("Test accuracy:", tree.score(X_test, y_test))
第三步:推荐逻辑实现
决策树推荐不同于传统的排序算法,需要:
- 遍历决策路径找到匹配的叶子节点
- 提取该节点下的所有商品
- 按 feature importance 加权排序
def recommend(user_features, top_k=5):
leaf_id = tree.apply(user_features.reshape(1,-1))[0]
candidate_items = leaf_to_items[leaf_id]
# 计算匹配分
scores = []
for item in candidate_items:
score = np.dot(item_features, user_features)
scores.append(score)
return candidate_items[np.argsort(scores)[-top_k:]]
性能优化实战技巧
经过上百次 AB 测试,我们总结出这些经验:
- 树深度:服装推荐最优深度在 6 - 8 层
- 剪枝策略:CCP(Cost Complexity Pruning)效果优于预剪枝
- 特征组合:人工构造 ” 颜色_材质 ” 等交叉特征可提升效果
- 样本权重:对点击未购买样本降权处理
调参示例:
from sklearn.tree import DecisionTreeClassifier
params = {'max_depth': [6, 7, 8],
'ccp_alpha': [0.0, 0.01, 0.1]
}
grid_search = GridSearchCV(DecisionTreeClassifier(),
param_grid=params,
cv=5
)
grid_search.fit(X_train, y_train)
五个必知的避坑指南
- 特征泄露:绝对不能把价格折扣信息作为特征
- 类别不平衡:oversampling 小众风格样本
- 冷启动缓解:
- 新用户:用人口统计特征初始化
- 新商品:用视觉特征相似度填充
- 季节漂移:按月更新模型
- 解释性陷阱:颜色重要性高不代表应该只推同色系
进阶方向:从单棵树到森林
当推荐效果遇到瓶颈时,可以考虑:
- GBDT:通过梯度提升组合多棵弱分类器
- 随机森林:增加推荐多样性
- 混合模型:决策树处理结构化特征 + 神经网络处理图像特征
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(
n_estimators=100,
max_features='sqrt',
oob_score=True
)
rf.fit(X_train, y_train)
实践建议
建议使用 Amazon Fashion 数据集(约 50 万条服装数据)进行验证:
- 从 Kaggle 下载原始数据
- 用 OpenCV 提取图像特征
- 按照 7:2:1 划分训练 / 验证 / 测试集
- 重点监控长尾商品的推荐覆盖率
决策树就像时尚顾问的大脑,通过一系列精心设计的问题(特征判断),最终找到最适合你的那件衣服。这种白盒模型在电商场景中的优势会越来越明显,特别是在《个人信息保护法》实施后,可解释性强的算法将更受青睐。
正文完
