我有一个相当大的数据集,我想分解但是太大而无法加载到内存中。研究我的选择,似乎sklearn's IncrementalPCA是一个不错的选择,但我无法弄清楚如何使其发挥作用。
我可以很好地加载数据:
f = h5py.File('my_big_data.h5')
features = f['data']
从this example开始,似乎我需要决定我想从中读取的块大小:
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正确指出的那样,在最终代码中使用更大数量的维度和块大小会更好。
答案 0 :(得分:2)
正如您所猜测的那样,拟合已正确完成,但我建议将chunk_size
增加到100或1000(甚至更高,具体取决于数据的形状)。
现在要做的就是改变它,实际上是transform它:
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_
,它会返回维度n_components
的向量(您作为参数传递给IPCA的n_components
),其中每个值 i 通过 i -th新组件解释原始数据的方差百分比。
您可以按照this answer中的步骤提取第一个 n 组件保留的信息量:
>>> print(ipca.explained_variance_ratio_.cumsum())
[ 0.32047581 0.59549787 0.80178824 0.932976 1. ]
注意:假设您已将IPCA减少到5个组件,数字从上面的答案中获取。 i -th数表示第一个[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)
上面将返回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]
注意切片到:k
只选择第一个k
组件而忽略其余组件。