Python 和 SAS 生成具有相同 abs 的 PCA 数据。值但符号倒置 - 为什么?
Python and SAS produce PCA data with same abs. values but inverted signs - why?
我正在构建一个 Python 3(pandas 用于数据操作,numpy 用于通过 SVD 的 PCA)来模仿我在研究生院写的一些代码。该代码在 SAS 9.4 中使用 PROC IML 在光谱矩阵上调用 svd。 SAS 代码:
data Raman1;
infile "Combined SpectraC.csv" dsd firstobs=2;
input Wavenumber R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21;
run;
proc iml;
use Raman1;
read all var {R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21} into Raman1[colname=varname]; *Matrix is row=value at a wavenumber, column sample**;
close Raman1;
Raman=Raman1`; *transpose;
mean1=mean(Raman);
std1=std(Raman);
RamanSVD=(Raman-mean1)/std1;
call svd (u,q,v,RamanSVD);
我的python代码(跳过in-take,spec1是SAS代码中叫Raman1的同一个数据)
(所有缩写都正常,pd=pandas,np=numpy,la=numpy.linalg)
tspec=spec1.T
tspec_stats=tspec.describe()
tspec_stats=tspec_stats.drop(["count","min","25%", "50%","75%","max"], axis=0)
scale_spec=pd.DataFrame()
tsamplelist=tspec.columns.tolist()
for i in tsamplelist:
scale_spec[i]=((tspec[i]-tspec_stats.iloc[0, i])/tspec_stats.iloc[1,i])
PCA_data=scale_spec.to_numpy()
u, s, vh= la.svd(PCA_data)
它们产生几乎相同的数据,只是大部分数据的符号相反。 Q(来自 SAS)和 S(来自 Python)相同,但对于 U 和 V 列,第 1-6、8、13-14、16、19(21 列中)具有相同的 abs 但符号不同在 SAS 和 Python 之间(即在 SAS 中为正的数据在 Python 中为负,反之亦然)。其他列(7、9-12、15、17、28、20 和 21)具有相同的 abs 值和符号。
这本身不是问题:解释光谱 PCA 的一般方法是使用有限维度(主成分)重建光谱;因为数据两边的符号都翻转了,所以重建是一样的。 X+*X+ = X-*X- 等于相同的东西,并且 X+*X- = X-*X+(假设 X 是相同的数字)。
这是我对数据的信心问题,也是我能够捍卫我的方法的问题。谁能帮我理解为什么会发生这些标志变化?这些流程有何不同?
PS:我检查过了。使用的数据是完全相同的文件。
这在数学上是因为如果x是一个特征向量,那么-x也是一个具有相同特征值的特征向量。因此,特征向量的方向是不确定的。在数值上,计算过程中的一个小舍入误差可以使方向发生变化。如果这个问题已经在图书馆之间进行了数字标准化,那就简单多了,但这不是目前的情况,所以我们必须接受它。但是,您可以任意更改方向作为任何 PCA 例程的 post 处理,例如使第一个组件非负:这是对缺乏标准化的合理修复。
我正在构建一个 Python 3(pandas 用于数据操作,numpy 用于通过 SVD 的 PCA)来模仿我在研究生院写的一些代码。该代码在 SAS 9.4 中使用 PROC IML 在光谱矩阵上调用 svd。 SAS 代码:
data Raman1;
infile "Combined SpectraC.csv" dsd firstobs=2;
input Wavenumber R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21;
run;
proc iml;
use Raman1;
read all var {R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21} into Raman1[colname=varname]; *Matrix is row=value at a wavenumber, column sample**;
close Raman1;
Raman=Raman1`; *transpose;
mean1=mean(Raman);
std1=std(Raman);
RamanSVD=(Raman-mean1)/std1;
call svd (u,q,v,RamanSVD);
我的python代码(跳过in-take,spec1是SAS代码中叫Raman1的同一个数据)
(所有缩写都正常,pd=pandas,np=numpy,la=numpy.linalg)
tspec=spec1.T
tspec_stats=tspec.describe()
tspec_stats=tspec_stats.drop(["count","min","25%", "50%","75%","max"], axis=0)
scale_spec=pd.DataFrame()
tsamplelist=tspec.columns.tolist()
for i in tsamplelist:
scale_spec[i]=((tspec[i]-tspec_stats.iloc[0, i])/tspec_stats.iloc[1,i])
PCA_data=scale_spec.to_numpy()
u, s, vh= la.svd(PCA_data)
它们产生几乎相同的数据,只是大部分数据的符号相反。 Q(来自 SAS)和 S(来自 Python)相同,但对于 U 和 V 列,第 1-6、8、13-14、16、19(21 列中)具有相同的 abs 但符号不同在 SAS 和 Python 之间(即在 SAS 中为正的数据在 Python 中为负,反之亦然)。其他列(7、9-12、15、17、28、20 和 21)具有相同的 abs 值和符号。
这本身不是问题:解释光谱 PCA 的一般方法是使用有限维度(主成分)重建光谱;因为数据两边的符号都翻转了,所以重建是一样的。 X+*X+ = X-*X- 等于相同的东西,并且 X+*X- = X-*X+(假设 X 是相同的数字)。
这是我对数据的信心问题,也是我能够捍卫我的方法的问题。谁能帮我理解为什么会发生这些标志变化?这些流程有何不同?
PS:我检查过了。使用的数据是完全相同的文件。
这在数学上是因为如果x是一个特征向量,那么-x也是一个具有相同特征值的特征向量。因此,特征向量的方向是不确定的。在数值上,计算过程中的一个小舍入误差可以使方向发生变化。如果这个问题已经在图书馆之间进行了数字标准化,那就简单多了,但这不是目前的情况,所以我们必须接受它。但是,您可以任意更改方向作为任何 PCA 例程的 post 处理,例如使第一个组件非负:这是对缺乏标准化的合理修复。