2017-06-02 31 views
0

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

我可以在数据加载就好:

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正确地指出,这将是更好的方式来使用的最终代码尺寸更大数量和块大小。

回答

1

正如你所猜测的那样,拟合是否正确完成,虽然我会建议将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_,它返回(您传递作为参数传递给IPCA的n_components)尺寸n_components的向量,其中每个值 inicates自己的原始数据的方差的解释比例第号第号新组件。

您可以按照this answer的过程抽取多少信息被第一ñ成分保留:

>>> print(ipca.explained_variance_ratio_.cumsum()) 
[ 0.32047581 0.59549787 0.80178824 0.932976 1.  ] 

注:数字ficticius从答案采取上述假设你已经减少IPCA到5个组件。第 - 个数字表示第一个[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分量的数目。

然后你可以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仅仅只选择第一k成分而忽略了其他。

+0

所以我根本不使用'partial_fit'?我的理解(这可能是错误的)是,你首先通过数据执行'partial_fit',然后转换整个事情。 – JeffThompson

+0

@JeffThompson是的,你必须这样做,那就是你已经完成了部分合体。你必须首先适应你的所有数据,然后完成所有数据。 –

+0

我明白了 - 所以你必须在'partial_fit'循环后再次循环块? – JeffThompson

相关问题