如何使用sklearn的IncrementalPCApartial_fit

Jef*_*son 4 python machine-learning pca scikit-learn

我有一个相当大的数据集,我想分解它,但太大而无法加载到内存中。研究我的选择,似乎sklearn 的 IncrementalPCA是一个不错的选择,但我不太清楚如何让它工作。

\n\n

我可以很好地加载数据:

\n\n
f = h5py.File(\'my_big_data.h5\')\nfeatures = f[\'data\']\n
Run Code Online (Sandbox Code Playgroud)\n\n

这个例子来看,我似乎需要决定我想从中读取什么大小的块:

\n\n
num_rows = data.shape[0]     # total number of rows in data\nchunk_size = 10              # how many rows at a time to feed ipca\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后我可以创建 IncrementalPCA,逐块流式传输数据,并部分拟合它(同样来自上面的示例):

\n\n
ipca = IncrementalPCA(n_components=2)\nfor i in range(0, num_rows//chunk_size):\n    ipca.partial_fit(features[i*chunk_size : (i+1)*chunk_size])\n
Run Code Online (Sandbox Code Playgroud)\n\n

这一切都没有错误,但我不知道下一步该做什么。我实际上如何进行降维并获得一个可以进一步操作并保存的新的 numpy 数组?

\n\n

编辑
\n上面的代码用于测试我的数据的较小子集 \xe2\x80\x93\xc2\xa0as @ImanolLuengo 正确指出,在最终代码中使用更多的维度和块大小会更好。

\n

Ima*_*ngo 8

正如您所猜测的那样,拟合已正确完成,尽管我建议将 增加到chunk_size100 或 1000(甚至更高,具体取决于数据的形状)。

你现在要做的就是改造

out = my_new_features_dataset # shape N x 2
for i in range(0, num_rows//chunk_size):
    out[i*chunk_size:(i+1) * chunk_size] = ipca.transform(features[i*chunk_size : (i+1)*chunk_size])
Run Code Online (Sandbox Code Playgroud)

这应该会给你带来新的转变功能。如果您仍然有太多样本无法容纳在内存中,我建议将其用作out另一个 hdf5 数据集。

另外,我认为将一个巨大的数据集减少为两个组件可能不是一个好主意。但在不知道你的形状的情况下很难说features。我建议将它们减少到sqrt(features.shape[1]),因为这是一个不错的启发式或专业提示:用于ipca.explained_variance_ratio_确定适合您负担得起的信息丢失阈值的最佳功能数量。


编辑:对于 ,explained_variance_ratio_它返回一个维度向量n_componentsn_components作为参数传递给 IPCA 的 ),其中每个值i表示由第i个新分量解释的原始数据方差的百分比。

您可以按照此答案中的过程来提取前n个组件保留了多少信息:

>>> print(ipca.explained_variance_ratio_.cumsum())
[ 0.32047581  0.59549787  0.80178824  0.932976    1.        ]
Run Code Online (Sandbox Code Playgroud)

注意:数字是从上面的答案中虚构的,假设您已将 IPCA 减少到 5 个组件。第i个数字表示有多少原始数据由前 [0, i] 分量解释,因为它是解释方差比的累积和。

因此,通常要做的是将 PCA 拟合到与原始数据相同数量的组件中:

ipca = IncrementalPCA(n_components=features.shape[1])
Run Code Online (Sandbox Code Playgroud)

然后,在对整个数据进行训练(使用迭代 + partial_fit)后,您可以绘制explaine_variance_ratio_.cumsum()并选择要丢失的数据量。或者自动执行:

k = np.argmax(ipca.explained_variance_ratio_.cumsum() > 0.9)
Run Code Online (Sandbox Code Playgroud)

上面的代码将返回 cumcum 数组上的第一个索引,其中值为> 0.9,即表示保留至少 90% 原始数据的 PCA 分量的数量。

然后您可以调整转换以反映它:

cs = chunk_size
out = my_new_features_dataset # shape N x k
for i in range(0, num_rows//chunk_size):
    out[i*cs:(i+1)*cs] = ipca.transform(features[i*cs:(i+1)*cs])[:, :k]
Run Code Online (Sandbox Code Playgroud)

请注意,切片:k仅选择第一个k组件,而忽略其余组件。