逻辑回归用于连续值预测:Matlab实现有界输出回归模型
2026/9/6 14:51:48 网站建设 项目流程

简介:本资源是一套面向机器学习初学者与Matlab实践者的逻辑回归建模工具包,聚焦多输入单输出的回归预测任务,适用于金融风控评分、医学风险评估、工况状态预测等需概率化输出的场景。压缩包共4个文件(3个核心M函数+1个Excel数据集),总大小仅14KB,轻量易部署:其中训练主程序LPtrain.m实现参数迭代优化,main.m封装完整预测流程,sigmoid.m提供可导激活函数,data.xlsx内置标准化样本数据便于快速验证。已有309人学习下载,代码严格兼容Matlab 2018a及以上版本,结构清晰、注释详尽,关键步骤含数学推导说明;除常规MAE、RMSE评价指标外,还内置预测结果可视化与混淆矩阵分析模块,支持用户无缝替换自有数据并开展模型调优。

1. 项目概述:当逻辑回归遇上回归预测

看到这个标题,很多朋友可能会一愣:逻辑回归(Logistic Regression)不是用来做分类的吗?怎么还能做“回归预测”?这其实是一个在工程和数据分析领域非常经典且实用的思路转换。我最初接触这个需求,是在处理一个设备故障率预测的项目上。目标是根据多个传感器读数(比如温度、振动频率、工作电流等),预测出一个连续的故障概率值,或者说是设备的“健康度评分”。这个值在0到1之间,但它不是非此即彼的类别标签,而是一个需要精确量化的连续指标。这时候,标准的线性回归可能因为输出范围无界而失效,而把逻辑回归的输出直接当作一个连续的“概率分数”或“比例值”来用,就成了一个非常自然的解决方案。

简单来说,我们这里谈的“基于逻辑回归的数据回归预测”,核心是利用逻辑回归模型的Sigmoid函数,将多维输入特征线性组合的结果,映射到一个(0,1)区间内的连续值。这个值可以被解释为事件发生的概率、某种比例、完成度或者归一化后的评分。它特别适合处理那些目标变量天然有界(尤其是介于0和1之间)的回归问题。模型是“多输入单输出”的,意味着我们可以综合多种影响因素,来预测一个最终的量化结果。在Matlab里实现这套流程,从数据准备、模型训练、到预测评估,有着一套高效且直观的工具链,对于工科生、研究员和数据分析师来说,掌握这个方法能解决一大类实际的量化预测问题。

2. 核心思路与模型选型考量

2.1 为什么用逻辑回归做“回归”?

这可能是最大的困惑点。传统的逻辑回归用于二分类,其输出通过Sigmoid函数压缩到(0,1),代表样本属于正类的概率。我们通常设置一个阈值(如0.5)来做出分类决策。

然而,当我们不进行最终的阈值判断,而是直接使用这个位于(0,1)之间的概率值本身作为预测目标时,逻辑回归就变成了一种特殊的回归模型。它的优势非常明显:

  1. 输出范围有界:Sigmoid函数确保了预测值永远不会超出(0,1)这个物理或逻辑上合理的区间。比如预测转化率、市场份额、电池健康度(SOH),这些值都不可能超过100%或低于0%。普通线性回归不做约束,可能会预测出120%或-5%这种无意义的值。
  2. 非线性映射:尽管决策边界是线性的,但Sigmoid函数本身提供了输入到输出之间的非线性变换。这对于许多真实世界的关系来说,比单纯的线性关系更贴合。
  3. 概率解释性:输出值具有清晰的概率解释,这比一个单纯的回归数值更容易被业务方理解和信任。你可以说“根据当前工况,设备在未来24小时内发生故障的可能性是7.3%”,而不是“故障风险指数是0.073”。
  4. Matlab生态支持:Matlab的统计和机器学习工具箱对逻辑回归的支持非常完善,fitglm函数配合‘Distribution‘, ‘binomial‘选项可以轻松训练模型,并且提供了丰富的诊断和预测接口。

