Пример #1
0
def _compute_betas(y, x):
    """
    compute MLE coefficients using iwls routine

    Methods: p189, Iteratively (Re)weighted Least Squares (IWLS),
    Fotheringham, A. S., Brunsdon, C., & Charlton, M. (2002).
    Geographically weighted regression: the analysis of spatially varying relationships.
    """
    xT = x.T
    xtx = spdot(xT, x)
    xtx_inv = la.inv(xtx)
    xtx_inv = sp.csr_matrix(xtx_inv)
    xTy = spdot(xT, y, array_out=False)
    betas = spdot(xtx_inv, xTy)
    return betas
Пример #2
0
def logp_lambda_prec(state, val):
    """
    Compute the log likelihood of the upper-level spatial correlation parameter using 
    sparse operations and the precision matrix, rather than the covariance matrix. 
    """
    st = state

    if (val < st.Lambda_min) or (val > st.Lambda_max):
        return np.array([-np.inf])

    PsiLambdai = st.Psi_2i(val, st.M, sparse=True)
    logdet = -splogdet(PsiLambdai) #negative because precision

    kernel = spdot(spdot(st.Alphas.T, PsiLambdai), st.Alphas) / st.Tau2

    return -.5 * logdet - .5 * kernel + st.Log_Lambda0(val)
Пример #3
0
def iwls(y,
         x,
         family,
         offset,
         y_fix,
         ini_betas=None,
         tol=1.0e-8,
         max_iter=200,
         wi=None):
    """
    Iteratively re-weighted least squares estimation routine
    """
    n_iter = 0
    diff = 1.0e6

    if ini_betas is None:
        betas = np.zeros((x.shape[1], 1), np.float)
    else:
        betas = ini_betas

    if isinstance(family, Binomial):
        y = family.link._clean(y)
    if isinstance(family, Poisson):
        y_off = y / offset
        y_off = family.starting_mu(y_off)
        v = family.predict(y_off)
        mu = family.starting_mu(y)
    else:
        mu = family.starting_mu(y)
        v = family.predict(mu)

    while diff > tol and n_iter < max_iter:
        n_iter += 1
        w = family.weights(mu)
        z = v + (family.link.deriv(mu) * (y - mu))
        w = np.sqrt(w)
        if type(x) != np.ndarray:
            w = sp.csr_matrix(w)
            z = sp.csr_matrix(z)
        wx = spmultiply(x, w, array_out=False)
        wz = spmultiply(z, w, array_out=False)
        if wi is None:
            n_betas = _compute_betas(wz, wx)
        else:
            n_betas, xtx_inv_xt = _compute_betas_gwr(wz, wx, wi)
        v = spdot(x, n_betas)
        mu = family.fitted(v)

        if isinstance(family, Poisson):
            mu = mu * offset

        diff = min(abs(n_betas - betas))
        betas = n_betas

    if wi is None:
        return betas, mu, wx, n_iter
    else:
        return betas, mu, v, w, z, xtx_inv_xt, n_iter
Пример #4
0
def logp_rho_prec(state, val):
    """
    Compute the log likelihood of the lower-level spatial correlation parameter using
    sparse operations and the precision matrix, rather than the covariance matrix. 
    """
    st = state

    if (val < st.Rho_min) or (val > st.Rho_max):
        return np.array([-np.inf])

    PsiRhoi = st.Psi_1i(val, st.W, sparse=True)
    logdet = -splogdet(PsiRhoi)

    eta = st.Y - st.XBetas - st.DeltaAlphas

    kernel = spdot(spdot(eta.T, PsiRhoi), eta) / st.Sigma2

    return -.5 * logdet - .5 * kernel + st.Log_Rho0(val)
Пример #5
0
def logp_rho_prec(state, val):
    """
    This computes the logp of the spatial parameter using the precision, rather than the covariance. This results in fewer matrix operations in the case of a SE formulation, but not in an SMA formulation.
    """
    st = state

    #must truncate in logp otherwise sampling gets unstable
    if (val < st.Rho_min) or (val > st.Rho_max):
        return np.array([-np.inf])

    PsiRhoi = st.Psi_1i(val, st.W, sparse=True)
    logdet = splogdet(PsiRhoi)

    eta = st.Y - st.XBetas - st.DeltaAlphas
    kernel = spdot(spdot(eta.T, PsiRhoi), eta) / st.Sigma2

    return .5 * logdet - .5 * kernel + st.Log_Rho0(
        val)  #since precision, no negative on ld
