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

Matlab PLS回归代码转Python后结果差异问题求助

Matlab与Python PLSR模型结果差异问题分析与解决办法

问题描述

我需要将Matlab中实现的偏最小二乘回归(PLSR)代码转换为Python版本,原Matlab代码包含15个潜变量、5折交叉验证、100次蒙特卡洛重复。使用sklearn完成Python代码编写后,发现Matlab版本模型的R²均≥0.5,但Python版本的R²接近0甚至为负,求差异原因及解决办法。

Matlab代码实现

% PLSR with 15 latent variables
[~,~,~,~,~,MSEcv] = plsregress(X,y,15,"cv",5,"MCReps",100);
rRMSE = 100*sqrt(MSEcv(2,:))/(max(y)-min(y)); % 修正原代码括号语法错误
% Find optimal number of latent variables
minl = 1; maxl = 15;
nlv = find(rRMSE(minl+1:maxl+1)==min(rRMSE(minl+1:maxl+1)))-1+minl;
nlv = nlv(1);
% Fit with optimal number of latent variables
[XL,yl,XS,YS,beta,PCTVAR,MSE,stats] = plsregress(X,y,nlv); % 修正原代码分号语法错误

说明:最大15个潜变量,5折交叉验证,100次蒙特卡洛重复

Python代码实现

import numpy as np
from sklearn.cross_decomposition import PLSRegression
from sklearn.model_selection import cross_validate
from sklearn.model_selection import ShuffleSplit
import pandas as pd

# 读取数据
X = pd.read_table("/path/to/saved/files/X.txt", header=None)
y = pd.read_table("/path/to/saved/files/y.txt", header=None)

# Maximum number of latent variables
mlv = 15
# Cross-validation
cv = 5
# Monte-Carlo repetitions
mcr = 100

# 1...mlv to fit models with various number of latent variables
try_latent_vars = np.arange(1, mlv)

##----------------------------------------------------------------------------|
# Define funtion to fit PLSmodel
def optimise_pls_cv(X_vals, y_vals, n_comp, crossval, mcreps):
    '''Fit PLS regression model using cross-validation.'''
    # Define PLS object
    pls = PLSRegression(n_components=n_comp)

    # Cross-validation fit
    cv_split = ShuffleSplit(n_splits=mcreps, test_size=1/crossval,
                            random_state=0)
    cvs = cross_validate(pls, X_vals, y_vals, cv=cv_split,
                         scoring=["r2", "neg_mean_squared_error"])
    mean_r2_error = np.mean(cvs["test_r2"])
    test_mse = -np.mean(cvs["test_neg_mean_squared_error"])
    return pls, mean_r2_error, test_mse

##----------------------------------------------------------------------------|
# Fit PLS model

# Empty lists to store R^2 and mean squared error values
r2s = []
mses = []

for n_comp in try_latent_vars:
    model, r2, mse = optimise_pls_cv(X_vals=X.T,
                                     y_vals=y,
                                     n_comp=n_comp,
                                     crossval=cv,
                                     mcreps=mcr)
    r2s.append(r2)
    mses.append(mse)

index_max_r2s = np.argmax(r2s)
lv = try_latent_vars[index_max_r2s]

##----------------------------------------------------------------------------|
## Fit model with optimized number of components
model, r2, mse = optimise_pls_cv(X_vals=X.T,
                                 y_vals=y,
                                 n_comp=lv,
                                 crossval=cv,
                                 mcreps=mcr)
metrics = {"R2": r2,
           "MSE": mse}
metrics_str = "R2: %0.4f, MSE: %0.4f" % (r2, mse)

差异原因分析

  1. 数据维度错误:Matlab中plsregress默认输入X为[样本数×特征数]格式,而Python代码中直接使用X.T,若读取的X本身已是样本×特征的结构,转置后会变成特征×样本,导致模型输入维度完全颠倒,无法有效学习。
  2. 潜变量遍历范围缺失:Python中try_latent_vars = np.arange(1, mlv)仅遍历1到14个潜变量,遗漏了Matlab中包含的15个潜变量的情况,可能最优潜变量恰好是15。
  3. 交叉验证策略不一致:Matlab的MCReps=100是重复5折交叉验证100次,而Python使用ShuffleSplit做100次随机拆分(每次按4:1划分训练/测试集),两种拆分策略的数据分布匹配度不同,导致评估结果差异。
  4. 目标变量格式问题:读取的y是pandas DataFrame(二维结构),sklearn模型更适合接收一维数组输入,二维输入可能导致模型处理异常。
  5. 预处理细节差异:虽两者默认都对数据中心化,但需确认是否存在缩放等其他预处理差异(Matlab默认不缩放,sklearn的PLSRegression默认也不缩放,但需显式确认)。

解决办法

  1. 修正数据维度:先打印X.shape确认维度,若为(n_samples, n_features),则直接使用X.values而非X.T;若原始数据是特征×样本格式,再保留转置。
  2. 补全潜变量遍历范围:将try_latent_vars改为np.arange(1, mlv+1),确保包含15个潜变量的情况。
  3. 统一交叉验证策略:使用RepeatedKFold替代ShuffleSplit,完全匹配Matlab的重复5折交叉验证逻辑:
    from sklearn.model_selection import RepeatedKFold
    cv_split = RepeatedKFold(n_splits=cv, n_repeats=mcreps, random_state=0)
    
  4. 调整目标变量格式:将y转为一维数组,比如在调用函数时传入y_vals = y.values.ravel()。
  5. 显式设置预处理参数:初始化PLSRegression时显式指定center=True, scale=False,确保与Matlab的预处理逻辑一致:
    pls = PLSRegression(n_components=n_comp, center=True, scale=False)
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 18:40:38