def minvar_nls_oracle(sim, isotonic=False, trace=False, upper_bound=True): """Oracle eigenvalues for new MinVar nonlinear shrinkage""" T, N = sim.shape U, Sigma = sim.U, sim.Sigma lam = sim.lam alpha = U.T.dot(np.ones(N)) C = U.T.dot(Sigma).dot(U) if isotonic: # Solve non-linear problem with monotonicity constraints d_min, d_max = lam[-1], lam[0] _, d_kfold = nls_kfold(sim) d_isokfold = isotonic_regression(d_kfold) if trace: trace = np.sum(d_isokfold) d = minvar_nls_nlsq_multi_transformed([C], [alpha], trace, d_isokfold, d_min, d_max, upper_bound) else: trace = None d = minvar_nls_nlsq_multi([C], [alpha], trace, d_isokfold, d_min, d_max, upper_bound) else: # Solve plain vanilla linear system A = C * alpha z = np.linalg.solve(A, alpha) d = 1. / z return d
def nls_oracle(sim, isotonic=False, **kwargs): """Oracle eigenvalues for LW nonlinear shrinkage""" T, N = sim.shape U = sim.U Sig = sim.Sigma d = np.zeros(N) for i in range(N): u_i = U[:, i] d[i] = u_i.T.dot(Sig).dot(u_i) d_min, d_max = sim.lam_N, sim.lam_1 return isotonic_regression(d, y_min=d_min, y_max=d_max) if isotonic else d
def minvar_nls_kfold_oracle(sim, K=10, progress=False, trace=False, upper_bound=True): """ Oracle/K-fold cross-validated eigenvalues for new MinVar nonlinea shrinkage. """ T, N = sim.shape S, Sigma = sim.S, sim.Sigma X = sim.X lam = sim.lam m = int(T / K) C_list = [] alpha_list = [] if progress: pbar = tqdm(total=K) for k in range(K): k_set = list(range(k * m, (k + 1) * m)) X_k = X[k_set, :] S_k = (T * S - X_k.T.dot(X_k)) / (T - m) _, U_k = eig(S_k) C = U_k.T.dot(Sigma).dot(U_k) C_list.append(C) alpha = U_k.T.dot(np.ones(N)) alpha_list.append(alpha) if progress: pbar.update() d_min, d_max = lam[-1], lam[0] d_kfold = nls_kfold(sim, K) d_isokfold = isotonic_regression(d_kfold) if trace: trace = np.sum(d_isokfold) d = minvar_nls_nlsq_multi_transformed(C_list, alpha_list, trace, d_isokfold, d_min, d_max, upper_bound) else: trace = None d = minvar_nls_nlsq_multi(C_list, alpha_list, trace, d_isokfold, d_min, d_max, upper_bound) return d
def minvar_joint_kfold_isotonic(sim, K, smoothing='average', nonnegative=False, regularization=None): """ Base Estimator 4: MinVar $K$-Fold Joint Cross-Validation with Isotonic Regression Parameters: + K Variants: + Smoothing could be average or median. + Nonnegativity constraint + Regularization: 'l2' for now, maybe others """ T, N = sim.shape m = int(T / K) X, S = sim.X, sim.S P = np.zeros((N, N)) q = np.zeros(N) for k in range(K): k_set = list(range(k * m, (k + 1) * m)) _k = np.delete(range(T), k_set) X_k = X[k_set, :] S_k = (T * S - X_k.T @ X_k) / (T - m) # 1/(T-m) * X[_k,:].T @ X[_k,:] _, U_k = eig(S_k) alpha_k = U_k.T @ np.ones(N) C_k = U_k.T @ (1 / m * X_k.T @ X_k) @ U_k A_k = np.diag(alpha_k) P = P + (A_k @ C_k.T @ C_k @ A_k) q = q + (A_k @ C_k.T @ alpha_k) if nonnegative: z = nnlsq_regularized(P, -q, lmbda=0) interpolate_zeros(z) else: z = np.linalg.solve(P, -q) d = 1 / z d = isotonic_regression(d) return d
def minvar_nls_kfold(sim, K, progress=False, trace=False, upper_bound=True): """K-fold cross-validated eigenvalues for new MinVar nonlinear shrinkage""" T, N = sim.shape m = int(T / K) X, S, lam = sim.X, sim.S, sim.lam C_list = [] alpha_list = [] if progress: pbar = tqdm(total=K) for k in range(K): k_set = list(range(k * m, (k + 1) * m)) X_k = X[k_set, :] S_k = (T * S - X_k.T.dot(X_k)) / (T - m) _, U_k = eig(S_k) # this is a joint version. Lists of C and alpha are collected # and the system is solved for one z vector. z is not averaged here # Note that this is also a bona-fide estimator since in C calculation # sample covariance matrix is used. C = U_k.T.dot(X_k.T.dot(X_k)).dot(U_k) C_list.append(C) alpha = U_k.T.dot(np.ones(N)) alpha_list.append(alpha) if progress: pbar.update() d_min, d_max = lam[-1], lam[0] d_kfold = nls_kfold(sim, K) d_isokfold = isotonic_regression(d_kfold) if trace: trace = np.sum(d_isokfold) d = minvar_nls_nlsq_multi_transformed(C_list, alpha_list, trace, d_isokfold, d_min, d_max, upper_bound) else: trace = None d = minvar_nls_nlsq_multi(C_list, alpha_list, trace, d_isokfold, d_min, d_max, upper_bound) return d
def nls_kfold(sim, K=10, isotonic=False, **kwargs): """K-fold cross-validated eigenvalues for LW nonlinear shrinkage""" d = _nls_cv(sim, K) d_min, d_max = sim.lam_N, sim.lam_1 return isotonic_regression(d, y_min=d_min, y_max=d_max) if isotonic else d
def nls_asymptotic(sim, isotonic=False): X = sim.X S_lw = nlshrink_covariance(X, centered=True) d = eig(S_lw, return_eigenvectors=False) return isotonic_regression(d) if isotonic else d