Пример #6
0
def logp_lambda_prec(state, val):
    """
    The logp for upper level spatial parameters in this case has the same form
    as a multivariate normal distribution, sampled over the variance matrix,
    rather than over Y.
    """
    st = state

    #must truncate
    if (val < st.Lambda_min) or (val > st.Lambda_max):
        return np.array([-np.inf])

    PsiLambdai = st.Psi_2i(val, st.M)
    logdet = splogdet(PsiLambdai)

    kernel = spdot(spdot(st.Alphas.T, PsiLambdai), st.Alphas) / st.Tau2

    return .5 * logdet - .5 * kernel + st.Log_Lambda0(val)
Пример #7
0
def iwls(y, x, family, offset, y_fix,
    ini_betas=None, tol=1.0e-8, max_iter=200, wi=None):
    """
    Iteratively re-weighted least squares estimation routine
    """
    n_iter = 0
    diff = 1.0e6
    
    if ini_betas is None:
        betas = np.zeros((x.shape[1], 1), np.float)
    else:
        betas = ini_betas

    if isinstance(family, Binomial):
        y = family.link._clean(y)
    if isinstance(family, Poisson):
        y_off = y/offset
        y_off = family.starting_mu(y_off)
        v = family.predict(y_off)
        mu = family.starting_mu(y)
    else:
        mu = family.starting_mu(y)
        v = family.predict(mu)

    while diff > tol and n_iter < max_iter:
        n_iter += 1
        w = family.weights(mu)
        z = v + (family.link.deriv(mu)*(y-mu))
        w = np.sqrt(w)
        if type(x) != np.ndarray:
            w = sp.csr_matrix(w)
            z = sp.csr_matrix(z)
        wx = spmultiply(x, w, array_out=False)
        wz = spmultiply(z, w, array_out=False)
        if wi is None:
            n_betas = _compute_betas(wz, wx)
        else:
            n_betas, xtx_inv_xt = _compute_betas_gwr(wz, wx, wi)
        v = spdot(x, n_betas)
        mu  = family.fitted(v)

        if isinstance(family, Poisson):
            mu = mu * offset

        diff = min(abs(n_betas-betas))
        betas = n_betas

    if wi is None:
        return betas, mu, wx, n_iter
    else:
        return betas, mu, v, w, z, xtx_inv_xt, n_iter
Пример #8
0
 def __init__(self, model, params, mu, w):
     self.model = model
     self.n = model.n
     self.y = model.y.T.flatten()
     self.X = model.X
     self.k = model.k
     self.offset = model.offset
     self.df_model = model.df_model
     self.df_resid = model.df_resid
     self.family = model.family
     self.fit_params = model.fit_params
     self.params = params
     self.w = w
     self.mu = mu.flatten()
     self._cache = {}
     self.normalized_cov_params = la.inv(spdot(self.w.T, self.w))
Пример #9
0
 def __init__(self, model, params, mu, w):
     self.model = model
     self.n = model.n
     self.y = model.y.T.flatten()
     self.X = model.X
     self.k = model.k
     self.offset = model.offset
     self.df_model = model.df_model
     self.df_resid = model.df_resid
     self.family = model.family
     self.fit_params = model.fit_params
     self.params = params
     self.w = w
     self.mu = mu.flatten()
     self._cache = {}
     self.normalized_cov_params = la.inv(spdot(self.w.T, self.w))
Пример #10
0
def logp_rho_cov(state, val):
    """
    The logp for lower-level spatial parameters in this case has the same
    form as a multivariate normal distribution, sampled over the variance matrix, rather than over y.
    """
    st = state
    
    #must truncate in logp otherwise sampling gets unstable
    if (val < st.Rho_min) or (val > st.Rho_max):
        return np.array([-np.inf])
    
    PsiRho = st.Psi_1(val, st.W)
    logdet = splogdet(PsiRho)
    
    eta = st.Y - st.XBetas - st.DeltaAlphas
    kernel = spdot(eta.T, spsolve(PsiRho, eta)) / st.Sigma2

    return -.5*logdet -.5 * kernel + st.Log_Rho0(val)
