在PCA之前对标准化感到困惑

Fea*_*a94 2 python machine-learning pca scikit-learn

我正在尝试训练线性回归模型。通过 GridSearchCV,我想研究 PCA 后模型在不同维数下的表现。我还发现了一个 sklearn教程,它的作用几乎相同。

但首先,我的代码:

import pandas as pd
import sklearn.linear_model as skl_linear_model
import sklearn.pipeline as skl_pipeline
import sklearn.model_selection as skl_model_selection
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler

model_lr = skl_linear_model.LinearRegression()

pca_lr = PCA()

pipeline = skl_pipeline.Pipeline([
            ('standardize', StandardScaler()),
            ('reduce_dim', pca_lr), 
            ('regressor', model_lr)])

n_components = list(range(1, len(X_train.columns)+1))
param_grid_lr = {'reduce_dim__n_components': n_components}

estimator_lr = skl_model_selection.GridSearchCV(
                pipeline,
                param_grid_lr,
                scoring='neg_root_mean_squared_error',
                n_jobs=2,
                cv=skl_model_selection.KFold(n_splits=25, shuffle=False, random_state=None),
                error_score=0,
                verbose=1,
                refit=True)

estimator_lr.fit(X_train, y_train)
grid_results_lr = pd.DataFrame(estimator_lr.cv_results_)
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我的训练数据是 8548x7 数组形状的不同单位的测量值。到目前为止,代码似乎有效,这些是cv_results。由于问题的复杂性,线性回归的结果是可以的(我还使用性能更好的其他模型)。

如果我理解正确的话,图像显示,主成分 1 和 2 应该解释数据的主要部分,因为这两个成分的损失几乎最小化。添加更多主成分并不能真正改善结果,因此它们对解释方差的贡献可能相当低。

为了证明这一点,我手动进行了 PCA,这引起了混乱:

X_train_scaled = StandardScaler().fit_transform(X_train)

pca = PCA()

PC_list = []
for i in range(1,len(X_train.columns)+1): PC_list.append(''.join('PC'+str(i)))

PC_df = pd.DataFrame(data=pca.fit_transform(X_train_scaled), columns=PC_list)

PC_loadings_df = pd.DataFrame(pca.components_.T,
                            columns=PC_list,
                            index=X_train.columns.values.tolist())

PC_var_df = pd.DataFrame(data=pca.explained_variance_ratio_,
                         columns=['explained_var'],
                         index=PC_list)
Run Code Online (Sandbox Code Playgroud)

这就是解释的方差比。

这似乎有点出乎我的意料,所以我查看了我一开始提到的教程。如果我不忽略一件事,这个人所做的几乎是一样的,除了一件事:

在拟合 PCA 时,他们没有缩放数据,即使他们在管道中使用了 StandardScaler。无论如何,他们得到的结果看起来不错。

所以我尝试了相同的方法,并且没有标准化,解释的方差比看起来像这样。这似乎可以更好地解释我的 cv_results,因为 PC 1 和 2 解释了超过 90% 的方差。

但我想知道他们为什么不在 PCA 之前缩放数据。我找到的关于 PCA 的每条信息都表明输入需要标准化。这是有道理的,因为我拥有的数据是不同单位的测量值。

那么我错过了什么?我最初的方法实际上是正确的吗?我只是误解了结果?前两个主成分是否有可能几乎最小化损失,即使它们只能解释大约 50% 的方差?或者甚至可能是,管道中的 PCA 实际上并未对数据进行缩放,这就是为什么 CV 的结果与非标准化手动 PCA 的相关性更好?

Gul*_*zar 5

我没有检查代码的正确性,只是阅读文本并查看图表。我假设你的分析是正确的。

我只会尝试解决

但我想知道为什么他们不在 PCA 之前缩放数据

我建议对此持保留态度,因为不久前我开始思考同样的问题,这就是我想到的。我对以下内容没有任何参考。


什么时候应该或不应该扩展数据?

如果出现以下情况,您应该缩放数据:

  1. 您的数据是不同单位的测量值。
  2. 您的列具有完全不同的比例(因此显然其中一个将主导方差)。
  3. 您的数据是不同传感器的测量结果。

如果出现以下情况,则不应缩放数据

  1. 您的数据是同一测量的不同维度,例如 3d 点 - 因为您希望(例如)x 轴主导方差(如果所有轴都具有相同的比例)。
  2. 您的数据是同一多维传感器(例如图像)的测量结果。

看起来最后一点就是教程中的情况 - 8x8 位实际上是 64 通道传感器。每个像素已经在传感器中标准化(因为我相信数据集被假设是干净的)。


PCA将不起作用,如果

  1. 您的数据具有不同的(恒定)规模,但您希望保留数据中的绝对差异。
  2. 您的数据存在尺度差异。
  3. 还有很多原因,这里就不一一列举了。

不难找到 PCA 不起作用的例子。毕竟,这只是一个线性模型。


这并没有说明您应该如何处理自己的 8548x7 数据。仅从形状来看,我假设在这种情况下你应该正常化。

我希望这能给进一步思考带来一些启发。


让我添加一个关于不缩放图像的旁注:由于图像之间可能发生变化的光照、深度或其他影响,多个图像可以被视为由不同的传感器拍摄。对于测试数据库的 8x8 扫描,这种情况不太可能发生。