跳转至

冷启动问题

⚠️ 时效性说明:本章涉及前沿模型/价格/榜单等信息,可能随版本快速变化;请以论文原文、官方发布页和 API 文档为准。

冷启动问题

📖 章节导读

冷启动(Cold Start)是推荐系统中的经典难题,指新用户或新物品无法获得有效推荐的问题。本章将介绍冷启动问题的类型、解决方案和实际应用。

🎯 学习目标

  • 理解冷启动问题的类型和挑战
  • 掌握用户冷启动解决方案
  • 掌握物品冷启动解决方案
  • 了解混合策略
  • 能够设计冷启动解决方案

12.1 冷启动问题概述

12.1.1 问题类型

用户冷启动: - 新用户没有历史行为 - 无法建立用户画像 - 难以进行个性化推荐

物品冷启动: - 新物品没有用户交互 - 无法计算相似度 - 难以被推荐

12.1.2 挑战

数据稀疏: - 新用户/物品数据极少 - 传统算法无法有效工作

准确性要求: - 首次推荐体验很重要 - 错误推荐容易流失用户

时效性: - 需要快速建立画像 - 需要快速发现新物品

12.2 用户冷启动

12.2.1 注册时收集信息

收集策略: 1. 兴趣标签:让用户选择感兴趣的类别 2. ** demographic信息:年龄、性别、地域等 3. **社交账号:关联社交账号获取信息 4. 引导任务:完成简单任务获取偏好

实现示例:

Python
def collect_user_preferences(user_id):
    """
    收集用户偏好
    """
    preferences = {}

    # 兴趣标签
    interests = input("请选择您感兴趣的类别(用逗号分隔): ")
    preferences['interests'] = [i.strip() for i in interests.split(',')]

    # 年龄
    age = int(input("请输入您的年龄: "))
    preferences['age'] = age

    # 性别
    gender = input("请输入您的性别(M/F): ")
    preferences['gender'] = gender

    # 地域
    location = input("请输入您的城市: ")
    preferences['location'] = location

    return preferences

12.2.2 利用社交关系

社交信息利用: 1. 好友推荐:推荐好友喜欢的物品 2. 群体推荐:推荐用户所在群体流行的物品 3. 社交图谱:利用社交网络进行推荐

实现示例:

Python
def social_based_recommendation(user_id, social_graph, user_items):
    """
    基于社交关系的推荐
    """
    # 获取好友
    friends = social_graph.get(user_id, [])

    # 收集好友喜欢的物品
    friend_items = defaultdict(int)  # defaultdict访问不存在的键时返回默认值
    for friend_id in friends:
        for item_id in user_items.get(friend_id, []):
            friend_items[item_id] += 1

    # 排序
    sorted_items = sorted(friend_items.items(),
                        key=lambda x: x[1],  # lambda匿名函数
                        reverse=True)

    return [item_id for item_id, count in sorted_items[:10]]  # 切片操作,取前n个元素

12.2.3 热门推荐

热门物品推荐:

Python
def popular_based_recommendation(item_stats, n=10):
    """
    基于热门度的推荐
    """
    # 按热度排序
    sorted_items = sorted(item_stats.items(),
                        key=lambda x: x[1]['popularity'],
                        reverse=True)

    return [item_id for item_id, stats in sorted_items[:n]]

12.3 物品冷启动

12.3.1 基于内容的推荐

内容特征利用: 1. 文本特征:标题、描述、标签 2. 图像特征:视觉特征 3. 元数据:类别、价格、品牌

实现示例:

Python
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity

def content_based_recommendation(new_item, item_features, top_k=10):
    """
    基于内容的推荐
    """
    # 提取新物品特征
    new_item_features = extract_item_features(new_item)

    # 计算相似度
    similarities = []
    for item_id, features in item_features.items():
        sim = cosine_similarity(
            [new_item_features],
            [features]
        )[0][0]
        similarities.append((item_id, sim))

    # 排序
    similarities.sort(key=lambda x: x[1], reverse=True)

    return [item_id for item_id, sim in similarities[:top_k]]

12.3.2 探索与利用

探索策略: 1. ε-greedy:以概率ε探索新物品 2. UCB(Upper Confidence Bound):选择置信上界高的物品 3. Thompson Sampling:贝叶斯采样

实现示例:

Python
import numpy as np

class EpsilonGreedy:
    def __init__(self, n_items, epsilon=0.1):
        self.n_items = n_items
        self.epsilon = epsilon
        self.counts = np.zeros(n_items)
        self.values = np.zeros(n_items)

    def select_item(self):
        """
        选择物品
        """
        if np.random.random() < self.epsilon:
            # 探索:随机选择
            return np.random.randint(self.n_items)
        else:
            # 利用:选择最优
            return np.argmax(self.values)

    def update(self, item_id, reward):
        """
        更新
        """
        self.counts[item_id] += 1
        n = self.counts[item_id]
        value = self.values[item_id]

        # 更新平均值
        self.values[item_id] = (n - 1) / n * value + 1 / n * reward

