多维行为数据有效整合到ALS推荐系统中

在实际场景中,用户与评分对象的交互行为远不止单一的评分(rating),还包括例如点击、加购、购买、停留时长等多种行为。

而ALS算法通常只提供三个参数,user, item, rate。

通常有两种解决办法,一种是将多个行为通过权重的方式整合成一个rate;另一种是为每个item都构建一个ALS算法。

一、加权求和

1. 行为类型及权重分配

行为类型权重示例行为特点
浏览/点击1-3分频次高,偏好信号弱
商品详情停留2-5分时长越长权重越高
加入购物车5-8分强购买意向信号
收藏商品7-9分长期兴趣信号
购买行为10分最强烈正向信号
退货行为-5分负向信号
差评行为-3分负向信号

2. 行为权重动态计算

public class BehaviorWeightCalculator {
    public static double calculateWeight(String behaviorType, Map<String, Object> context) {
        double baseWeight = 0;
        
        // 基础权重
        switch (behaviorType) {
            case "view":
                baseWeight = 1.0;
                break;
            case "detail_view":
                // 停留时间越长权重越高(30秒为基准)
                long duration = (long) context.getOrDefault("duration", 0L);
                baseWeight = 2.0 + Math.min(duration / 30000.0, 3.0);
                break;
            case "add_to_cart":
                baseWeight = 5.0;
                break;
            // 其他行为...
        }
        
        // 时间衰减(半衰期7天)
        long daysPassed = (long) context.getOrDefault("daysPassed", 0L);
        double decay = Math.pow(0.5, daysPassed / 7.0);
        
        // 用户活跃度加权(活跃用户行为权重降低)
        double activityLevel = (double) context.getOrDefault("activityLevel", 1.0);
        double activityFactor = 1.0 / Math.log(1.0 + activityLevel);
        
        return baseWeight * decay * activityFactor;
    }
}

3. 综合评分计算

// 将用户对同一商品的不同行为合并为综合评分
public JavaRDD<Rating> aggregateBehaviors(JavaRDD<UserBehavior> behaviors) {
    return behaviors
        // 按(userId, itemId)分组
        .groupBy(ub -> Tuple2.apply(ub.getUserId(), ub.getItemId()))
        
        // 计算加权综合评分
        .map(tuple -> {
            int userId = tuple._1();
            int itemId = tuple._2();
            double totalScore = 0;
            
            for (UserBehavior ub : tuple._2()) {
                Map<String, Object> context = new HashMap<>();
                context.put("duration", ub.getDuration());
                context.put("daysPassed", ub.getDaysPassed());
                
                totalScore += BehaviorWeightCalculator.calculateWeight(
                    ub.getBehaviorType(), context);
            }
            
            // 应用sigmoid函数压缩到(0,1)区间
            double finalRating = 1 / (1 + Math.exp(-totalScore));
            
            return new Rating(userId, itemId, (float) finalRating);
        });
}

二、多行为矩阵分解

// 为每种行为类型创建单独的评分矩阵
public List<ALSModel> trainMultiBehaviorALS(List<JavaRDD<Rating>> behaviorRatings) {
    List<ALSModel> models = new ArrayList<>();
    
    for (JavaRDD<Rating> ratings : behaviorRatings) {
        ALS als = new ALS()
            .setRank(10)
            .setMaxIter(10)
            .setRegParam(0.1);
        
        models.add(als.fit(ratings));
    }
    
    return models;
}

// 合并多个行为模型的预测结果
public JavaRDD<Rating> blendPredictions(List<ALSModel> models, double[] weights) {
    // 实现模型预测结果加权融合
    // ...
}

三、Spark ALS实现多行为推荐

1. 多行为数据加载

public Dataset<Row> loadMultiBehaviorData(SparkSession spark, String path) {
    Dataset<Row> df = spark.read()
        .option("header", "true")
        .csv(path);
    
    // 解析多种行为类型
    df = df.selectExpr(
        "cast(userId as int) as userId",
        "cast(itemId as int) as itemId",
        "cast(view_count as int) as views",
        "cast(add_to_cart as int) as carts",
        "cast(purchase as int) as purchases",
        "cast(dwell_time as double) as dwellTime",
        "cast(timestamp as long) as timestamp"
    );
    
    return df;
}

2. 行为数据转换