选型对比:为什么不直接用线性回归加截断?比如预测值大于1就设为1,小于0就设为0。这种方法在边界处会产生扭曲,且模型在训练时并未考虑这种边界约束,可能导致边界附近的预测极不准确。逻辑回归的Sigmoid函数则提供了一种平滑、可导的约束方式,让模型从数据中自动学习到逼近边界时的饱和特性。

2.2 多输入单输出模型的结构设计

我们的模型结构非常清晰。假设我们有m个样本,每个样本有n个特征(输入变量),记作矩阵X(大小为 m×n)。还有一个连续的目标变量y(大小为 m×1),且y的值域在(0,1)内。

逻辑回归模型试图建立如下关系:

z = β₀ + β₁X₁ + β₂X₂ + ... + βₙXₙ(线性组合部分)y_pred = σ(z) = 1 / (1 + exp(-z))(Sigmoid变换部分)

其中,β₀是截距项,β₁βₙ是每个特征对应的系数,也就是我们需要从数据中学习到的参数。σ就是Sigmoid函数。我们的目标是通过训练,找到一组β参数,使得模型预测的y_pred与真实的y尽可能接近。

在Matlab中,我们通常不会自己从头编写梯度下降代码,而是利用fitglm函数,它内部采用最大似然估计(MLE)来优化这些参数,非常稳健高效。

注意:这里有一个关键技巧。虽然我们的y是连续值,但fitglm在调用二项分布逻辑回归时,默认期望y是二分类的标签(0或1)。为了让它处理连续的y,我们需要理解其原理:它实际上是在优化伯努利分布的负对数似然。当y是连续值时,我们可以将其视为“事件成功的概率”的观测值。此时,fitglm仍然可以工作,因为它最小化的损失函数对于连续的y在(0,1)内也是有定义的(可以看作是交叉熵损失对连续标签的扩展)。这是一种实用且被广泛接受的“技巧”。

3. 数据准备与预处理实战

3.1 目标变量的处理与审视

第一步,也是最重要的一步,是确认你的目标变量y是否适合这个模型。理想情况下,y应该分布在(0,1)的开区间内。在实际数据中,你可能会遇到两种情况:

  1. y严格在(0,1)内:这是最理想的情况,可以直接使用。
  2. y在[0,1]或其它有界区间内:比如包含0和1的百分比数据,或者是在[a, b]区间内的评分。这时需要进行简单的线性缩放:y_scaled = (y - a) / (b - a)将其映射到[0,1]区间。如果数据中确实存在大量的0和1边界值,模型也能处理,但要注意解释:预测值将无限接近0或1,但理论上永远不会等于它们。

实操心得:我强烈建议在训练前绘制y的直方图。如果y的分布严重偏向0或1(比如U型分布),或者大量堆积在边界上,那么标准逻辑回归可能不是最佳选择,因为Sigmoid函数在中段变化最灵敏。这时可以考虑使用Beta回归等专门为比例数据设计的模型,不过在Matlab中实现稍复杂。对于轻度偏态的数据,逻辑回归通常表现尚可。

3.2 特征工程与预处理

对于多输入特征X,预处理至关重要,它直接影响模型的收敛速度和性能。

  1. 缺失值处理:Matlab的fitglm默认会删除包含NaN的行。对于连续特征,常用均值或中位数填充;对于分类特征,可以单独编码后增加一个“缺失”类别。更稳健的做法是使用fillmissing函数。
  2. 异常值处理:逻辑回归的损失函数对异常值相对稳健,但极端的异常值仍可能扭曲系数。可以使用箱线图或3σ原则识别,并根据业务逻辑进行修正、缩尾或视为缺失值处理。
  3. 连续特征标准化:这是强烈推荐的一步。由于逻辑回归的优化过程(如迭代重加权最小二乘法,IRLS)受特征尺度影响,将特征标准化为均值为0、标准差为1,可以加速收敛并提高数值稳定性。使用zscore函数可以轻松实现。
    [X_train_scaled, mu, sigma] = zscore(X_train); X_test_scaled = (X_test - mu) ./ sigma; % 使用训练集的参数标准化测试集
  4. 分类特征编码:如果输入特征中有类别变量(如“设备类型A/B/C”),必须将其转换为数值。使用dummyvar函数创建虚拟变量(One-hot编码)。注意,对于有k个类别的特征,只需创建k-1个虚拟变量以避免多重共线性。
  5. 特征选择:并非所有特征都有用。初步可以计算每个特征与目标y的相关性(对于连续特征用corr,对于分类特征可分析箱线图)。在训练后,逻辑回归模型系数的大小和显著性(p值)也是重要的特征重要性指标。Matlab的fitglm输出结果中就包含了这些统计信息。

