免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

回归当分类做,loss降到0.01但R²为负:补完机器学习基础我才止血

回归当分类做,loss降到0.01但R²为负:补完机器学习基础我才止血 回归当分类做,loss降到0.01但R2为负:补完机器学习基础我才止血上个月周二下午,业务方丢来一个二手房估价需求--数据列全是朝向、面积、楼层,目标价是连续数值。我扫了一眼价格分布,脑子一抽把价格分成了“低、中、高”三档,直接套了一版多分类模型。训练时 loss 从 3.2 一路降到 0.08,曲线漂亮得让我信心爆棚。结果灰度上线当天,销售反馈“均价偏差超 40%”,领导盯着监控上R2 -0.67问我:“你不是说模型已经完美了吗?”直到我在亚马逊云科技上找到一套人工智能课程,重新把里面的机器学习基础走了一遍,才彻底搞明白自己连任务类型都没分清--课程用一整个模块拆解了回归与分类的判别边界,看完我才发现自己从第一步就踏进了坑。1. 为什么我会把回归当成分类做这个项目的原始数据里,目标价格分布在 80 万到 1200 万之间,跨度极大。我当时的思路是:价格区间太长,直接预测数值很难,不如先大概分个“低价/中价/高价”,再用分类模型预测档次。于是手动划分了三个区间,生成离散标签,然后喜提一个多分类任务。那会儿我甚至没意识到,这么粗暴的离散化直接抹掉了价格连续变化的梯度信息。比如实际卖 850 万和卖 860 万的两套房,在分类眼里变成同一个“中价”标签,模型根本学不到细微差异。学完人工智能课程的“问题定义与数据理解”章节,我才发现这属于典型的回归问题误判--课程中用了房价预测、销量预估等真实例子对比回归和分类的特征,看完像是被敲了一棒。另一个被忽略的地方是数据预处理:原始数据有 23% 的缺失值,我没做归一化也没处理异常值,直接把缺失的数值填成 -1,把带文本的朝向字段做了一刀切的 one-hot 编码。直到补了机器学习基础里的预处理流水线讲解,我才明白 -1 这种假值会严重干扰梯度下降的方向。2. 训练 loss 狂降,上线翻车:损失函数的错误选择用分类型思路训练时,我选的损失函数是交叉熵(CrossEntropyLoss),下面就是当时那段“罪魁祸首”代码:import torch import torch.nn as nn # 错误代码:把连续房价离散为三类后用交叉熵 criterion nn.CrossEntropyLoss() # 模型输出 shape: (batch, 3),目标标签是0/1/2 outputs model(inputs) loss criterion(outputs, labels) # 训练loss从3.2降到0.08训练 loss 的下降曲线确实好看,但模型学到的其实是“如何把特征映射到三个离散类别”,而不是“输出一个接近真实价格的连续值”。更致命的是,交叉熵在回归场景下毫无意义:它只看预测类别是否与标签类别一致,完全不管 850 万与 860 万之间的偏差。学完人工智能课程里专门拆解损失函数的那节课,我才理解了 MSE、MAE 和交叉熵各自的适用场景,课程还把每种损失函数的梯度形式画了出来,比单纯看博客有实感得多。3. 排查路上的弯路:用分类指标衡量回归上线翻车后,我第一时间不是反思任务类型,而是去看评估指标。可当时脑子里只有准确率、精确率这些分类指标,于是我对着真实类别标签算了一版混淆矩阵:from sklearn.metrics import confusion_matrix # 真实标签与预测标签都是0/1/2 cm confusion_matrix(y_true, y_pred) print(cm) # 对角线数值很高,看着挺美混淆矩阵显示“高价”类的召回率有 91%,“低中高”三个类平均准确率接近 89%。我拿着这份数据去找业务方解释,结果对方反问:“你能告诉我这套房子预测价和签约价差了多少万吗?”那一刻我直接愣住--混淆矩阵在这种连续价格预测场景下完全给不出有意义的业务答案。后来补机器学习基础时才系统学到:回归任务该看的是均方误差(MSE)、平均绝对误差(MAE)和决定系数(R2)。课程里还演示了这些指标在不同误差分布下的表现差异,比如存在离群点时 MAE 比 MSE 更鲁棒,这些内容让我在后续重构时少走了很多弯路。4. 补课机器学习基础后,重构整个建模流程在人工智能课程的“机器学习管道”章节里,我第一次画出完整的端到端流程:数据预处理 → 特征工程 → 模型选择 → 训练验证 → 评估上线。按这个思路,我把项目从头推倒重来:不再对价格做离散化,直接保留连续目标值;用数据预处理中的缺失值处理策略,对数值型特征采用分位数填充,对类别型特征用众数填充;进行归一化处理,消除面积和楼层这类不同量纲特征的影响;改用 MSELoss 作为损失函数:import torch.nn as nn # 正确的回归损失函数 criterion nn.MSELoss() outputs model(inputs) # 输出维度改为(batch, 1) loss criterion(outputs.squeeze(), targets) # 回归损失训练时加了验证集监控,防止过拟合--虽然改用 MSE 后 loss 下降变慢,但验证集上的 R2 从原来的负值一点点涨到了 0.31。随后我又借助超参调优的思路,用 Grid Search 调整了学习率和优化器:from sklearn.model_selection import GridSearchCV # 对学习率和L2正则化系数做网格搜索 param_grid {learning_rate: [1e-4, 1e-3, 1e-2], weight_decay: [1e-5, 1e-4]} # 最终选定lr1e-3, weight_decay1e-5 的组合这一轮调参让 R2 从 0.31 爬到了 0.68。人工智能课程里的超参调优实操演示,让我第一次体会到“调参不是玄学,而是有据可依的实验设计”。5. 模型重生:用正确指标驱动的迭代切换到回归视角后,整个优化方向清晰起来。我重新审视了特征工程:把朝向、装修程度这类高基数类别特征,从 one-hot 改成目标编码(Target Encoding),并加入了“距最近地铁站距离”和“同小区近三个月成交均价”两个外部衍生特征。机器学习管道的概念让我养成了每次改动都记录实验的习惯,训练脚本里也会自动给输出文件夹带上时间戳和版本号。最终模型在测试集上达到: - MAE:38.7 万元(对比业务方可接受的 50 万阈值显著有盈余) - R2:0.82(从最初的 -0.67 彻底翻盘) - 最大单样本偏差:从最初动辄偏差 200 万以上,收敛到单套最差情况下偏差不超过 120 万这期间AWS 基础知识提到的实验跟踪与模型版本管理思路也起了作用--我在 S3 上组织每次实验的输出,省去本地一堆散装 pickle 文件。回头看,如果一开始就完整学完这套人工智能课程,根本不用在错误的方向上浪费三周。6. 给类似处境人的 6 条避坑清单接到预测需求先判回归还是分类:如果目标变量是连续值(价格、温度、销量),不要试图人工分桶。人工智能课程里有专门一节“如何识别业务问题的机器学习类型”,值得点进去核对你的场景。损失函数必须和任务类型对齐:回归首选 MSE 或 MAE,分类才用交叉熵。机器学习基础里的损失函数对比表格,直接标明了每种函数的输出约束和适用场景。评估指标不能混用:别在回归任务上算准确率和混淆矩阵,那样只会给自己制造虚假信心。课程里演示了 R2、MAE、RMSE 的计算与解读,看完就知道业务方更关心偏差绝对值而不是“分类正确率”。数据预处理决定模型上限:缺失值处理、归一化、类别编码,这三步做完之前别急着建模。补了机器学习入门里的预处理 Demo,我才发现自己之前用 -1 填缺失值有多荒唐。超参调优是加速收敛的杠杆:别用默认参数硬扛,用网格或随机搜索扫一下学习率和正则化系数,很多时候 R2 能提升 10% 以上。我在超参调优模块里学的实验设计思路,把原本三天的玄学调参压缩成了半天。完整走通一条机器学习管道:从数据到部署,用机器学习管道的思维管理实验,避免东一个脚本西一个 notebook。AWS 深度学习的后续课程也提供了 Pipeline 的自动化模板,可以作为进阶方向。这次翻车让我彻底明白,模型效果差不一定是数据不够或结构不对,很大概率是基础没打牢。如果你也曾在训练 loss 下降时沾沾自喜,却在评估指标上栽跟头,真的建议把人工智能课程里的机器学习基础部分系统过一遍--它不是入门鸡汤,而是帮你把任务定义、损失函数、评估指标、调参流程这些硬骨头一块块啃下来的实战课。
返回列表