-
Notifications
You must be signed in to change notification settings - Fork 0
/
ICOMP.py
64 lines (57 loc) · 2.03 KB
/
ICOMP.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import numpy as np
import statsmodels.api as sm
from scipy.stats import gmean
from scipy.linalg import solve
# from sklearn.kernel_ridge import KernelRidge
# from sklearn.metrics.pairwise import pairwise_kernels
def icomp_penalty(cov, method='approx'):
# used with -2*pll+2*icomp
var = np.diag(cov)
if method == 'exact' or len(var) == 1:
if len(var) > 1:
dv = np.linalg.det(cov)
else:
dv = float(var)
icomp = (np.log(var).sum()-np.log(dv))/2
else:
ev = np.linalg.eigvals(cov)
gm = gmean(ev).real
am = np.mean(ev).real
icomp = len(var)*np.log(np.divide(am, gm))/2
return icomp
def OLS_icomp(X, y, X_cov=None):
if X_cov is None:
X_cov = np.cov(X)
ols_res = sm.OLS(y, X).fit()
pll = ols_res.llf
icomp = icomp_penalty(X_cov, method='approx')
return 2*(icomp-pll)
class KRR(object):
def __init__(self, alpha=0.1):
self.alpha = alpha
self.nobs = None
self.A = None
self.dual_coef_ = None
self.train_residual = None
self.pll = self.kic_1 = self.kic_2 = None
# K = pairwise_kernels(X, metric='rbf')
def fit(self, K, y):
self.nobs = len(y)
self.A = K + self.alpha * np.eye(len(K))
self.dual_coef_ = solve(self.A, y, assume_a='sym')
self.train_residual = y - self.predict(K)
self.kic(K, self.dual_coef_, self.train_residual, self.A)
return self
def predict(self, K):
return np.dot(K, self.dual_coef_)
def kic(self, K, theta, y_res, A):
nobs2 = self.nobs/2
var = np.dot(y_res, y_res)
tKt = theta.dot(K).dot(theta)
ss = (var + self.alpha*tKt)/self.nobs
# A = np.linalg.inv(A)
A = np.linalg.pinv(A, hermitian=True)
sigma_theta = K.dot(A.dot(A))
self.pll = -nobs2*np.log(2*np.pi*ss)-(var+self.alpha*tKt)/(2*ss)
self.kic_1 = -2*self.pll+ss*np.trace(sigma_theta)
self.kic_2 = -2*self.pll+ss*np.trace(sigma_theta.dot(sigma_theta))