Добавочные ППШ
Я никогда не использовал инкрементный PCA, который существует в sklearn, и я немного запутался в его параметрах и не смог найти хорошее объяснение им.
Я вижу, что в конструкторе есть batch_size
, но также, при использовании метода partial_fit
Вы можете снова передать только часть ваших данных, я нашел следующий Способ:
n = df.shape[0]
chunk_size = 100000
iterations = n//chunk_size
ipca = IncrementalPCA(n_components=40, batch_size=1000)
for i in range(0, iterations):
ipca.partial_fit(df[i*chunk_size : (i+1)*chunk_size].values)
ipca.partial_fit(df[iterations*chunk_size : n].values)
Теперь, чего я не понимаю, так это следующего - при использовании частичной подгонки, играет ли batch_size какую-либо роль вообще или нет? И как они связаны между собой?
Кроме того, если рассматривать оба варианта, как я должен правильно изменить их значения, когда хочу увеличить точность при увеличении объема памяти (и наоборот, уменьшить потребление памяти за счет снижения точности)?
2 ответа:
Batch_size: int или None, (по умолчанию=None)
The number of samples to use for each batch. Only used when calling fit...
Этот параметр не используется в
partial_fit
, где размер пакета контролируется пользователем.Больше пакетов будет увеличиваться потребление памяти, поменьше будет уменьшить его. Это также написано в документах:
Этот алгоритм имеет постоянную сложность памяти, в порядке batch_size, что позволяет использовать np.memmap файлы без загрузки всего файла в память.
Несмотря на некоторые проверки и параметрические эвристики, вся
fit
-функция выглядит следующим образом:for batch in gen_batches(n_samples, self.batch_size_): self.partial_fit(X[batch], check_input=False)
Вот некоторый инкрементный код PCA, основанный на https://github.com/kevinhughes27/pyIPCA который является реализацией метода CCIPCA.
import scipy.sparse as sp import numpy as np from scipy import linalg as la import scipy.sparse as sps from sklearn import datasets class CCIPCA: def __init__(self, n_components, n_features, amnesic=2.0, copy=True): self.n_components = n_components self.n_features = n_features self.copy = copy self.amnesic = amnesic self.iteration = 0 self.mean_ = None self.components_ = None self.mean_ = np.zeros([self.n_features], np.float) self.components_ = np.ones((self.n_components,self.n_features)) / \ (self.n_features*self.n_components) def partial_fit(self, u): n = float(self.iteration) V = self.components_ # amnesic learning params if n <= int(self.amnesic): w1 = float(n+2-1)/float(n+2) w2 = float(1)/float(n+2) else: w1 = float(n+2-self.amnesic)/float(n+2) w2 = float(1+self.amnesic)/float(n+2) # update mean self.mean_ = w1*self.mean_ + w2*u # mean center u u = u - self.mean_ # update components for j in range(0,self.n_components): if j > n: pass elif j == n: V[j,:] = u else: # update the components V[j,:] = w1*V[j,:] + w2*np.dot(u,V[j,:])*u / la.norm(V[j,:]) normedV = V[j,:] / la.norm(V[j,:]) normedV = normedV.reshape((self.n_features, 1)) u = u - np.dot(np.dot(u,normedV),normedV.T) self.iteration += 1 self.components_ = V / la.norm(V) return def post_process(self): self.explained_variance_ratio_ = np.sqrt(np.sum(self.components_**2,axis=1)) idx = np.argsort(-self.explained_variance_ratio_) self.explained_variance_ratio_ = self.explained_variance_ratio_[idx] self.components_ = self.components_[idx,:] self.explained_variance_ratio_ = (self.explained_variance_ratio_ / \ self.explained_variance_ratio_.sum()) for r in range(0,self.components_.shape[0]): d = np.sqrt(np.dot(self.components_[r,:],self.components_[r,:])) self.components_[r,:] /= d
Вы можете проверить это с помощью
Импорт панд как pd, ccipca
df = pd.read_csv('iris.csv') df = np.array(df)[:,:4].astype(float) pca = ccipca.CCIPCA(n_components=2,n_features=4) S = 10 print df[0, :] for i in range(150): pca.partial_fit(df[i, :]) pca.post_process()
Результирующие собственные векторы / значения не будут точно такими же, как пакетный PCA. Результаты приблизительны, но они полезны.