【问题标题】:Incremental PCA增量 PCA
【发布时间】:2017-02-03 09:14:02
【问题描述】:

我从未使用过 sklearn 中存在的增量 PCA,我对它的参数有点困惑,无法找到它们的良好解释。

我看到构造函数中有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 是否起任何作用?它们有什么关系?

此外,如果两者都考虑,我应该如何正确更改它们的值,当我想在增加内存占用的同时提高精度(反之,以降低精度为代价减少内存消耗)?

【问题讨论】:

    标签: scikit-learn pca


    【解决方案1】:

    docs 说:

    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-function 看起来像这样:

    for batch in gen_batches(n_samples, self.batch_size_):
        self.partial_fit(X[batch], check_input=False)
    

    【讨论】:

    • 好的,所以 ti 基本上和我手动做的一样。感谢您的帮助。
    【解决方案2】:

    这是一些基于https://github.com/kevinhughes27/pyIPCA 的增量PCA 代码,它是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 完全相同。结果是近似的,但它们很有用。

    【讨论】:

      猜你喜欢
      • 2015-10-04
      • 2018-09-11
      • 1970-01-01
      • 1970-01-01
      • 2021-02-08
      • 1970-01-01
      • 2016-03-12
      • 1970-01-01
      • 2017-08-04
      相关资源
      最近更新 更多