class UCB:
    """UCB1 (Upper Confidence Bound) 算法"""

    def __init__(self, n_items):
        self.n_items = n_items
        self.counts = np.zeros(n_items)
        self.values = np.zeros(n_items)
        self.total_count = 0

    def select_item(self):
        """
        选择置信上界最大的物品
        UCB_i = X̄_i + √(2·ln(t) / N_i)
        """
        self.total_count += 1

        # 未被选择过的物品优先探索
        unexplored = np.where(self.counts == 0)[0]
        if len(unexplored) > 0:
            return np.random.choice(unexplored)

        # 计算UCB值
        ucb_values = self.values + np.sqrt(
            2 * np.log(self.total_count) / self.counts
        )
        return np.argmax(ucb_values)

    def update(self, item_id, reward):
        """更新"""
        self.counts[item_id] += 1
        n = self.counts[item_id]
        value = self.values[item_id]
        self.values[item_id] = (n - 1) / n * value + 1 / n * reward

class ThompsonSampling:
    """Thompson Sampling(Beta-Bernoulli模型)"""

    def __init__(self, n_items):
        self.n_items = n_items
        # Beta分布先验参数 α=1, β=1(均匀先验)
        self.alpha = np.ones(n_items)
        self.beta = np.ones(n_items)

    def select_item(self):
        """
        从每个物品的Beta后验分布中采样,选择采样值最大的物品
        """
        samples = np.random.beta(self.alpha, self.beta)
        return np.argmax(samples)

    def update(self, item_id, reward):
        """
        更新Beta分布后验参数
        reward: 0或1(点击/未点击)
        """
        if reward > 0:
            self.alpha[item_id] += 1  # 成功次数+1
        else:
            self.beta[item_id] += 1   # 失败次数+1

12.3.3 跨域推荐

跨域迁移:

Python
def cross_domain_recommendation(user_id, domain_models):
    """
    跨域推荐
    """
    recommendations = []

    # 从多个域获取推荐
    for domain, model in domain_models.items():
        domain_recs = model.recommend(user_id, n=5)
        recommendations.extend(domain_recs)

    # 去重和排序
    unique_recs = list(set(recommendations))

    return unique_recs[:10]

12.4 混合策略

12.4.1 多策略融合

融合方法:

Python
def hybrid_recommendation(user_id, strategies, weights):
    """
    混合推荐
    """
    all_scores = defaultdict(float)

    for strategy, weight in zip(strategies, weights):  # zip按位置配对
        items = strategy.recommend(user_id)
        for item_id, score in items:
            all_scores[item_id] += weight * score

    # 排序
    sorted_items = sorted(all_scores.items(),
                        key=lambda x: x[1],
                        reverse=True)

    return [item_id for item_id, score in sorted_items[:10]]

12.4.2 阶段性策略

分阶段推荐:

Python
def staged_recommendation(user_id, user_history, strategies):
    """
    阶段性推荐
    """
    # 新用户阶段
    if len(user_history) < 5:
        return strategies['popular'].recommend(user_id)

    # 成长阶段
    elif len(user_history) < 20:
        return strategies['content'].recommend(user_id)

    # 成熟阶段
    else:
        return strategies['collaborative'].recommend(user_id)

12.5 实战案例

案例:新用户推荐系统

Python
import numpy as np
from collections import defaultdict

