如何使用 sklearn 的 IncrementalPCA partial_fit
How to use sklearn's IncrementalPCA partial_fit
我有一个相当大的数据集,我想对其进行分解,但由于太大而无法加载到内存中。研究我的选择,似乎 sklearn's IncrementalPCA 是一个不错的选择,但我不太清楚如何让它发挥作用。
我可以很好地加载数据:
f = h5py.File('my_big_data.h5')
features = f['data']
从 开始,我似乎需要决定要从中读取的块大小:
num_rows = data.shape[0] # total number of rows in data
chunk_size = 10 # how many rows at a time to feed ipca
然后我可以创建我的 IncrementalPCA,逐块流式传输数据,并部分拟合它(也来自上面的示例):
ipca = IncrementalPCA(n_components=2)
for i in range(0, num_rows//chunk_size):
ipca.partial_fit(features[i*chunk_size : (i+1)*chunk_size])
这一切都没有错误,但我不确定下一步该怎么做。我如何实际进行降维并获得一个我可以进一步操作并保存的新 numpy 数组?
编辑
上面的代码用于测试我数据的较小子集——正如@ImanolLuengo 正确指出的那样,在最终代码中使用更多的维度和块大小会更好。
如您所料,拟合已正确完成,但我建议将 chunk_size
增加到 100 或 1000(或更高,具体取决于数据的形状)。
你现在要做的是改造它,实际上是 transforming 它:
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])
这应该会给您新的转换功能。如果您仍然有太多样本无法放入内存,我建议使用 out
作为另一个 hdf5 数据集。
此外,我认为将庞大的数据集减少为 2 个组件可能不是一个好主意。但是如果不知道你的 features
的形状就很难说了。我建议将它们减少到 sqrt(features.shape[1])
,因为它是一种不错的启发式方法,或者专业提示:使用 ipca.explained_variance_ratio_
来确定可承受的信息丢失阈值的最佳特征量。
编辑:至于 explained_variance_ratio_
,它 return 是维度 n_components
的向量(您作为参数传递给 IPCA 的 n_components
),其中每个值 i 表示第 i 个新分量解释的原始数据的方差百分比。
您可以按照 中的过程提取前 n 个组件保留了多少信息:
>>> print(ipca.explained_variance_ratio_.cumsum())
[ 0.32047581 0.59549787 0.80178824 0.932976 1. ]
注意:假设您已将 IPCA 减少到 5 个组件,数字是从上面的答案中提取的虚构数字。第 i 个数字表示原始数据中有多少被第 [0, i] 个分量解释,因为它是解释方差比的累积和。
因此,通常要做的是使 PCA 适合与原始数据相同数量的组件:
ipca = IncrementalPCA(n_components=features.shape[1])
然后,在对整个数据进行训练后(使用迭代 + partial_fit
),您可以绘制 explaine_variance_ratio_.cumsum()
并选择要丢失的数据量。或者自动执行:
k = np.argmax(ipca.explained_variance_ratio_.cumsum() > 0.9)
以上将return cumcum 数组中值为> 0.9
的第一个索引,这表示保留至少90% 原始数据的PCA 组件的数量。
然后你可以 tweek 转换来反映它:
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]
请注意 :k
的切片仅 select 前 k
部分而忽略其余部分。
我有一个相当大的数据集,我想对其进行分解,但由于太大而无法加载到内存中。研究我的选择,似乎 sklearn's IncrementalPCA 是一个不错的选择,但我不太清楚如何让它发挥作用。
我可以很好地加载数据:
f = h5py.File('my_big_data.h5')
features = f['data']
从
num_rows = data.shape[0] # total number of rows in data
chunk_size = 10 # how many rows at a time to feed ipca
然后我可以创建我的 IncrementalPCA,逐块流式传输数据,并部分拟合它(也来自上面的示例):
ipca = IncrementalPCA(n_components=2)
for i in range(0, num_rows//chunk_size):
ipca.partial_fit(features[i*chunk_size : (i+1)*chunk_size])
这一切都没有错误,但我不确定下一步该怎么做。我如何实际进行降维并获得一个我可以进一步操作并保存的新 numpy 数组?
编辑
上面的代码用于测试我数据的较小子集——正如@ImanolLuengo 正确指出的那样,在最终代码中使用更多的维度和块大小会更好。
如您所料,拟合已正确完成,但我建议将 chunk_size
增加到 100 或 1000(或更高,具体取决于数据的形状)。
你现在要做的是改造它,实际上是 transforming 它:
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])
这应该会给您新的转换功能。如果您仍然有太多样本无法放入内存,我建议使用 out
作为另一个 hdf5 数据集。
此外,我认为将庞大的数据集减少为 2 个组件可能不是一个好主意。但是如果不知道你的 features
的形状就很难说了。我建议将它们减少到 sqrt(features.shape[1])
,因为它是一种不错的启发式方法,或者专业提示:使用 ipca.explained_variance_ratio_
来确定可承受的信息丢失阈值的最佳特征量。
编辑:至于 explained_variance_ratio_
,它 return 是维度 n_components
的向量(您作为参数传递给 IPCA 的 n_components
),其中每个值 i 表示第 i 个新分量解释的原始数据的方差百分比。
您可以按照
>>> print(ipca.explained_variance_ratio_.cumsum())
[ 0.32047581 0.59549787 0.80178824 0.932976 1. ]
注意:假设您已将 IPCA 减少到 5 个组件,数字是从上面的答案中提取的虚构数字。第 i 个数字表示原始数据中有多少被第 [0, i] 个分量解释,因为它是解释方差比的累积和。
因此,通常要做的是使 PCA 适合与原始数据相同数量的组件:
ipca = IncrementalPCA(n_components=features.shape[1])
然后,在对整个数据进行训练后(使用迭代 + partial_fit
),您可以绘制 explaine_variance_ratio_.cumsum()
并选择要丢失的数据量。或者自动执行:
k = np.argmax(ipca.explained_variance_ratio_.cumsum() > 0.9)
以上将return cumcum 数组中值为> 0.9
的第一个索引,这表示保留至少90% 原始数据的PCA 组件的数量。
然后你可以 tweek 转换来反映它:
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]
请注意 :k
的切片仅 select 前 k
部分而忽略其余部分。