public Dataset<Row> transformBehaviors(Dataset<Row> behaviorData) {
    // 定义UDF计算综合评分
    spark.udf().register("calculate_rating", 
        (Integer views, Integer carts, Integer purchases, Double dwellTime) -> {
            double score = views * 0.2 + 
                         carts * 1.0 + 
                         purchases * 3.0 + 
                         Math.log1p(dwellTime) * 0.5;
            return (float) (1 / (1 + Math.exp(-score)));
        }, DataTypes.FloatType);
    
    // 应用转换
    return behaviorData.selectExpr(
        "userId",
        "itemId",
        "calculate_rating(views, carts, purchases, dwellTime) as rating",
        "timestamp"
    );
}

3. 时间加权ALS实现

public ALSModel trainTimeWeightedALS(Dataset<Row> ratings) {
    // 计算时间衰减权重
    Dataset<Row> withWeights = ratings.withColumn("timeWeight", 
        functions.exp(functions.lit(-0.1).multiply(
            functions.datediff(
                functions.current_date(), 
                functions.to_date(functions.from_unixtime(functions.col("timestamp")))
        ));
    
    // 创建自定义ALS模型(扩展原生ALS支持样本权重)
    TimeWeightedALS als = new TimeWeightedALS()
        .setRank(10)
        .setMaxIter(15)
        .setRegParam(0.1)
        .setUserCol("userId")
        .setItemCol("itemId")
        .setRatingCol("rating")
        .setWeightCol("timeWeight")  // 使用时间衰减权重
        .setColdStartStrategy("drop");
    
    return als.fit(withWeights);
}

四、多行为推荐系统架构

1. 离线训练流程

Raw-Behavior-Logs
Spark-ETL
Behavior-Aggregation
Feature-Join
User-Features
ALS-Training
Model-Storage

2. 在线服务流程

API-Request
Real-time-Feature-Lookup
Score-Blending
ALS-Model
Business-Rules
Response
Content-Based-Model

五、多行为推荐优化技巧

1. 行为分层处理

// 对不同行为类型分层处理
public Map<String, Dataset<Row>> stratifyBehaviors(Dataset<Row> behaviors) {
    Map<String, Dataset<Row>> stratified = new HashMap<>();
    
    // 浏览行为(轻量级交互)
    stratified.put("view", behaviors.filter("views > 0"));
    
    // 转化行为(强购买意向)
    stratified.put("conversion", behaviors.filter("carts > 0 OR purchases > 0"));
    
    // 负反馈行为
    stratified.put("negative", behaviors.filter("returns > 0 OR negative_reviews > 0"));
    
    return stratified;
}

2. 注意力机制加权

// 使用注意力机制动态调整行为权重
public Dataset<Row> applyAttentionWeights(Dataset<Row> behaviors) {
    // 加载预训练的注意力模型
    AttentionModel attentionModel = AttentionModel.load("models/attention");
    
    // 应用注意力权重
    return attentionModel.transform(behaviors)
        .withColumn("finalRating", 
            col("attentionWeight").multiply(col("baseRating")));
}

3. 多目标优化

// 同时优化点击率和转化率
public MultiObjectiveALS trainMultiObjective(List<Dataset<Row>> behaviorData) {
    MultiObjectiveALS als = new MultiObjectiveALS()
        .setRanks(10, 10)
        .setMaxIter(10)
        .setObjectives("ctr", "cvr");
    
    return als.fit(behaviorData);
}

六、生产环境注意事项

  1. 行为数据时效性

    • 实时行为数据(最近1小时)使用流处理
    • 短期行为(7天)使用增量更新
    • 长期行为使用全量更新
  2. 异常行为处理

    // 过滤机器人行为
    df = df.filter("not (userId in (select userId from bot_users))");
    
    // 平滑极端值
    df = df.withColumn("dwellTime", 
        when(col("dwellTime") > 3600, 3600).otherwise(col("dwellTime")));
    
  3. 动态权重调整

    // 根据业务阶段调整行为权重
    double purchaseWeight = getCurrentPurchaseWeight(); // 大促期间提高购买权重
    
  4. A/B测试框架

    // 不同行为权重策略的A/B测试
    if (userBucket == "A") {
        // 策略A:重视加购行为
        weights = new double[]{0.2, 1.0, 0.8}; 
    } else {
        // 策略B:重视浏览深度
        weights = new double[]{0.5, 0.7, 0.3};
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值