Пример #11
0
 def normalized_cov_params(self):
     return la.inv(spdot(self.w.T, self.w))
 def normalized_cov_params(self):
     return la.inv(spdot(self.w.T, self.w))
Пример #13
0
    def _iteration(self):
        st = self.state

        ### Sample the Beta conditional posterior
        ### P(beta | . ) \propto L(Y|.) \dot P(\beta)
        ### is
        ### N(Sb, S) where
        ### S = (X' Sigma^{-1}_Y X + S_0^{-1})^{-1}
        ### b = X' Sigma^{-1}_Y (Y - Delta Alphas) + S^{-1}\mu_0
        covm_update = st.X.T.dot(st.X) / st.Sigma2
        covm_update += st.Betas_cov0i
        covm_update = la.inv(covm_update)

        resids = st.Y - st.Delta.dot(st.Alphas)
        XtSresids = st.X.T.dot(resids) / st.Sigma2
        mean_update = XtSresids + st.Betas_cov0i.dot(st.Betas_mean0)
        mean_update = np.dot(covm_update, mean_update)
        st.Betas = chol_mvn(mean_update, covm_update)
        st.XBetas = np.dot(st.X, st.Betas)

        ### Sample the Random Effect conditional posterior
        ### P( Alpha | . ) \propto L(Y|.) \dot P(Alpha | \lambda, Tau2)
        ###                               \dot P(Tau2) \dot P(\lambda)
        ### is
        ### N(Sb, S)
        ### Where
        ### S = (Delta'Sigma_Y^{-1}Delta + Sigma_Alpha^{-1})^{-1}
        ### b = (Delta'Sigma_Y^{-1}(Y - X\beta) + 0)
        covm_update = st.Delta.T.dot(st.Delta) / st.Sigma2
        covm_update += st.PsiLambdai / st.Tau2
        covm_update = np.asarray(covm_update)
        covm_update = la.inv(covm_update)

        resids = st.Y - st.XBetas
        mean_update = st.Delta.T.dot(resids) / st.Sigma2
        mean_update = np.dot(covm_update, mean_update)
        mean_update = np.asarray(mean_update)
        st.Alphas = chol_mvn(mean_update, covm_update)
        st.DeltaAlphas = np.dot(st.Delta, st.Alphas)

        ### Sample the Random Effect aspatial variance parameter
        ### P(Tau2 | .) \propto L(Y|.) \dot P(\Alpha | \lambda, Tau2)
        ###                            \dot P(Tau2) \dot P(\lambda)
        ### is
        ### IG(J/2 + a0, u'(\Psi(\lambda))^{-1}u * .5 + b0)
        bn = spdot(st.Alphas.T, spdot(st.PsiLambdai,
                                      st.Alphas)) * .5 + st.Tau2_b0
        st.Tau2 = stats.invgamma.rvs(st.Tau2_an, scale=bn)

        ### Sample the response aspatial variance parameter
        ### P(Sigma2 | . ) \propto L(Y | .) \dot P(Sigma2)
        ### is
        ### IG(N/2 + a0, eta'Psi(\rho)^{-1}eta * .5 + b0)
        ### Where eta is the linear predictor, Y - X\beta + \DeltaAlphas
        eta = st.Y - st.XBetas - st.DeltaAlphas
        bn = eta.T.dot(eta) * .5 + st.Sigma2_b0
        st.Sigma2 = stats.invgamma.rvs(st.Sigma2_an, scale=bn)

        ### P(Psi(\rho) | . ) \propto L(Y | .) \dot P(\rho)
        ### is
        ### |Psi(rho)|^{-1/2} exp(1/2(eta'Psi(rho)^{-1}eta * Sigma2^{-1})) * 1/(emax-emin)
        st.Lambda = self.configs.Lambda(st)
        st.PsiLambdai = st.Psi_2i(st.Lambda, st.M)