def _slow_path(self):
"""Frisch-Waugh-Lovell implementation, works for all scenarios"""
has_effect = self.entity_effects or self.time_effects or self.other_effects
w = self.weights.values2d
root_w = np.sqrt(w)
y = root_w * self.dependent.values2d
x = root_w * self.exog.values2d
if not has_effect:
ybar = root_w @ lstsq(root_w, y)[0]
return y, x, ybar, 0, 0
drop_first = self._constant
d = []
if self.entity_effects:
d.append(self.dependent.dummies('entity', drop_first=drop_first).values)
drop_first = True
if self.time_effects:
d.append(self.dependent.dummies('time', drop_first=drop_first).values)
drop_first = True
if self.other_effects:
oe = self._other_effect_cats.dataframe
for c in oe:
dummies = pd.get_dummies(oe[c], drop_first=drop_first).astype(np.float64)
d.append(dummies.values)
drop_first = True
d = np.column_stack(d)
wd = root_w * d
if self.has_constant:
wd -= root_w * (w.T @ d / w.sum())
z = np.ones_like(root_w)
d -= z * (z.T @ d / z.sum())
x_mean = np.linalg.lstsq(wd, x)[0]
y_mean = np.linalg.lstsq(wd, y)[0]
# Save fitted unweighted effects to use in eps calculation
x_effects = d @ x_mean
y_effects = d @ y_mean
# Purge fitted, weighted values
x = x - wd @ x_mean
y = y - wd @ y_mean
ybar = root_w @ lstsq(root_w, y)[0]
return y, x, ybar, y_effects, x_effects
评论列表
文章目录