如何在python中使用varimax旋转?

时间:2017-07-06 19:01:18

标签: python

我有来自维基百科的varimax旋转代码

def varimax(Phi, gamma = 1, q = 20, tol = 1e-6):
from numpy import eye, asarray, dot, sum, diag
from numpy.linalg import svd
p,k = Phi.shape
R = eye(k)
d=0
for i in xrange(q):
    d_old = d
    Lambda = dot(Phi, R)
    u,s,vh = svd(dot(Phi.T,asarray(Lambda)**3 - (gamma/p) * dot(Lambda, diag(diag(dot(Lambda.T,Lambda))))))
    R = dot(u,vh)
    d = sum(s)
    if d/d_old < tol: break
return dot(Phi, R)

我用这种方式:

  varimax(X)  ## X is a numpy array

但它会返回这样的数字:2.4243244e-15 !!那不是我预期的答案

我应该更改其他参数吗?例如gamma或q ?? 我不熟悉varimax旋转

1 个答案:

答案 0 :(得分:0)

您是否可以发布一个示例,说明您使用的内容作为X的输入以及您期望的输出类型?

我通过修复代码中的缩进来测试代码,如下所示:

from numpy import eye, asarray, dot, sum, diag
from numpy.linalg import svd

def varimax(Phi, gamma = 1, q = 20, tol = 1e-6):
    p,k = Phi.shape
    R = eye(k)
    d=0
    for i in xrange(q):
        d_old = d
        Lambda = dot(Phi, R)
        u,s,vh = svd(dot(Phi.T,asarray(Lambda)**3 - (gamma/p) * dot(Lambda, diag(diag(dot(Lambda.T,Lambda))))))
        R = dot(u,vh)
        d = sum(s)
        if d/d_old < tol: break
    return dot(Phi, R)

并制作一些虚拟组件来测试它:

import numpy as np

comps = np.linalg.svd(
    np.random.randn(100,10),
    full_matrices=False
    )[0]

rot_comps = varimax(comps)

print("Original components dimension {}".format(comps.shape))
print("Component norms")
print(np.sum(comps**2, axis=0))

print("Rotated components dimension {}".format(rot_comps.shape))
print("Rotated component norms")
print(np.sum(rot_comps**2, axis=0))

输入和输出是100 x 10阵列,具有单位规范,正如您所期望的那样。