Source code for psy.fa.rotations

# coding=utf-8
import numpy as np


[docs]class GPForth(object): # 基于正交梯度投影算法的因子旋转 def __init__(self, init_loadings, method='varimax'): self._init_loadings = init_loadings self._method = method
[docs] def solve(self): init_loadings = self._init_loadings t_mat = np.eye(init_loadings.shape[1]) method = getattr(self, self._method) al = 1 l = np.dot(init_loadings, t_mat) f, gq = method(l) g = np.dot(init_loadings.transpose(), gq) for i in range(500): m = np.dot(t_mat.transpose(), g) s = (m + m.transpose()) / 2 gp = g - np.dot(t_mat, s) s = np.sum(np.diag(np.dot(gp, gp.transpose()))) ** 0.5 if s < 1e-5: break al = 2 * al for j in range(10): x = t_mat - al * gp u, d, v = np.linalg.svd(x) t_mat_temp = np.dot(u, v) l = np.dot(init_loadings, t_mat_temp) f_temp, gq_temp = method(l) if f_temp < (f - 0.5 * s ** 2 * al): break al = al / 2.0 t_mat = t_mat_temp f = f_temp g = np.dot(init_loadings.transpose(), gq_temp) return l
[docs] @staticmethod def varimax(l): # varimax旋转 mean = np.mean(l ** 2, axis=0) mean.shape = 1, mean.shape[0] ql = l ** 2 - mean f = -1. * np.sum(np.diag(np.dot(ql.transpose(), ql))) / 4 gq = -1. * l * ql return f, gq