2017-06-02 32 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

相關問題