4. 在Matlab中构建与训练逻辑回归模型

4.1 使用fitglm函数的核心流程

Matlab的统计和机器学习工具箱提供了最直接的途径。假设我们已有训练数据X_train(矩阵) 和y_train(向量),且已经完成了上述的预处理(特别是目标变量缩放和特征标准化)。

% 假设 X_train 是 m x n 的矩阵,y_train 是 m x 1 的向量,值在(0,1)间 % 将数据转换为表(table),这是fitglm推荐的数据格式,便于变量命名 tbl_train = array2table([X_train, y_train]); % 为最后一列命名,例如‘Target‘ tbl_train.Properties.VariableNames(end) = {‘Target‘}; % 指定模型公式。‘Target ~ 1 + X1 + X2 + ...‘ 表示用所有特征预测Target。 % 这里使用‘PredictorVars‘和‘ResponseVar‘来指定,更清晰 predictorNames = tbl_train.Properties.VariableNames(1:end-1); model = fitglm(tbl_train, ... ‘ResponseVar‘, ‘Target‘, ... ‘PredictorVars‘, predictorNames, ... ‘Distribution‘, ‘binomial‘, ... ‘Link‘, ‘logit‘); % ‘Distribution‘, ‘binomial‘ 和 ‘Link‘, ‘logit‘ 共同指定了逻辑回归模型。

关键参数解析

  • ‘Distribution‘, ‘binomial‘:指定响应变量服从二项分布。即使我们的y是连续的,也如此设置,这是使用逻辑回归核心。
  • ‘Link‘, ‘logit‘:指定连接函数为 Logit,即log(p/(1-p)),它与Sigmoid互为反函数。这一定义了线性部分z如何与概率p关联。
  • ‘Intercept‘:默认为true,会包含截距项β₀。通常不需要更改。

4.2 模型输出解读与诊断

训练完成后,直接输入model到命令行,会显示一个详细的摘要:

model = Generalized linear regression model: Target ~ [Linear Formula] Distribution = Binomial Estimated Coefficients: Estimate SE tStat pValue ________ _________ _______ __________ (Intercept) 0.051356 0.026097 1.968 0.049132 X1 0.89271 0.056015 15.937 2.328e-57 X2 -0.23456 0.032091 -7.3094 2.687e-13 ...
  • Estimate:就是学到的系数β。正数表示该特征与目标概率正相关,负数表示负相关。
  • SE:系数的标准误,衡量估计的准确性。
  • tStat:t统计量,等于 Estimate/SE。
  • pValue:p值。通常我们关注p值小于0.05或0.01的特征,认为其在统计上是显著的。注意:这里解释p值需谨慎,因为我们的y不是真正的二项分布变量,但其相对大小仍可用来辅助判断特征重要性。

模型诊断

  1. 查看模型拟合优度model.Deviancemodel.ModelCriterion.AIC/model.ModelCriterion.BIC。这些信息准则可用于比较不同特征组合的模型,值越小通常说明模型在拟合度和复杂度之间权衡得越好。
  2. 绘制残差图:逻辑回归的残差分析比线性回归复杂。可以绘制皮尔逊残差或偏差残差与预测值的散点图,检查是否有明显的模式(如漏斗形),这可能提示模型假设不满足。
    y_pred_train = predict(model, tbl_train); residuals = y_train - y_pred_train; scatter(y_pred_train, residuals); xlabel(‘预测值‘); ylabel(‘残差‘); title(‘残差图‘);
    理想情况是残差随机分布在0附近。