class NewUserRecommender:
    def __init__(self, item_features, user_items, social_graph):
        self.item_features = item_features
        self.user_items = user_items
        self.social_graph = social_graph
        self.epsilon_greedy = EpsilonGreedy(n_items=10000, epsilon=0.1)

    def recommend(self, user_id, user_info=None, n=10):
        """
        为新用户推荐
        """
        # 策略1:基于用户信息
        if user_info:
            recs1 = self._demographic_based(user_info)
        else:
            recs1 = []

        # 策略2:基于社交关系
        recs2 = self._social_based(user_id)

        # 策略3:热门推荐
        recs3 = self._popular_based()

        # 策略4:探索新物品
        recs4 = self._exploration_based()

        # 融合策略
        all_recs = recs1 + recs2 + recs3 + recs4

        # 去重
        unique_recs = list(set(all_recs))

        return unique_recs[:n]

    def _demographic_based(self, user_info):
        """基于人口统计学的推荐"""
        # 根据年龄、性别、地域推荐
        age_group = self._get_age_group(user_info['age'])
        gender = user_info['gender']
        location = user_info['location']

        # 简化:返回该年龄段的热门物品
        return self._get_popular_items(age_group, n=3)

    def _social_based(self, user_id):
        """基于社交关系的推荐"""
        friends = self.social_graph.get(user_id, [])
        friend_items = defaultdict(int)

        for friend_id in friends:
            for item_id in self.user_items.get(friend_id, []):
                friend_items[item_id] += 1

        sorted_items = sorted(friend_items.items(),
                           key=lambda x: x[1],
                           reverse=True)

        return [item_id for item_id, count in sorted_items[:3]]

    def _popular_based(self):
        """热门推荐"""
        # 返回全局热门物品
        return self._get_popular_items('all', n=3)

    def _exploration_based(self):
        """探索性推荐"""
        # 使用ε-greedy选择物品
        item_id = self.epsilon_greedy.select_item()
        return [item_id]

    def _get_age_group(self, age):
        """获取年龄组"""
        if age < 25:
            return '18-24'
        elif age < 35:
            return '25-34'
        elif age < 45:
            return '35-44'
        else:
            return '45+'

    def _get_popular_items(self, group, n=3):
        """获取热门物品(简化)"""
        # 实际应该从数据库查询
        return list(range(n))

# 使用示例
recommender = NewUserRecommender(
    item_features={},
    user_items={},
    social_graph={}
)

# 新用户1:有用户信息
user_info_1 = {
    'age': 25,
    'gender': 'M',
    'location': '北京'
}
recs1 = recommender.recommend(user_id=1001, user_info=user_info_1)
print(f"为用户1001推荐: {recs1}")

# 新用户2:无用户信息
recs2 = recommender.recommend(user_id=1002, user_info=None)
print(f"为用户1002推荐: {recs2}")

📝 本章小结

本章介绍了冷启动问题:

  1. ✅ 冷启动问题的类型和挑战
  2. ✅ 用户冷启动解决方案
  3. ✅ 物品冷启动解决方案
  4. ✅ 混合策略
  5. ✅ 实战案例

通过本章学习,你应该能够: - 理解冷启动问题的挑战 - 设计用户冷启动解决方案 - 设计物品冷启动解决方案 - 设计混合推荐策略 - 构建冷启动推荐系统

🔗 下一步

下一章我们将学习推荐系统评估,了解如何评估推荐系统的效果。

继续学习: 13-推荐系统评估.md

💡 思考题

  1. 用户冷启动和物品冷启动各有什么挑战?

    用户冷启动:无行为历史无法建模兴趣,只能依赖属性/热门/引导。挑战:0行为→几次行为的快速转化、第一印象影响留存。物品冷启动:新物品无交互数据,排序模型无法计算CTR。挑战:新品曝光机会与老品竞争、快速反馈质量信号。

  2. 如何设计有效的冷启动解决方案?

    用户冷启动:①注册引导选兴趣标签 ②人口统计+热门推荐 ③Look-alike(相似用户迁移) ④Bandit探索(UCB/Thompson采样)。物品冷启动:①内容特征召回(标题/标签/图像相似匹配) ②运营流量注入 ③Meta-Learning(少量布消快速学到Embedding) ④初始CTR估计(用同类目均值)。

  3. 探索与利用如何平衡?

    探索(Exploration):尝试新内容获取信息。利用(Exploitation):推荐已知高质量内容。方法:①ε-greedy(简单,少量随机) ②UCB(上置信赖区间,给不确定性高的加分) ③Thompson Sampling(贝叶斯采样,理论最优) ④LinUCB(上下文Bandit,考虑特征) ⑤流量配额(新品保底曝光量)。

  4. 跨域推荐如何实现?

    目标:利用A域行为提升B域推荐(如视频→电商)。方法:①共享用户Embedding(抛给两个域共训练) ②知识迁移(A域预训练→B域微调) ③特征映射(A域特征→统一空间→B域特征) ④联邦学习+隐私保护(不共享原始数据)。挑战:域间用户重叠率、转化模式差异、隐私合规。

  5. 如何评估冷启动解决方案的效果?

    指标:①新用户留存率(核心) ②新用户首日行为数(探索效率) ③新物品曝光→点击转化率 ④冷启动用户/物品的AUC(单独测) ⑤探索成本(Regret)。评估方法:分组A/B测试(新用户分流)+离线仿真(replay方法模拟Bandit策略效果)。

📚 参考资料

  1. "Cold-Start Recommendations" - Schein et al.
  2. "Addressing Cold-Start in Recommender Systems" - Lika et al.
  3. "Exploration and Exploitation in Recommender Systems" - Rendle
  4. "Cross-Domain Recommendation" - Cremonesi et al.
  5. Bandit Algorithms for Recommender Systems