Skip to content

Commit

Permalink
Merge pull request #130 from martinfleis/summary_names
Browse files Browse the repository at this point in the history
allow custom variable names in summary
  • Loading branch information
weikang9009 authored Nov 2, 2023
2 parents d9c8aaf + cff904a commit 85e30c6
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 17 deletions.
44 changes: 33 additions & 11 deletions mgwr/gwr.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ class GWR(GLM):
True to store full n by n hat matrix,
False to not store full hat matrix to minimize memory footprint (defalut).
name_x : list of strings
Names of independent variables for use in output
Attributes
----------
coords : array-like
Expand Down Expand Up @@ -207,7 +210,7 @@ class GWR(GLM):

def __init__(self, coords, y, X, bw, family=Gaussian(), offset=None,
sigma2_v1=True, kernel='bisquare', fixed=False, constant=True,
spherical=False, hat_matrix=False):
spherical=False, hat_matrix=False, name_x=None):
"""
Initialize class
"""
Expand All @@ -230,9 +233,10 @@ def __init__(self, coords, y, X, bw, family=Gaussian(), offset=None,
self.P = None
self.spherical = spherical
self.hat_matrix = hat_matrix
self.name_x = name_x

def _build_wi(self, i, bw):

if bw == np.inf:
wi = np.ones((self.n))
return wi
Expand Down Expand Up @@ -354,7 +358,7 @@ def fit(self, ini_params=None, tol=1.0e-5, max_iter=20, solve='iwls',
tr_STS = np.sum(np.array(rslt_list[-2]))
CCT = np.array(rslt_list[-1])
return GWRResults(self, params, predy, S, CCT, influ, tr_STS,
w)
w, self.name_x)


def predict(self, points, P, exog_scale=None, exog_resid=None,
Expand Down Expand Up @@ -437,6 +441,9 @@ class GWRResults(GLMResults):
n*1, final weight used for iteratively re-weighted least
sqaures; default is None
name_x : list of strings
Names of independent variables for use in output
Attributes
----------
model : GWR Object
Expand Down Expand Up @@ -602,10 +609,13 @@ class GWRResults(GLMResults):
p*1, predicted values generated by calling the GWR
predict method to predict dependent variable at
unsampled points ()
name_x : list of strings
Names of independent variables for use in output
"""

def __init__(self, model, params, predy, S, CCT, influ, tr_STS=None,
w=None):
w=None, name_x=None):
GLMResults.__init__(self, model, params, predy, w)
self.offset = model.offset
if w is not None:
Expand All @@ -616,6 +626,7 @@ def __init__(self, model, params, predy, S, CCT, influ, tr_STS=None,
self.influ = influ
self.CCT = self.cov_params(CCT, model.exog_scale)
self._cache = {}
self.name_x=name_x

@cache_readonly
def W(self):
Expand Down Expand Up @@ -1265,10 +1276,10 @@ def summary(self, as_str: bool = False) -> Optional[str]:
optional GWR summary string if `as_str` is True
"""
summary = summaryModel(self) + summaryGLM(self) + summaryGWR(self)

if as_str:
return summary

print(summary)
return None

Expand Down Expand Up @@ -1399,6 +1410,9 @@ class MGWR(GWR):
hat matrices R (n,n,k) and model hat matrix S (n,n).
False (default) for computing MGWR inference on the fly.
name_x : list of strings
Names of independent variables for use in output
Attributes
----------
coords : array-like
Expand Down Expand Up @@ -1475,6 +1489,9 @@ class MGWR(GWR):
observations from each calibration point: one for each
covariate (k)
name_x : list of strings
Names of independent variables for use in output
Examples
--------
Expand Down Expand Up @@ -1504,7 +1521,7 @@ class MGWR(GWR):

def __init__(self, coords, y, X, selector, sigma2_v1=True,
kernel='bisquare', fixed=False, constant=True,
spherical=False, hat_matrix=False):
spherical=False, hat_matrix=False, name_x=None):
"""
Initialize class
"""
Expand All @@ -1526,6 +1543,7 @@ def __init__(self, coords, y, X, selector, sigma2_v1=True,
self.exog_resid = None
self.exog_scale = None
self_fit_params = None
self.name_x = name_x

def _chunk_compute_R(self, chunk_id=0):
"""
Expand Down Expand Up @@ -1628,7 +1646,7 @@ def tqdm(x, total=0,
R = np.hstack(rslt_list[2])
else:
R = None
return MGWRResults(self, params, predy, CCT, ENP_j, w, R)
return MGWRResults(self, params, predy, CCT, ENP_j, w, R, self.name_x)


def exact_fit(self):
Expand Down Expand Up @@ -1713,6 +1731,9 @@ class MGWRResults(GWRResults):
n*1, final weight used for iteratively re-weighted least
sqaures; default is None
name_x : list of strings
Names of independent variables for use in output
Attributes
----------
model : GWR Object
Expand Down Expand Up @@ -1850,7 +1871,7 @@ class MGWRResults(GWRResults):
"""

def __init__(self, model, params, predy, CCT, ENP_j, w, R):
def __init__(self, model, params, predy, CCT, ENP_j, w, R, x_name=None):
"""
Initialize class
"""
Expand All @@ -1860,6 +1881,7 @@ def __init__(self, model, params, predy, CCT, ENP_j, w, R):
if model.hat_matrix:
self.S = np.sum(self.R, axis=2)
self.predy = predy
self.x_name = x_name

@cache_readonly
def tr_S(self):
Expand Down Expand Up @@ -2150,9 +2172,9 @@ def summary(self, as_str: bool=False) -> Optional[str]:
optional MGWR summary string if `as_str` is True
"""
summary = summaryModel(self) + summaryGLM(self) + summaryMGWR(self)

if as_str:
return summary

print(summary)
return
29 changes: 23 additions & 6 deletions mgwr/summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ def summaryModel(self):

def summaryGLM(self):

XNames = ["X" + str(i) for i in range(self.k)]
if self.name_x is not None:
XNames = list(self.name_x)
if len(XNames) < self.k:
XNames = ["Intercept"] + XNames
else:
XNames = ["X" + str(i) for i in range(self.k)]
glm_rslt = GLM(self.model.y, self.model.X, constant=False,
family=self.family).fit()

Expand Down Expand Up @@ -47,14 +52,20 @@ def summaryGLM(self):
'-' * 10, '-' * 10)
for i in range(self.k):
summary += "%-31s %10.3f %10.3f %10.3f %10.3f\n" % (
XNames[i], glm_rslt.params[i], glm_rslt.bse[i],
XNames[i][:30], glm_rslt.params[i], glm_rslt.bse[i],
glm_rslt.tvalues[i], glm_rslt.pvalues[i])
summary += "\n"
return summary


def summaryGWR(self):
XNames = ["X" + str(i) for i in range(self.k)]
if self.name_x is not None:
XNames = list(self.name_x)
if len(XNames) < self.k:
XNames = ["Intercept"] + XNames

else:
XNames = ["X" + str(i) for i in range(self.k)]

summary = "%s\n" % ('Geographically Weighted Regression (GWR) Results')
summary += '-' * 75 + '\n'
Expand Down Expand Up @@ -111,7 +122,7 @@ def summaryGWR(self):
'-' * 20, '-' * 10, '-' * 10, '-' * 10, '-' * 10, '-' * 10)
for i in range(self.k):
summary += "%-20s %10.3f %10.3f %10.3f %10.3f %10.3f\n" % (
XNames[i], np.mean(self.params[:, i]), np.std(self.params[:, i]),
XNames[i][:20], np.mean(self.params[:, i]), np.std(self.params[:, i]),
np.min(self.params[:, i]), np.median(self.params[:, i]),
np.max(self.params[:, i]))

Expand All @@ -122,7 +133,13 @@ def summaryGWR(self):

def summaryMGWR(self):

XNames = ["X" + str(i) for i in range(self.k)]
if self.name_x is not None:
XNames = list(self.name_x)
if len(XNames) < self.k:
XNames = ["Intercept"] + XNames

else:
XNames = ["X" + str(i) for i in range(self.k)]

summary = ''
summary += "%s\n" % (
Expand Down Expand Up @@ -182,7 +199,7 @@ def summaryMGWR(self):
'-' * 20, '-' * 10, '-' * 10, '-' * 10, '-' * 10, '-' * 10)
for i in range(self.k):
summary += "%-20s %10.3f %10.3f %10.3f %10.3f %10.3f\n" % (
XNames[i], np.mean(self.params[:, i]), np.std(self.params[:, i]),
XNames[i][:20], np.mean(self.params[:, i]), np.std(self.params[:, i]),
np.min(self.params[:, i]), np.median(self.params[:, i]),
np.max(self.params[:, i]))

Expand Down

0 comments on commit 85e30c6

Please sign in to comment.