一、模型原理
偏最小二乘回归(PLSR)是一种用来分析两组数据之间的关系的统计方法。想象你在玩积木,其中一些积木代表一个类型的信息(比如一个产品的各种质量指标),另一些积木则代表另一类型的信息(比如产品的性能测试结果)。现在,你的任务是找出哪些质量指标的积木和哪些性能测试的积木是相互匹配的,这样当你改变了质量指标的某些积木时,你就能预测性能测试会如何变化。
PLSR做的事情就像是找到两堆积木之间的最佳匹配。它不是简单地挨个比较每个指标和每个测试结果,而是试图找到最能代表每组数据整体特征的几个积木。这样,当其中一堆积木发生变化时,PLSR可以帮助你理解,另一堆积木上哪几个最可能会受影响,以及影响的程度。
技术上讲,PLSR通过寻找两组数据中变量之间的多维关系来工作。它寻找主要成分或者模式,这些模式揭示了一组数据是如何影响另一组数据的。这就像是在积木的两堆之间找到了隐藏的线索,这些线索告诉你哪些积木是互相影响的关键点。通过这些关键点,PLSR帮助我们预测和理解这两堆积木(也就是两组数据)之间复杂的关系。
二、应用一:比较光谱数据预测值与真实值的关系
首先,我们生成一组随机的光谱数据 X
和对应的参考值 Y
来模拟真实的实验数据。我们的目标是建立一个PLSR模型,该模型可以预测给定光谱数据的参考值。为了评估模型的预测性能,我们使用了交叉验证方法,并计算了均方误差(MSE)和决定系数(R²)作为性能指标。
1.完整代码
import numpy as np
from sklearn.cross_decomposition import PLSRegression
from sklearn.model_selection import cross_val_predict
from sklearn.metrics import mean_squared_error, r2_score
import matplotlib.pyplot as plt
# 假设有一组光谱数据X和参考值Y
# X是一个n_samples x n_features的矩阵,其中每一行代表一个样本,每一列代表一个波长的强度
# Y是一个n_samples x n_targets的矩阵,其中每一行代表一个样本的参考值,例如化学成分的浓度
# 这里我们使用随机数据来模拟真实的光谱数据和参考值
np.random.seed(0)
n_samples = 100
n_features = 200
n_targets = 1
# 生成模拟光谱数据
X = np.random.normal(0, 1, (n_samples, n_features))
# 生成模拟参考值
Y = np.random.normal(0, 1, (n_samples, n_targets))
# 创建PLSR对象,这里假设我们想要两个成分
pls = PLSRegression(n_components=2)
# 训练模型
pls.fit(X, Y)
# 使用交叉验证来评估模型
Y_cv = cross_val_predict(pls, X, Y, cv=10)
# 计算并打印性能指标
mse = mean_squared_error(Y, Y_cv)
r2 = r2_score(Y, Y_cv)
print(f'Mean Squared Error: {mse}')
print(f'R^2 Score: {r2}')
# 绘制实际值与预测值之间的关系
plt.scatter(Y, Y_cv, edgecolors=(0, 0, 0))
plt.plot([Y.min(), Y.max()], [Y_cv.min(), Y_cv.max()], 'k--', lw=4)
plt.xlabel('True Values')
plt.ylabel('Predictions')
plt.title('PLSR Model Predictions vs True Values')
plt.show()
2.运行结果
三、应用二:建立样品属性与光谱数据的相关关系
第二个应用时使用偏最小二乘回归(PLSR)分析样品属性(如浓度)与其光谱数据之间的相关关系。首先,程序生成了150个样本的模拟光谱数据(X)和相应的样品属性值(Y),其中光谱数据包含100个波长点。接着,数据被分割成训练集和测试集。然后,PLSR模型被训练在训练集上以找到X和Y之间的关系,并用该模型来预测测试集样本的属性值。最后,程序绘制了这些预测值与相应的光谱数据,为了可视化分析,只展示了前10个样本,并假定了波数在0到100厘米^-1之间均匀分布。
1.完整代码
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cross_decomposition import PLSRegression
from sklearn.model_selection import train_test_split
# 假定已经加载了光谱数据X和相应的多个样品属性Y
# 这里使用模拟数据示例
np.random.seed(2)
X = np.random.normal(0, 1, (150, 100)) # 假设有100个波长点
Y = np.random.normal(0, 1, (150, 1)) # 假设预测单个样品属性(浓度)
# 分割数据为训练集和测试集
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2, random_state=1)
# PLSR模型
pls = PLSRegression(n_components=2)
pls.fit(X_train, Y_train)
# 使用模型预测光谱浓度
Y_pred = pls.predict(X_test)
# 假设波数是均匀分布的,生成与X相对应的波数数组
# 更新波数范围为0-100厘米^-1
wavenumbers = np.linspace(0, 100, X.shape[1])
# 绘制前10个样品的光谱浓度曲线
plt.figure(figsize=(12, 6))
# 确保不超过样品总数
num_samples_to_plot = min(10, Y_pred.shape[0])
for i in range(num_samples_to_plot):
plt.plot(wavenumbers, X_test[i, :], label=f'Sample {i+1}')
plt.xlabel('Wavenumber (cm-1)')
plt.ylabel('Predicted Concentration')
plt.title('Predicted Spectral Concentrations for First 10 Samples (0-100 cm-1)')
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left') # 将图例放置在图外
plt.tight_layout()
plt.show()