基于用户特征构建推荐系统:Python实现方案求助
我有一个用户数据库,每行对应一位用户,包含两类列:用户特征列和0-6分的流派评分列,示例如下:
| 用户 | 年龄 | 性别 | ... | 流派1 | 流派2 | ... |
|---|---|---|---|---|---|---|
| 1 | 18 | M | 4 | 5 | ||
| 2 | 75 | F | 3 | 2 | ||
| 3 | 45 | M | 0 | 1 |
已知特征F₁,F₂,...,Fₘ和流派评分G₁, G₂,..., G_d(每个Gᵢ ∈ {0,1,...,5}),核心需求是构建函数F(F₁,F₂,...,Fₘ) = (G₁,G₂,...,G_d),即通过用户特征预估流派评分,再按评分高低排序推荐流派。比如输入35岁男性用户,得到F(35, male) = (1,3,2),就优先推荐动作类。数据无缺失值。
尝试过多元多项回归但在Python中无法实现,希望得到解决思路及Python可实现的算法建议;了解过协同过滤,但它侧重用户交互而非用户特征,认为当前问题更简单。
你的问题本质是多输出回归任务(每个流派评分是一个回归目标,目标值是离散的0-5分,也可看作有序分类),核心是用用户特征同时预测多个目标变量。下面是具体的思路和可落地的Python方案:
一、基础思路拆分
把多输出任务拆分为多个单输出任务处理,这是最简单易实现的方案:
- 对每个流派评分
Gᵢ,单独训练一个回归模型(或有序分类模型),输入都是用户特征F₁...Fₘ - 预测时,用每个模型分别输出对应流派的评分,再整合排序
二、Python可实现的算法推荐
1. 多输出线性回归(拆分式)
直接用scikit-learn的线性回归模型,为每个流派单独训练:
from sklearn.linear_model import LinearRegression import numpy as np # 假设X是用户特征矩阵(n_samples, m_features),y是流派评分矩阵(n_samples, d_genres) X = ... y = ... # 存储每个流派的模型 models = [] for genre_idx in range(y.shape[1]): model = LinearRegression() model.fit(X, y[:, genre_idx]) models.append(model) # 预测示例 test_user = np.array([[35, 1]]) # 假设性别已编码为1=男,0=女 pred_scores = [model.predict(test_user)[0] for model in models] # 按评分降序排序流派索引 recommended_genres = sorted(range(len(pred_scores)), key=lambda x: pred_scores[x], reverse=True)
如果把评分看作有序分类,也可以用OrdinalRegression(需安装mord库),更贴合离散评分的特性:
from mord import LogisticIT models = [] for genre_idx in range(y.shape[1]): model = LogisticIT() model.fit(X, y[:, genre_idx]) models.append(model)
2. 多输出集成模型
用scikit-learn的MultiOutputRegressor包装任意单输出回归器,统一处理多输出任务:
from sklearn.multioutput import MultiOutputRegressor from sklearn.ensemble import RandomForestRegressor # 用随机森林作为基础模型,自动处理多输出 multi_model = MultiOutputRegressor(RandomForestRegressor(n_estimators=100)) multi_model.fit(X, y) # 预测 pred_scores = multi_model.predict(test_user)[0] recommended_genres = sorted(range(len(pred_scores)), key=lambda x: pred_scores[x], reverse=True)
集成模型(随机森林、梯度提升树等)能自动捕捉特征间的非线性关系,效果通常比线性回归好,适合用户特征和流派评分有复杂关联的场景。
3. 神经网络(简单全连接)
如果特征维度高或想捕捉更复杂的模式,可以用简单的全连接神经网络,用Keras实现:
from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense # 构建多输出神经网络 model = Sequential([ Dense(64, activation='relu', input_shape=(X.shape[1],)), Dense(32, activation='relu'), Dense(y.shape[1], activation='linear') # 输出层对应每个流派的评分 ]) model.compile(optimizer='adam', loss='mse') model.fit(X, y, epochs=50, batch_size=32) # 预测 pred_scores = model.predict(test_user)[0]
这种方式适合数据量较大的情况,能自动学习特征组合。
三、关于多元多项回归的替代方案
你提到的多元多项回归(multivariate multinomial regression)主要用于多分类的多输出任务,但你的目标是离散评分(更接近有序回归或回归),所以上述方案更贴合需求。如果一定要用类似思路,可以考虑用多分类模型处理每个流派的评分(把0-5看作6个类别),再用MultiOutputClassifier包装,但效果可能不如回归类模型直接。
内容的提问来源于stack exchange,提问作者Jesús A. Piñera

