一、原理
PLS是一种用于处理多元回归问题的统计方法,特别适用于处理高维数据、多重共线性问题和小样本数据集。
PLS算法原理的核心思想
- 目标:解决多元线性回归中的多重共线性问题,同时进行降维。
- 策略:通过寻找特征空间(X)和目标空间(Y)的协方差最大的方向(即潜在变量)来构建模型。
- 特点:同时分解X和Y,并最大化它们的协方差。
二、主要解决的问题
pls算法主要用于解决高维小样本问题,特征数量(p)远大于样本数量(n);噪声数据建模,例如近红外光谱分析(仪器噪声干扰)等;因此,用pls做近红外光谱预测化学成分、感官质量、烟气等,非常适合。
三、python代码需要优化的参数
近红外光谱数据预测烟气含量,步骤:
1、数据预处理、数据标准化
2、划分训练集(验证集是从训练集中划分的一部分,主要用来调参数)及测试集,其中训练集通过K折交叉验证,筛选出最优的主成分数,算法参数选定后,“训练集+验证集”重新训练最终的模型。
3、测试集只进行评估模型,不参与模型优化
建模过程中的几个问题:
1、近红外光谱数据经过一阶导+平滑处理后,还需要进行标准化吗?
一阶导数和平滑处理主要解决基线漂移、背景干扰和噪声问题,但它们不会消除不同波长点或样本间的绝对强度差异。
PLS通过最大化自变量(光谱)与因变量(烟气浓度)的协方差建模。若光谱各波长点量纲差异大(如部分波段强度高、部分波段强度低),模型会过度关注高方差波段,忽略低方差但可能重要的信息。标准化确保所有特征处于相近数值范围,提升模型稳定性和解释性。
避免过度处理:若数据本身强度范围一致,或导数处理后已满足要求,可仅做中心化。标准化可能放大噪声,需通过交叉验证确认效果。
在Python的scikit-learn库中,PLSRegression(n_components=best_combo)在执行时会自动对输入数据进行中心化(即减去均值),但不会自动进行标准化(除以标准差)。
可以通过对比标准化与非标准化的模型差异。
预测(测试集)指标评估-公式:
平均绝对误差 (MAE - Mean Absolute Error)-接近0,鲁棒性强:
MAE = (1/n) * Σ |y_true - y_pred|
优点: 直观易懂,表示平均预测误差的绝对值。单位与原数据相同(如 mg/cig)。
均方根误差 (RMSE - Root Mean Squared Error)-越小越好,对异常值敏感:
RMSE = sqrt((1/n) * Σ (y_true - y_pred)^2)
优点: 对较大的预测误差更为敏感(平方项放大了大误差的影响),能更好地反映预测的稳定性。单位与原数据相同。
RMSE 值越小越好。通常比 MAE 大,如果 RMSE 显著大于 MAE,说明模型存在较大的预测偏差点。
决定系数 (R² - R-Squared / Coefficient of Determination)-越接近1越好,表示模型解释的方差比例:
R² = 1 - (Σ (y_true - y_pred)^2) / (Σ (y_true - mean(y_true))^2)
优点: 衡量模型对目标变量变异性的解释程度。值域 [0, 1]。
解读: R² 越接近 1 越好。0.8 以上通常被认为模型拟合效果不错,但具体阈值取决于领域要求和数据特性。注意: 在训练集上 R² 通常偏高,需关注在测试集上的 R²。
平均绝对百分比误差 (MAPE - Mean Absolute Percentage Error)-MAPE 值越小越好:
MAPE = (100% / n) * Σ |(y_true - y_pred) / y_true|
优点: 以百分比形式表示平均预测误差,便于在不同量级的目标变量之间比较模型的相对表现。
缺点: 当真实值 y_true 接近或等于 0 时,MAPE 会变得非常大或未定义。
模型评估
检查过拟合
- 比较训练集和测试集性能:
- 若训练集R²很高而测试集很低 → 过拟合
- 若两者均低 → 欠拟合
2、PLSRegression中主成分数是唯一需要优化的超参数,可以采用k折交叉验证筛选最优主成分数。
单因变量预测代码
# 数据标准化 只对x进行标准化,pls函数内部对y进行了中心化
X_scaler = StandardScaler()
X_scaled = X_scaler.fit_transform(d)
# 划分训练集和测试集 (80%训练, 20%测试)
X_train, X_test, y_train, y_test = train_test_split(
X_scaled, y, test_size=0.2, random_state=42
)
# 交叉验证确定最佳主成分数
mse_scores = []
components= range(1, 20) # 1到最小维度或20
# 回归任务常用评分选项
# - `'r2'`:决定系数R²
# - `'neg_mean_squared_error'`:负均方误差(MSE)
# - `'neg_root_mean_squared_error'`:负均方根误差(RMSE)
# - `'neg_mean_absolute_error'`:负平均绝对误差(MAE)
# - `'neg_mean_absolute_percentage_error'`:负平均绝对百分比误差(MAPE)
# - `'max_error'`:最大误差
for n_comp in components:
pls_temp = PLSRegression(n_components=n_comp)
# 使用10折交叉验证计算MSE
scores = -cross_val_score(pls_temp, X_scaled, y,
cv=KFold(10, shuffle=True, random_state=42),
scoring='neg_mean_squared_error')
mse_scores.append(np.mean(scores))
# 找到最佳主成分数
best_n_comp = components[np.argmin(mse_scores)]
print(f"最佳主成分数: {best_n_comp}, 最小MSE: {min(mse_scores):.4f}")
# 使用最佳主成分训练最终模型
final_pls = PLSRegression(n_components=best_n_comp)
final_pls.fit(X_train, y_train)
# 预测
y_test_pred = final_pls.predict(X_test)
y_train_pred = final_pls.predict(X_train)
# 模型评估 预测集
rmse = np.sqrt(mean_squared_error(y_test, y_test_pred))
r2 = r2_score(y_test, y_test_pred)
mae = mean_absolute_error(y_test, y_test_pred)
print(f"RMSE: {rmse:.4f}, R²: {r2:.4f}, MAE: {mae:.4f}")













网友评论