You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言交叉验证及CV绘图失败,Lasso模型预测出错求助

汽车价格预测模型问题排查与解决方案

一、交叉验证CV Errors全为NaN问题

原因分析

  1. 循环内判断条件sum(best.fit$which[i, ]) > 0逻辑错误:best.fit$which的行对应不同变量数的模型,列对应变量,该条件无法正确判断模型是否有效,导致大量循环未执行,cv.errors矩阵始终为NA。
  2. 数据集存在NA值:scaled_train_df中的缺失值会导致模型拟合或预测失败,生成NaN。
  3. 哑变量不匹配:训练集和验证集的分类变量水平不一致,导致predict.regsubsets函数生成的预测值为NA。

解决方案

  1. 修正循环判断逻辑
    替换错误的判断条件,直接检查对应变量数的模型是否有系数:

    k <- 10
    set.seed(42)
    folds <- sample(1:k, nrow(scaled_train_df), replace = TRUE)
    cv.errors <- matrix(NA, k, 10, dimnames = list(NULL, paste(1:10)))
    
    for (j in 1:k) {
      best.fit <- regsubsets(Pris ~ ., data = scaled_train_df[folds != j, ], nvmax = 10)
      for (i in 1:10) {
        # 检查对应变量数的模型是否存在有效系数
        coef_i <- coef(best.fit, id = i)
        if (!is.null(coef_i)) {
          pred <- predict(best.fit, scaled_train_df[folds == j, ], id = i)
          actual <- scaled_train_df$Pris[folds == j]
          cv.errors[j, i] <- mean((actual - pred)^2, na.rm = TRUE)
        }
      }
    }
    
  2. 清理数据集缺失值
    移除或填充NA值,确保模型拟合正常:

    # 方式1:直接移除含NA的行
    scaled_train_df <- na.omit(scaled_train_df)
    # 方式2:按变量类型填充NA(数值变量用均值,分类变量用众数)
    scaled_train_df$Miltal[is.na(scaled_train_df$Miltal)] <- mean(scaled_train_df$Miltal, na.rm = TRUE)
    scaled_train_df$Bränsle[is.na(scaled_train_df$Bränsle)] <- names(which.max(table(scaled_train_df$Bränsle)))
    
  3. 同步分类变量水平
    确保验证集的分类变量水平与训练集一致:

    # 同步所有分类变量的水平
    for(col in c("Bränsle", "Växellåda", "Biltyp", "Drivning")){
      scaled_train_df[[col]] <- as.factor(scaled_train_df[[col]])
      # 若验证集是scaled_train_df的子集可跳过,否则需同步外部测试集
      # scaled_test_df[[col]] <- factor(scaled_test_df[[col]], levels = levels(scaled_train_df[[col]]))
    }
    

二、Lasso模型预测变量数不匹配问题

原因分析

  1. 训练集与测试集的变量数不一致:训练Lasso时的x矩阵和测试集x_test的变量数不同,通常是因为分类变量生成的哑变量数量不一致(比如训练集某分类变量有3个水平,测试集只有2个)。
  2. model.matrix生成的矩阵未对齐:训练和测试的特征矩阵没有统一变量列,导致维度不匹配。

解决方案

  1. 统一特征矩阵生成方式
    基于训练集的变量列生成测试集的特征矩阵,确保维度一致:

    # 生成训练集特征矩阵(去掉截距列)
    x_train <- model.matrix(Pris ~ ., data = scaled_train_df)[, -1]
    y_train <- scaled_train_df$Pris
    
    # 同步测试集分类变量水平
    for(col in c("Bränsle", "Växellåda", "Biltyp", "Drivning")){
      scaled_test_df[[col]] <- factor(scaled_test_df[[col]], levels = levels(scaled_train_df[[col]]))
    }
    
    # 生成测试集特征矩阵,仅保留训练集存在的变量
    x_test <- model.matrix(Pris ~ ., data = scaled_test_df)[, colnames(x_train)]
    
    # 重新训练Lasso并预测
    grid <- 10^seq(10, -2, length = 100)
    lasso.mod <- glmnet(x_train, y_train, alpha = 1, lambda = grid)
    set.seed(42)
    cv.out <- cv.glmnet(x_train, y_train, alpha = 1)
    bestlam <- cv.out$lambda.min
    
    lasso.pred <- predict(lasso.mod, newx = x_test, s = bestlam)
    
  2. 解决绘图警告
    collapsing to unique 'x' values是因为lambda值重复,生成唯一的lambda序列即可:

    grid <- unique(10^seq(10, -2, length = 100)) # 去重lambda值
    lasso.mod <- glmnet(x_train, y_train, alpha = 1, lambda = grid)
    plot(lasso.mod)
    
  3. 修复均方误差计算
    确保预测值生成后再执行逆缩放:

    # 逆缩放计算真实均方误差
    pred <- lasso.pred * pris_scale_factor + pris_scale
    actual <- scaled_test_df$Pris * pris_scale_factor + pris_scale
    mean_error <- mean((actual - pred)^2)
    print(mean_error)
    

内容的提问来源于stack exchange,提问作者l_b

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 09:03:13