5. 预测、评估与部署

5.1 进行预测与结果反缩放

训练好模型后,对新的数据X_new进行预测前,务必使用与训练集完全相同的参数进行标准化。

% 对新数据(假设为矩阵)进行标准化,使用训练时保存的mu和sigma X_new_scaled = (X_new - mu) ./ sigma; % 转换为表 tbl_new = array2table(X_new_scaled, ‘VariableNames‘, predictorNames); % 预测得到 (0,1) 区间内的值 y_pred_prob = predict(model, tbl_new);

如果你的目标变量y之前进行过缩放,现在需要将预测值y_pred_prob映射回原始范围:

% 假设原始y的范围是 [ymin, ymax] y_pred_original = y_pred_prob * (ymax - ymin) + ymin;

5.2 回归预测的性能评估指标

由于我们是在做回归预测,不能使用分类任务的准确率、混淆矩阵。需要使用回归任务的评估指标:

  1. 均方误差 (MSE) 与均方根误差 (RMSE):最常用的指标,衡量预测值与真实值之间的平均平方差异。RMSE与目标变量单位相同,更易解释。
    mse = mean((y_true - y_pred).^2); rmse = sqrt(mse);
  2. 平均绝对误差 (MAE):对异常值不如MSE敏感,衡量的是平均绝对差异。
    mae = mean(abs(y_true - y_pred));
  3. 决定系数 (R²):表示模型可解释的方差比例。越接近1越好。在Matlab中可以用corr(y_true, y_pred)^2计算,或者通过1 - sum((y_true-y_pred).^2)/sum((y_true-mean(y_true)).^2)计算。
  4. 平均绝对百分比误差 (MAPE):如果目标变量是严格正值,这个指标很有用,因为它给出了误差的相对大小。
    mape = mean(abs((y_true - y_pred) ./ y_true)) * 100;

实操心得:一定要在独立的测试集上计算这些指标,而不是在训练集上,以避免过拟合的乐观估计。使用cvpartition进行交叉验证是更稳健的做法。

5.3 模型部署与持续监控

将训练好的模型用于实际生产环境,你需要保存模型对象和预处理参数。

% 保存模型和标准化参数 save(‘logistic_regression_model.mat‘, ‘model‘, ‘mu‘, ‘sigma‘, ‘ymin‘, ‘ymax‘, ‘predictorNames‘);

在部署的脚本或应用中加载:

load(‘logistic_regression_model.mat‘); % 对新数据data进行同样的预处理和预测 data_scaled = (data - mu) ./ sigma; tbl_data = array2table(data_scaled, ‘VariableNames‘, predictorNames); prediction = predict(model, tbl_data); prediction_original = prediction * (ymax - ymin) + ymin;

持续监控:模型上线后,需要定期(如每月)评估其在新数据上的性能(RMSE, MAE)。如果性能显著下降,可能意味着数据分布发生了漂移(Concept Drift),此时需要收集新数据,重新训练或调整模型。

6. 高级技巧与常见问题排查

6.1 处理过拟合与正则化

当特征很多而样本相对较少时,逻辑回归容易过拟合。Matlab的fitglm支持L2正则化(岭回归),通过‘Regularization‘, ‘ridge‘参数实现。正则化通过对系数大小施加惩罚,来防止模型过于复杂。

model_ridge = fitglm(tbl_train, ... ‘ResponseVar‘, ‘Target‘, ... ‘PredictorVars‘, predictorNames, ... ‘Distribution‘, ‘binomial‘, ... ‘Link‘, ‘logit‘, ... ‘Regularization‘, ‘ridge‘); % 可以通过‘Lambda‘参数指定正则化强度,通常需要通过交叉验证选择

