Skip to content

Commit 6e34f5d

Browse files
committed
regress now returns standard error from betas. stored as sigma in results dicts
1 parent d9f65ba commit 6e34f5d

File tree

4 files changed

+52
-21
lines changed

4 files changed

+52
-21
lines changed

nltools/data/adjacency.py

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,24 +1331,30 @@ def regress(self, X, mode="ols", **kwargs):
13311331
if isinstance(X, Adjacency):
13321332
if X.square_shape()[0] != self.square_shape()[0]:
13331333
raise ValueError("Adjacency instances must be the same size.")
1334-
b, t, p, _, res = regression(X.data.T, self.data, mode=mode, **kwargs)
1335-
stats["beta"], stats["t"], stats["p"], stats["residual"] = (b, t, p, res)
1334+
(
1335+
stats["beta"],
1336+
stats["sigma"],
1337+
stats["t"],
1338+
stats["p"],
1339+
stats["df"],
1340+
stats["residual"],
1341+
) = regression(X.data.T, self.data, mode=mode, **kwargs)
13361342
elif isinstance(X, Design_Matrix):
13371343
if X.shape[0] != len(self):
13381344
raise ValueError(
13391345
"Design matrix must have same number of observations as Adjacency"
13401346
)
1341-
b, t, p, df, res = regression(X, self.data, mode=mode, **kwargs)
1342-
mode = "ols"
1343-
stats["beta"], stats["t"], stats["p"] = [x for x in self[:3]]
1344-
stats["beta"].data, stats["t"].data, stats["p"].data = (
1345-
b.squeeze(),
1346-
t.squeeze(),
1347-
p.squeeze(),
1348-
)
1349-
stats["residual"] = self.copy()
1350-
stats["residual"].data = res
1351-
stats["df"] = df
1347+
(b, se, t, p, df, res) = regression(X, self.data, mode=mode, **kwargs)
1348+
1349+
stats["beta"], stats["sigma"], stats["t"] = [x for x in self[:3]]
1350+
stats["p"], stats["df"], stats["residual"] = [x for x in self[:3]]
1351+
1352+
stats["beta"].data = b.squeeze()
1353+
stats["sigma"].data = se.squeeze()
1354+
stats["t"].data = t.squeeze()
1355+
stats["p"].data = p.squeeze()
1356+
stats["df"].data = df.squeeze()
1357+
stats["residual"].data = res.squeeze()
13521358
else:
13531359
raise ValueError("X must be a Design_Matrix or Adjacency Instance.")
13541360

nltools/data/brain_data.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -693,31 +693,41 @@ def regress(self, mode="ols", **kwargs):
693693
if self.data.shape[0] != self.X.shape[0]:
694694
raise ValueError("self.X does not match the correct size of " "self.data")
695695

696-
b, t, p, _, res = regression(self.X, self.data, mode=mode, **kwargs)
696+
b, se, t, p, df, res = regression(self.X, self.data, mode=mode, **kwargs)
697697

698698
# Prevent copy of all data in self multiple times; instead start with an empty instance and copy only needed attributes from self, and use this as a template for other outputs
699699
b_out = self.__class__()
700700
b_out.mask = deepcopy(self.mask)
701701
b_out.nifti_masker = deepcopy(self.nifti_masker)
702702

703703
# Use this as template for other outputs before setting data
704+
se_out = b_out.copy()
704705
t_out = b_out.copy()
705706
p_out = b_out.copy()
706-
sigma_out = b_out.copy()
707+
df_out = b_out.copy()
707708
res_out = b_out.copy()
708-
b_out.data, t_out.data, p_out.data, sigma_out.data, res_out.data = (
709+
(
710+
b_out.data,
711+
se_out.data,
712+
t_out.data,
713+
p_out.data,
714+
df_out.data,
715+
res_out.data,
716+
) = (
709717
b,
718+
se,
710719
t,
711720
p,
712-
sigma_out,
721+
df,
713722
res,
714723
)
715724

716725
return {
717726
"beta": b_out,
718727
"t": t_out,
719728
"p": p_out,
720-
"sigma": sigma_out,
729+
"df": df_out,
730+
"sigma": se_out,
721731
"residual": res_out,
722732
}
723733

nltools/stats.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,14 +1012,18 @@ def regress(X, Y, mode="ols", stats="full", **kwargs):
10121012
Args:
10131013
X (ndarray): design matrix; assumes intercept is included
10141014
Y (ndarray): dependent variable array; if 2d, a model is fit to each column of Y separately
1015-
mode (str): kind of model to fit; must be one of 'ols' (default), 'robust', or 'arma'
1015+
mode (str): kind of model to fit; must be one of 'ols' (default), 'robust', or
1016+
'arma'
1017+
stats (str): one of 'full', 'betas', 'tstats'. Useful to speed up calculation if
1018+
you know you only need some statistics and not others. Defaults to 'full'.
10161019
robust_estimator (str,optional): kind of robust estimator to use if mode = 'robust'; default 'hc0'
10171020
nlags (int,optional): auto-correlation lag correction if mode = 'robust' and robust_estimator = 'hac'; default 1
10181021
order (tuple,optional): auto-regressive and moving-average orders for mode = 'arma'; default (1,1)
10191022
kwargs (dict): additional keyword arguments to statsmodels.tsa.arima_model.ARMA and joblib.Parallel
10201023
10211024
Returns:
10221025
b: coefficients
1026+
se: standard error of coefficients
10231027
t: t-statistics (coef/sterr)
10241028
p : p-values
10251029
df: degrees of freedom
@@ -1130,7 +1134,18 @@ def regress(X, Y, mode="ols", stats="full", **kwargs):
11301134
else:
11311135
b, t, p, df, res = _arma_func(X, Y, **kwargs)
11321136

1133-
return b.squeeze(), t.squeeze(), p.squeeze(), df.squeeze(), res.squeeze()
1137+
# Arma models don't return stderr, so make a variable for consistent function
1138+
# return values
1139+
stderr = np.empty_like(b)
1140+
1141+
return (
1142+
b.squeeze(),
1143+
stderr.squeeze(),
1144+
t.squeeze(),
1145+
p.squeeze(),
1146+
df.squeeze(),
1147+
res.squeeze(),
1148+
)
11341149

11351150

11361151
def regress_permutation(

nltools/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
"""Specifies current version of nltools to be used by setup.py and __init__.py
22
"""
33

4-
__version__ = "0.4.6"
4+
__version__ = "0.4.7"

0 commit comments

Comments
 (0)