我有一个相当大的数据集,我想分解,但是太大了,无法加载到内存中.研究我的选择,似乎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正确指出的那样,在最终代码中使用大量维度和块大小会更好.
解决方法:
如您所料,拟合工作正确完成,尽管我建议将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])
那应该为您提供新的转换功能.如果仍然有太多样本无法容纳在内存中,建议将其用作另一个hdf5数据集.
另外,我认为将庞大的数据集减少为2个组件可能不是一个好主意.但是,如果不知道特征的形状很难说.我建议将其减少为sqrt(features.shape [1]),因为它是一种不错的启发式方法或提示:请使用ipca.explained_variance_ratio_确定可承受的信息丢失阈值的最佳功能.
编辑:至于explained_variance_ratio_,它返回一个维数为n_components的向量(作为参数传递给IPCA的n_components),其中每个值i表示由第i个新组件解释的原始数据的方差百分比.
您可以按照this answer中的过程提取前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)
上面的代码将返回值大于等于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个组件,而忽略其余部分.