选择最优的Lambda值,可以使用交叉验证。虽然fitglm没有内置的CV for GLM,但可以结合cvpartition和循环来实现。

6.2 常见问题与解决方案速查表

问题现象可能原因排查与解决思路
训练时警告:“Iteration limit reached.”模型未收敛。可能学习率问题(自定义优化时)、特征尺度差异巨大、或数据完全可分。1. 确保特征已标准化。2. 检查目标变量y是否有很多0或1,导致概率预测趋近边界,对数似然难以优化。可尝试对y进行轻微调整,如y = max(min(y, 1-eps), eps),避免取对数时无穷大。3. 增加fitglm‘Options‘中的最大迭代次数(虽然不常见)。
预测值全部非常接近0.5模型没有学到有效模式,可能特征与目标无关,或模型太简单(欠拟合)。1. 检查特征与y的相关性。2. 查看模型系数,是否都接近0且p值很大。3. 考虑增加特征交互项(如X1*X2)或多项式特征(需谨慎,可能过拟合)。
预测值大量堆积在0或1附近数据本身分布极端,或者Sigmoid函数在极端值区间的梯度很小,模型倾向于做出“肯定”的预测。1. 检查y的分布直方图。2. 如果业务允许,可以尝试对y进行 logit 变换 (log(y/(1-y))) 后使用线性回归,但这会改变误差假设。3. 考虑使用Tobit模型或Beta回归。
新数据预测出现NaN新数据中存在训练时未出现的类别(对于分类特征),或存在缺失值。1. 确保预测时使用的特征集合与训练时完全一致。2. 对于分类特征,在预处理时确保为所有可能类别生成虚拟变量,即使某些类别在训练集中未出现。3. 实施严格的数据验证管道,在预测前处理缺失值和未知类别。
模型在训练集上表现好,测试集差过拟合。1. 引入正则化(如上所述)。2. 减少特征数量(基于系数p值或LASSO等方法进行特征选择)。3. 增加训练数据量。4. 使用更简单的模型(如减少多项式阶数)。

6.3 扩展:从概率回归到分类阈值选择

虽然本项目聚焦于连续值预测,但逻辑回归的输出本质是概率。如果你最终需要一个分类决策(例如,判断设备是否“高危”,故障概率>10%),那么就需要选择一个阈值。

  • 默认阈值0.5:适用于正负例代价相似的情况。
  • 基于业务代价的阈值:如果误报(假阳性)和漏报(假阴性)的代价不同,可以通过调整阈值来优化。例如,在故障预测中,漏报的代价通常远高于误报,因此可以降低阈值(如0.1),以提高召回率。
  • 使用ROC曲线:绘制不同阈值下的真阳性率(TPR)和假阳性率(FPR)曲线,选择最靠近左上角的点,或根据业务需求确定可接受的FPR,找到对应的阈值。
% 假设 y_test_true 是连续的真实值(我们当作概率),y_test_pred 是模型预测的概率 % 为了画ROC,我们需要将连续的真实值二值化,这需要一个人为的阈值,比如0.5。 % 注意:这仅用于评估分类性能,与我们的回归目标不同。 binary_truth = y_test_true > 0.5; [X, Y, T, AUC] = perfcurve(binary_truth, y_test_pred, true); plot(X, Y); xlabel(‘False positive rate‘); ylabel(‘True positive rate‘); title([‘ROC Curve, AUC=‘ num2str(AUC)]);

这个基于逻辑回归的回归预测框架,其魅力在于它的简洁、可解释性和强大的实用性。它完美地填补了线性回归和无界输出与分类任务之间的空白,为那些需要输出一个有界连续值的预测问题提供了优雅的解决方案。在Matlab中,借助成熟的统计工具箱,从实验到部署的整个流程都能流畅地进行。下次当你遇到一个预测目标在0到100%之间的问题时,不妨先别急着尝试复杂的神经网络,试试这个经典又强大的逻辑回归回归模型,或许会有意想不到的收获。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询