Python中的维度减少(定义方差阈值)

时间:2017-03-10 23:32:41

标签: arrays numpy iteration linear-algebra python-3.6

下午。我的脚本遇到了一些问题。具体地,当特征值的子集的总和大于.9 *所有特征值的总和时,我想保持奇异值及其对应的特征向量。到目前为止,Iv已经能够使用for循环和追加函数来创建表示奇异值和特征向量的元组列表。但是,当我尝试在for循环中嵌套if语句以满足条件时我会破坏它。这是我的代码。

o = np.genfromtxt (r"C:\Users\Python\Desktop\PCADUMMYDATADUMP.csv", delimiter=",")
o_m=np.matrix(o)

#We define the covariance matrix of our data accordingly  This is the mean centered data approx
#of the covariance matrix.  
def covariance_matrix(x):
    #create the mean centered data matrix.  this is the data matrix minus the matrix augmented from the vector that represents the column average
    m_c_d=x-np.repeat(np.mean(x, axis=0,), len(x), axis=0)
    #we compute the matrix operations here
    m_c_c=np.multiply(1/((len(m_c_d)-1)),np.transpose(m_c_d)*m_c_d)
    return m_c_c



#Define the correlation matrix for our mean adjsuted data matrix
def correlation_matrix(x):
    C_M = covariance_matrix(x)
    #matrix operation is diagonal(covariance_matrix)^-1/2*(covaraince_matrix)*diagonal(covariance_matrix)^-1/2
    c_m=fractional_matrix_power(np.diag(np.diag(C_M)),-1/2)*C_M*fractional_matrix_power(np.diag(np.diag(C_M)),-1/2)
    return c_m


def s_v_d(x):
    C_M=covariance_matrix(x)
    #create arrays that hold the left singular vectors(u), the right singular vectors(v), and the singular values (s)
    u,s,v=np.linalg.svd(C_M)
    #not sure if we should keep this here but this is how we can grab the eigenvalues which are the sqares of the singular values
    eigenvalues=np.square(s)

    singular_array=[]
    for i in range(0,len(s)-1):
        if np.sum(singular_array,axis=1) < (.9*np.sum(s)):
            singular_pairs=[s[i],v[:,i]]
            singular_array.append(singular_pairs)
        else:
            break

    return np.sum(s,axis=0)

具体来说,考虑奇异[array]之后的for和if循环。谢谢!

1 个答案:

答案 0 :(得分:0)

我认为你的singular_array和#34;混合了#34;标量/向量元素比np.sum能够处理的要多一些。我不是百分百肯定,但不是奇异值的平方的方差吗?换句话说,您不应该使用eigenvalues作出决定吗?

无论如何,这是一个非循环的方法:

part_sums = np.cumsum(eigenvalues)
cutoff = np.searchsorted(part_sums, 0.9 * part_sums[-1])
singular_array = list(zip(s[:cutoff], v[:, :cutoff]))

如果您认为它更合适,请将eigenvalues更改为s

工作原理:

cumsum计算eigenvalues上的运行总和。因此,它的最后一个元素是总和,我们只需要找到part_sums超过90%的地方。这就是searchsorted为我们做的事情。

一旦我们得到了截止值,剩下的就是将它应用于奇异值和向量,并使用zip形成对。