MATLAB中矩阵存储多组数据的批量线性回归实现
MATLAB矩阵逐列配对线性回归实现
你之前的单向量回归逻辑完全可以复用,逐列处理时构造设计矩阵报错,基本都是全1向量长度和x列长度不匹配、索引维度错误导致的,下面给出两种可直接运行的实现方案。
方案1:for循环实现(逻辑清晰,易调试,优先推荐)
该方案完全沿用你已熟悉的单组回归逻辑,提前预分配内存存储所有列的结果,不会出现变量覆盖问题,出错时也方便逐列调试。
各结果存储规则:
m2_all:2行N列矩阵,第一行为每组回归的截距,第二行为对应斜率yCalc_all:和输入X/Y同尺寸矩阵,每一列存储对应组的回归预测y值Rsq2_all:1行N列向量,存储每组回归的R²决定系数
% 输入尺寸校验 [n_sample, n_group] = size(X); if ~isequal(size(X), size(Y)) error('X和Y矩阵的行数、列数必须完全一致,才能逐列配对执行回归'); end % 预分配内存(避免循环内动态扩容拖慢速度) m2_all = zeros(2, n_group); yCalc_all = zeros(n_sample, n_group); Rsq2_all = zeros(1, n_group); % 逐列执行回归 for col_idx = 1:n_group % 提取当前组的x、y数据 x_curr = X(:, col_idx); y_curr = Y(:, col_idx); % 构造当前组的设计矩阵:第一列为全1向量(长度等于样本量),第二列为当前x列 X_design = [ones(n_sample, 1), x_curr]; % 核心回归计算 m2_curr = X_design \ y_curr; yCalc_curr = X_design * m2_curr; ss_res = sum((y_curr - yCalc_curr).^2); ss_tot = sum((y_curr - mean(y_curr)).^2); Rsq2_curr = 1 - ss_res / ss_tot; % 结果存入对应存储位置 m2_all(:, col_idx) = m2_curr; yCalc_all(:, col_idx) = yCalc_curr; Rsq2_all(col_idx) = Rsq2_curr; end
方案2:向量化无循环实现(适合大矩阵高速运算)
如果你的矩阵列数非常多(比如上千组回归),for循环会有一定性能开销,可以用稀疏矩阵构造全局设计矩阵,一次性求解所有组的回归结果,运算速度远高于循环。
[n_sample, n_group] = size(X); if ~isequal(size(X), size(Y)) error('X和Y矩阵的行数、列数必须完全一致'); end % 构造稀疏全局设计矩阵 y_vec = Y(:); X_design_sparse = [ repelem(speye(n_group), n_sample, 1), ... % 截距项对应的块对角全1矩阵 sparse(X(:)) % 所有组的x值拼接为单列 ]; % 一次性求解所有回归系数 m2_vec = X_design_sparse \ y_vec; intercepts = m2_vec(1:n_group); slopes = m2_vec(n_group+1:end); m2_all = [intercepts'; slopes']; % 批量计算预测值和R² yCalc_all = reshape(X_design_sparse * m2_vec, n_sample, n_group); ss_res = sum((Y - yCalc_all).^2, 1); ss_tot = sum((Y - mean(Y,1)).^2, 1); Rsq2_all = 1 - ss_res ./ ss_tot;
注意:如果某一列的x值完全相同(x无方差),反斜杠运算会抛出警告,且该列的
ss_tot为0,计算出的R²为NaN,属于正常统计结果,代表该列数据不存在有效线性关系。
内容的提问来源于stack exchange,提问作者Lisa Mills
相关产品推荐
相关产品推荐

