Patsy offers a set of specific stateful transforms (for more details about stateful transforms see Stateful transforms) that you can use in formulas to generate splines bases and express non-linear fits.
B-spline bases can be generated with the bs() stateful transform. The spline bases returned by bs() are designed to be compatible with those produced by the R bs function. The following code illustrates a typical basis and the resulting spline:
In [3]: import matplotlib.pyplot as plt
In [4]: plt.title("B-spline basis example (degree=3)");
In [5]: x = np.linspace(0., 1., 100)
In [6]: y = dmatrix("bs(x, df=6, degree=3, include_intercept=True) - 1", {"x": x})
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-6-6a1672cd9508> in <module>()
----> 1 y = dmatrix("bs(x, df=6, degree=3, include_intercept=True) - 1", {"x": x})
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in dmatrix(formula_like, data, eval_env, NA_action, return_type)
276 eval_env = EvalEnvironment.capture(eval_env, reference=1)
277 (lhs, rhs) = _do_highlevel_design(formula_like, data, eval_env,
--> 278 NA_action, return_type)
279 if lhs.shape[1] != 0:
280 raise PatsyError("encountered outcome variables for a model "
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in _do_highlevel_design(formula_like, data, eval_env, NA_action, return_type)
150 return iter([data])
151 builders = _try_incr_builders(formula_like, data_iter_maker, eval_env,
--> 152 NA_action)
153 if builders is not None:
154 return build_design_matrices(builders, data,
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in _try_incr_builders(formula_like, data_iter_maker, eval_env, NA_action)
55 formula_like.rhs_termlist],
56 data_iter_maker,
---> 57 NA_action)
58 else:
59 return None
/tmp/buildd/patsy-0.3.0/patsy/build.py in design_matrix_builders(termlists, data_iter_maker, NA_action)
658 factor_states,
659 data_iter_maker,
--> 660 NA_action)
661 # Now we need the factor evaluators, which encapsulate the knowledge of
662 # how to turn any given factor into a chunk of data:
/tmp/buildd/patsy-0.3.0/patsy/build.py in _examine_factor_types(factors, factor_states, data_iter_maker, NA_action)
422 for data in data_iter_maker():
423 for factor in list(examine_needed):
--> 424 value = factor.eval(factor_states[factor], data)
425 if factor in cat_sniffers or guess_categorical(value):
426 if factor not in cat_sniffers:
/tmp/buildd/patsy-0.3.0/patsy/eval.py in eval(self, memorize_state, data)
483 # http://nedbatchelder.com/blog/200711/rethrowing_exceptions_in_python.html
484 def eval(self, memorize_state, data):
--> 485 return self._eval(memorize_state["eval_code"], memorize_state, data)
486
487 def test_EvalFactor_basics():
/tmp/buildd/patsy-0.3.0/patsy/eval.py in _eval(self, code, memorize_state, data)
466 self,
467 self._eval_env.eval,
--> 468 code, inner_namespace=inner_namespace)
469
470 def memorize_chunk(self, state, which_pass, data):
/tmp/buildd/patsy-0.3.0/patsy/compat.py in call_and_wrap_exc(msg, origin, f, *args, **kwargs)
115 def call_and_wrap_exc(msg, origin, f, *args, **kwargs):
116 try:
--> 117 return f(*args, **kwargs)
118 except Exception as e:
119 if sys.version_info[0] >= 3:
/tmp/buildd/patsy-0.3.0/patsy/eval.py in eval(self, expr, source_name, inner_namespace)
125 code = compile(expr, source_name, "eval", self.flags, False)
126 return eval(code, {}, VarLookupDict([inner_namespace]
--> 127 + self._namespaces))
128
129 @classmethod
<string> in <module>()
/tmp/buildd/patsy-0.3.0/patsy/splines.py in transform(self, x, df, knots, degree, include_intercept, lower_bound, upper_bound)
237 include_intercept=False,
238 lower_bound=None, upper_bound=None):
--> 239 basis = _eval_bspline_basis(x, self._all_knots, self._degree)
240 if not include_intercept:
241 basis = basis[:, 1:]
/tmp/buildd/patsy-0.3.0/patsy/splines.py in _eval_bspline_basis(x, knots, degree)
20 from scipy.interpolate import splev
21 except ImportError: # pragma: no cover
---> 22 raise ImportError("spline functionality requires scipy")
23 # 'knots' are assumed to be already pre-processed. E.g. usually you
24 # want to include duplicate copies of boundary knots; you should do
ImportError: spline functionality requires scipy
# Define some coefficients
In [7]: b = np.array([1.3, 0.6, 0.9, 0.4, 1.6, 0.7])
# Plot B-spline basis functions (colored curves) each multiplied by its coeff
In [8]: plt.plot(x, y*b);
# Plot the spline itself (sum of the basis functions, thick black curve)
In [9]: plt.plot(x, np.dot(y, b), color='k', linewidth=3);
In the following example we first set up our B-spline basis using some data and then make predictions on a new set of data:
In [10]: data = {"x": np.linspace(0., 1., 100)}
In [11]: design_matrix = dmatrix("bs(x, df=4)", data)
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-11-a9ab731d3d8f> in <module>()
----> 1 design_matrix = dmatrix("bs(x, df=4)", data)
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in dmatrix(formula_like, data, eval_env, NA_action, return_type)
276 eval_env = EvalEnvironment.capture(eval_env, reference=1)
277 (lhs, rhs) = _do_highlevel_design(formula_like, data, eval_env,
--> 278 NA_action, return_type)
279 if lhs.shape[1] != 0:
280 raise PatsyError("encountered outcome variables for a model "
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in _do_highlevel_design(formula_like, data, eval_env, NA_action, return_type)
150 return iter([data])
151 builders = _try_incr_builders(formula_like, data_iter_maker, eval_env,
--> 152 NA_action)
153 if builders is not None:
154 return build_design_matrices(builders, data,
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in _try_incr_builders(formula_like, data_iter_maker, eval_env, NA_action)
55 formula_like.rhs_termlist],
56 data_iter_maker,
---> 57 NA_action)
58 else:
59 return None
/tmp/buildd/patsy-0.3.0/patsy/build.py in design_matrix_builders(termlists, data_iter_maker, NA_action)
658 factor_states,
659 data_iter_maker,
--> 660 NA_action)
661 # Now we need the factor evaluators, which encapsulate the knowledge of
662 # how to turn any given factor into a chunk of data:
/tmp/buildd/patsy-0.3.0/patsy/build.py in _examine_factor_types(factors, factor_states, data_iter_maker, NA_action)
422 for data in data_iter_maker():
423 for factor in list(examine_needed):
--> 424 value = factor.eval(factor_states[factor], data)
425 if factor in cat_sniffers or guess_categorical(value):
426 if factor not in cat_sniffers:
/tmp/buildd/patsy-0.3.0/patsy/eval.py in eval(self, memorize_state, data)
483 # http://nedbatchelder.com/blog/200711/rethrowing_exceptions_in_python.html
484 def eval(self, memorize_state, data):
--> 485 return self._eval(memorize_state["eval_code"], memorize_state, data)
486
487 def test_EvalFactor_basics():
/tmp/buildd/patsy-0.3.0/patsy/eval.py in _eval(self, code, memorize_state, data)
466 self,
467 self._eval_env.eval,
--> 468 code, inner_namespace=inner_namespace)
469
470 def memorize_chunk(self, state, which_pass, data):
/tmp/buildd/patsy-0.3.0/patsy/compat.py in call_and_wrap_exc(msg, origin, f, *args, **kwargs)
115 def call_and_wrap_exc(msg, origin, f, *args, **kwargs):
116 try:
--> 117 return f(*args, **kwargs)
118 except Exception as e:
119 if sys.version_info[0] >= 3:
/tmp/buildd/patsy-0.3.0/patsy/eval.py in eval(self, expr, source_name, inner_namespace)
125 code = compile(expr, source_name, "eval", self.flags, False)
126 return eval(code, {}, VarLookupDict([inner_namespace]
--> 127 + self._namespaces))
128
129 @classmethod
<string> in <module>()
/tmp/buildd/patsy-0.3.0/patsy/splines.py in transform(self, x, df, knots, degree, include_intercept, lower_bound, upper_bound)
237 include_intercept=False,
238 lower_bound=None, upper_bound=None):
--> 239 basis = _eval_bspline_basis(x, self._all_knots, self._degree)
240 if not include_intercept:
241 basis = basis[:, 1:]
/tmp/buildd/patsy-0.3.0/patsy/splines.py in _eval_bspline_basis(x, knots, degree)
20 from scipy.interpolate import splev
21 except ImportError: # pragma: no cover
---> 22 raise ImportError("spline functionality requires scipy")
23 # 'knots' are assumed to be already pre-processed. E.g. usually you
24 # want to include duplicate copies of boundary knots; you should do
ImportError: spline functionality requires scipy
In [12]: new_data = {"x": [0.1, 0.25, 0.9]}
In [13]: build_design_matrices([design_matrix.design_info.builder], new_data)[0]
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-13-99e7694535ce> in <module>()
----> 1 build_design_matrices([design_matrix.design_info.builder], new_data)[0]
NameError: name 'design_matrix' is not defined
bs() can produce B-spline bases of arbitrary degrees – e.g., degree=0 will give produce piecewise-constant functions, degree=1 will produce piecewise-linear functions, and the default degree=3 produces cubic splines. The next section describes more specialized functions for producing different types of cubic splines.
Natural and cyclic cubic regression splines are provided through the stateful transforms cr() and cc() respectively. Here the spline is parameterized directly using its values at the knots. These splines were designed to be compatible with those found in the R package mgcv (these are called cr, cs and cc in the context of mgcv), but can be used with any model.
Warning
Note that the compatibility with mgcv applies only to the generation of spline bases: we do not implement any kind of mgcv-compatible penalized fitting process. Thus these spline bases can be used to precisely reproduce predictions from a model previously fitted with mgcv, or to serve as building blocks for other regression models (like OLS).
Here are some illustrations of typical natural and cyclic spline bases:
In [14]: plt.title("Natural cubic regression spline basis example");
In [15]: y = dmatrix("cr(x, df=6) - 1", {"x": x})
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-15-44d89bfbd318> in <module>()
----> 1 y = dmatrix("cr(x, df=6) - 1", {"x": x})
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in dmatrix(formula_like, data, eval_env, NA_action, return_type)
276 eval_env = EvalEnvironment.capture(eval_env, reference=1)
277 (lhs, rhs) = _do_highlevel_design(formula_like, data, eval_env,
--> 278 NA_action, return_type)
279 if lhs.shape[1] != 0:
280 raise PatsyError("encountered outcome variables for a model "
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in _do_highlevel_design(formula_like, data, eval_env, NA_action, return_type)
150 return iter([data])
151 builders = _try_incr_builders(formula_like, data_iter_maker, eval_env,
--> 152 NA_action)
153 if builders is not None:
154 return build_design_matrices(builders, data,
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in _try_incr_builders(formula_like, data_iter_maker, eval_env, NA_action)
55 formula_like.rhs_termlist],
56 data_iter_maker,
---> 57 NA_action)
58 else:
59 return None
/tmp/buildd/patsy-0.3.0/patsy/build.py in design_matrix_builders(termlists, data_iter_maker, NA_action)
658 factor_states,
659 data_iter_maker,
--> 660 NA_action)
661 # Now we need the factor evaluators, which encapsulate the knowledge of
662 # how to turn any given factor into a chunk of data:
/tmp/buildd/patsy-0.3.0/patsy/build.py in _examine_factor_types(factors, factor_states, data_iter_maker, NA_action)
422 for data in data_iter_maker():
423 for factor in list(examine_needed):
--> 424 value = factor.eval(factor_states[factor], data)
425 if factor in cat_sniffers or guess_categorical(value):
426 if factor not in cat_sniffers:
/tmp/buildd/patsy-0.3.0/patsy/eval.py in eval(self, memorize_state, data)
483 # http://nedbatchelder.com/blog/200711/rethrowing_exceptions_in_python.html
484 def eval(self, memorize_state, data):
--> 485 return self._eval(memorize_state["eval_code"], memorize_state, data)
486
487 def test_EvalFactor_basics():
/tmp/buildd/patsy-0.3.0/patsy/eval.py in _eval(self, code, memorize_state, data)
466 self,
467 self._eval_env.eval,
--> 468 code, inner_namespace=inner_namespace)
469
470 def memorize_chunk(self, state, which_pass, data):
/tmp/buildd/patsy-0.3.0/patsy/compat.py in call_and_wrap_exc(msg, origin, f, *args, **kwargs)
115 def call_and_wrap_exc(msg, origin, f, *args, **kwargs):
116 try:
--> 117 return f(*args, **kwargs)
118 except Exception as e:
119 if sys.version_info[0] >= 3:
/tmp/buildd/patsy-0.3.0/patsy/eval.py in eval(self, expr, source_name, inner_namespace)
125 code = compile(expr, source_name, "eval", self.flags, False)
126 return eval(code, {}, VarLookupDict([inner_namespace]
--> 127 + self._namespaces))
128
129 @classmethod
<string> in <module>()
/tmp/buildd/patsy-0.3.0/patsy/mgcv_cubic_splines.py in transform(self, x, df, knots, lower_bound, upper_bound, constraints)
678 % (self._name,))
679 dm = _get_crs_dmatrix(x, self._all_knots,
--> 680 self._constraints, cyclic=self._cyclic)
681 if have_pandas:
682 if isinstance(x_orig, (pandas.Series, pandas.DataFrame)):
/tmp/buildd/patsy-0.3.0/patsy/mgcv_cubic_splines.py in _get_crs_dmatrix(x, knots, constraints, cyclic)
362 :return: The (2-d array) design matrix.
363 """
--> 364 dm = _get_free_crs_dmatrix(x, knots, cyclic)
365 if constraints is not None:
366 dm = _absorb_constraints(dm, constraints)
/tmp/buildd/patsy-0.3.0/patsy/mgcv_cubic_splines.py in _get_free_crs_dmatrix(x, knots, cyclic)
336 f = _get_cyclic_f(knots)
337 else:
--> 338 f = _get_natural_f(knots)
339
340 dmt = ajm * i[j, :].T + ajp * i[j1, :].T + \
/tmp/buildd/patsy-0.3.0/patsy/mgcv_cubic_splines.py in _get_natural_f(knots)
33 from scipy import linalg
34 except ImportError: # pragma: no cover
---> 35 raise ImportError("Cubic spline functionality requires scipy.")
36
37 h = knots[1:] - knots[:-1]
ImportError: Cubic spline functionality requires scipy.
# Plot natural cubic regression spline basis functions (colored curves) each multiplied by its coeff
In [16]: plt.plot(x, y*b);
# Plot the spline itself (sum of the basis functions, thick black curve)
In [17]: plt.plot(x, np.dot(y, b), color='k', linewidth=3);
In [18]: plt.title("Cyclic cubic regression spline basis example");
In [19]: y = dmatrix("cc(x, df=6) - 1", {"x": x})
# Plot cyclic cubic regression spline basis functions (colored curves) each multiplied by its coeff
In [20]: plt.plot(x, y*b);
# Plot the spline itself (sum of the basis functions, thick black curve)
In [21]: plt.plot(x, np.dot(y, b), color='k', linewidth=3);
In the following example we first set up our spline basis using same data as for the B-spline example above and then make predictions on a new set of data:
In [22]: design_matrix = dmatrix("cr(x, df=4, constraints='center')", data)
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-22-9df37c2ea0cd> in <module>()
----> 1 design_matrix = dmatrix("cr(x, df=4, constraints='center')", data)
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in dmatrix(formula_like, data, eval_env, NA_action, return_type)
276 eval_env = EvalEnvironment.capture(eval_env, reference=1)
277 (lhs, rhs) = _do_highlevel_design(formula_like, data, eval_env,
--> 278 NA_action, return_type)
279 if lhs.shape[1] != 0:
280 raise PatsyError("encountered outcome variables for a model "
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in _do_highlevel_design(formula_like, data, eval_env, NA_action, return_type)
150 return iter([data])
151 builders = _try_incr_builders(formula_like, data_iter_maker, eval_env,
--> 152 NA_action)
153 if builders is not None:
154 return build_design_matrices(builders, data,
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in _try_incr_builders(formula_like, data_iter_maker, eval_env, NA_action)
55 formula_like.rhs_termlist],
56 data_iter_maker,
---> 57 NA_action)
58 else:
59 return None
/tmp/buildd/patsy-0.3.0/patsy/build.py in design_matrix_builders(termlists, data_iter_maker, NA_action)
651 for term in termlist:
652 all_factors.update(term.factors)
--> 653 factor_states = _factors_memorize(all_factors, data_iter_maker)
654 # Now all the factors have working eval methods, so we can evaluate them
655 # on some data to find out what type of data they return.
/tmp/buildd/patsy-0.3.0/patsy/build.py in _factors_memorize(factors, data_iter_maker)
349 factor.memorize_chunk(state, which_pass, data)
350 for factor in list(memorize_needed):
--> 351 factor.memorize_finish(factor_states[factor], which_pass)
352 if which_pass == passes_needed[factor] - 1:
353 memorize_needed.remove(factor)
/tmp/buildd/patsy-0.3.0/patsy/eval.py in memorize_finish(self, state, which_pass)
474 def memorize_finish(self, state, which_pass):
475 for obj_name in state["pass_bins"][which_pass]:
--> 476 state["transforms"][obj_name].memorize_finish()
477
478 # XX FIXME: consider doing something cleverer with exceptions raised here,
/tmp/buildd/patsy-0.3.0/patsy/mgcv_cubic_splines.py in memorize_finish(self)
654 # Now we can compute centering constraints
655 constraints = _get_centering_constraint_from_dmatrix(
--> 656 _get_free_crs_dmatrix(x, self._all_knots, cyclic=self._cyclic)
657 )
658
/tmp/buildd/patsy-0.3.0/patsy/mgcv_cubic_splines.py in _get_free_crs_dmatrix(x, knots, cyclic)
336 f = _get_cyclic_f(knots)
337 else:
--> 338 f = _get_natural_f(knots)
339
340 dmt = ajm * i[j, :].T + ajp * i[j1, :].T + \
/tmp/buildd/patsy-0.3.0/patsy/mgcv_cubic_splines.py in _get_natural_f(knots)
33 from scipy import linalg
34 except ImportError: # pragma: no cover
---> 35 raise ImportError("Cubic spline functionality requires scipy.")
36
37 h = knots[1:] - knots[:-1]
ImportError: Cubic spline functionality requires scipy.
In [23]: new_design_matrix = build_design_matrices([design_matrix.design_info.builder], new_data)[0]
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-23-6e953bb8a417> in <module>()
----> 1 new_design_matrix = build_design_matrices([design_matrix.design_info.builder], new_data)[0]
NameError: name 'design_matrix' is not defined
In [24]: new_design_matrix
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-24-0e3c2d7d9308> in <module>()
----> 1 new_design_matrix
NameError: name 'new_design_matrix' is not defined
In [25]: np.asarray(new_design_matrix)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-25-440af3f34c34> in <module>()
----> 1 np.asarray(new_design_matrix)
NameError: name 'new_design_matrix' is not defined
Note that in the above example 5 knots are actually used to achieve 4 degrees of freedom since a centering constraint is requested.
Note that the API is different from mgcv:
Smooths of several covariates can be generated through a tensor product of the bases of marginal univariate smooths. For these marginal smooths one can use the above defined splines as well as user defined smooths provided they actually transform input univariate data into some kind of smooth functions basis producing a 2-d array output with the (i, j) element corresponding to the value of the j th basis function at the i th data point. The tensor product stateful transform is called te().
Note
The implementation of this tensor product is compatible with mgcv when considering only cubic regression spline marginal smooths, which means that generated bases will match those produced by mgcv. Recall that we do not implement any kind of mgcv-compatible penalized fitting process.
In the following code we show an example of tensor product basis functions used to represent a smooth of two variables x1 and x2. Note how marginal spline bases patterns can be observed on the x and y contour projections:
In [26]: from matplotlib import cm
In [27]: from mpl_toolkits.mplot3d.axes3d import Axes3D
In [28]: x1 = np.linspace(0., 1., 100)
In [29]: x2 = np.linspace(0., 1., 100)
In [30]: x1, x2 = np.meshgrid(x1, x2)
In [31]: df = 3
In [32]: y = dmatrix("te(cr(x1, df), cc(x2, df)) - 1",
....: {"x1": x1.ravel(), "x2": x2.ravel(), "df": df})
....:
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-32-5b2d2c1429cc> in <module>()
1 y = dmatrix("te(cr(x1, df), cc(x2, df)) - 1",
----> 2 {"x1": x1.ravel(), "x2": x2.ravel(), "df": df})
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in dmatrix(formula_like, data, eval_env, NA_action, return_type)
276 eval_env = EvalEnvironment.capture(eval_env, reference=1)
277 (lhs, rhs) = _do_highlevel_design(formula_like, data, eval_env,
--> 278 NA_action, return_type)
279 if lhs.shape[1] != 0:
280 raise PatsyError("encountered outcome variables for a model "
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in _do_highlevel_design(formula_like, data, eval_env, NA_action, return_type)
150 return iter([data])
151 builders = _try_incr_builders(formula_like, data_iter_maker, eval_env,
--> 152 NA_action)
153 if builders is not None:
154 return build_design_matrices(builders, data,
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in _try_incr_builders(formula_like, data_iter_maker, eval_env, NA_action)
55 formula_like.rhs_termlist],
56 data_iter_maker,
---> 57 NA_action)
58 else:
59 return None
/tmp/buildd/patsy-0.3.0/patsy/build.py in design_matrix_builders(termlists, data_iter_maker, NA_action)
651 for term in termlist:
652 all_factors.update(term.factors)
--> 653 factor_states = _factors_memorize(all_factors, data_iter_maker)
654 # Now all the factors have working eval methods, so we can evaluate them
655 # on some data to find out what type of data they return.
/tmp/buildd/patsy-0.3.0/patsy/build.py in _factors_memorize(factors, data_iter_maker)
347 for factor in memorize_needed:
348 state = factor_states[factor]
--> 349 factor.memorize_chunk(state, which_pass, data)
350 for factor in list(memorize_needed):
351 factor.memorize_finish(factor_states[factor], which_pass)
/tmp/buildd/patsy-0.3.0/patsy/eval.py in memorize_chunk(self, state, which_pass, data)
470 def memorize_chunk(self, state, which_pass, data):
471 for obj_name in state["pass_bins"][which_pass]:
--> 472 self._eval(state["memorize_code"][obj_name], state, data)
473
474 def memorize_finish(self, state, which_pass):
/tmp/buildd/patsy-0.3.0/patsy/eval.py in _eval(self, code, memorize_state, data)
466 self,
467 self._eval_env.eval,
--> 468 code, inner_namespace=inner_namespace)
469
470 def memorize_chunk(self, state, which_pass, data):
/tmp/buildd/patsy-0.3.0/patsy/compat.py in call_and_wrap_exc(msg, origin, f, *args, **kwargs)
115 def call_and_wrap_exc(msg, origin, f, *args, **kwargs):
116 try:
--> 117 return f(*args, **kwargs)
118 except Exception as e:
119 if sys.version_info[0] >= 3:
/tmp/buildd/patsy-0.3.0/patsy/eval.py in eval(self, expr, source_name, inner_namespace)
125 code = compile(expr, source_name, "eval", self.flags, False)
126 return eval(code, {}, VarLookupDict([inner_namespace]
--> 127 + self._namespaces))
128
129 @classmethod
<string> in <module>()
/tmp/buildd/patsy-0.3.0/patsy/mgcv_cubic_splines.py in transform(self, x, df, knots, lower_bound, upper_bound, constraints)
678 % (self._name,))
679 dm = _get_crs_dmatrix(x, self._all_knots,
--> 680 self._constraints, cyclic=self._cyclic)
681 if have_pandas:
682 if isinstance(x_orig, (pandas.Series, pandas.DataFrame)):
/tmp/buildd/patsy-0.3.0/patsy/mgcv_cubic_splines.py in _get_crs_dmatrix(x, knots, constraints, cyclic)
362 :return: The (2-d array) design matrix.
363 """
--> 364 dm = _get_free_crs_dmatrix(x, knots, cyclic)
365 if constraints is not None:
366 dm = _absorb_constraints(dm, constraints)
/tmp/buildd/patsy-0.3.0/patsy/mgcv_cubic_splines.py in _get_free_crs_dmatrix(x, knots, cyclic)
336 f = _get_cyclic_f(knots)
337 else:
--> 338 f = _get_natural_f(knots)
339
340 dmt = ajm * i[j, :].T + ajp * i[j1, :].T + \
/tmp/buildd/patsy-0.3.0/patsy/mgcv_cubic_splines.py in _get_natural_f(knots)
33 from scipy import linalg
34 except ImportError: # pragma: no cover
---> 35 raise ImportError("Cubic spline functionality requires scipy.")
36
37 h = knots[1:] - knots[:-1]
ImportError: Cubic spline functionality requires scipy.
In [33]: print y.shape
(100, 6)
In [34]: fig = plt.figure()
In [35]: fig.suptitle("Tensor product basis example (2 covariates)");
In [36]: for i in xrange(df * df):
....: ax = fig.add_subplot(df, df, i + 1, projection='3d')
....: yi = y[:, i].reshape(x1.shape)
....: ax.plot_surface(x1, x2, yi, rstride=4, cstride=4, alpha=0.15)
....: ax.contour(x1, x2, yi, zdir='z', cmap=cm.coolwarm, offset=-0.5)
....: ax.contour(x1, x2, yi, zdir='y', cmap=cm.coolwarm, offset=1.2)
....: ax.contour(x1, x2, yi, zdir='x', cmap=cm.coolwarm, offset=-0.2)
....: ax.set_xlim3d(-0.2, 1.0)
....: ax.set_ylim3d(0, 1.2)
....: ax.set_zlim3d(-0.5, 1)
....: ax.set_xticks([0, 1])
....: ax.set_yticks([0, 1])
....: ax.set_zticks([-0.5, 0, 1])
....:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-36-d93078afaed3> in <module>()
1 for i in xrange(df * df):
2 ax = fig.add_subplot(df, df, i + 1, projection='3d')
----> 3 yi = y[:, i].reshape(x1.shape)
4 ax.plot_surface(x1, x2, yi, rstride=4, cstride=4, alpha=0.15)
5 ax.contour(x1, x2, yi, zdir='z', cmap=cm.coolwarm, offset=-0.5)
ValueError: total size of new array must be unchanged
In [37]: fig.tight_layout()
Following what we did for univariate splines in the preceding sections, we will now set up a 3-d smooth basis using some data and then make predictions on a new set of data:
In [38]: data = {"x1": np.linspace(0., 1., 100),
....: "x2": np.linspace(0., 1., 100),
....: "x3": np.linspace(0., 1., 100)}
....:
In [39]: design_matrix = dmatrix("te(cr(x1, df=3), cr(x2, df=3), cc(x3, df=3), constraints='center')",
....: data)
....:
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-39-292ed954bd19> in <module>()
1 design_matrix = dmatrix("te(cr(x1, df=3), cr(x2, df=3), cc(x3, df=3), constraints='center')",
----> 2 data)
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in dmatrix(formula_like, data, eval_env, NA_action, return_type)
276 eval_env = EvalEnvironment.capture(eval_env, reference=1)
277 (lhs, rhs) = _do_highlevel_design(formula_like, data, eval_env,
--> 278 NA_action, return_type)
279 if lhs.shape[1] != 0:
280 raise PatsyError("encountered outcome variables for a model "
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in _do_highlevel_design(formula_like, data, eval_env, NA_action, return_type)
150 return iter([data])
151 builders = _try_incr_builders(formula_like, data_iter_maker, eval_env,
--> 152 NA_action)
153 if builders is not None:
154 return build_design_matrices(builders, data,
/tmp/buildd/patsy-0.3.0/patsy/highlevel.py in _try_incr_builders(formula_like, data_iter_maker, eval_env, NA_action)
55 formula_like.rhs_termlist],
56 data_iter_maker,
---> 57 NA_action)
58 else:
59 return None
/tmp/buildd/patsy-0.3.0/patsy/build.py in design_matrix_builders(termlists, data_iter_maker, NA_action)
651 for term in termlist:
652 all_factors.update(term.factors)
--> 653 factor_states = _factors_memorize(all_factors, data_iter_maker)
654 # Now all the factors have working eval methods, so we can evaluate them
655 # on some data to find out what type of data they return.
/tmp/buildd/patsy-0.3.0/patsy/build.py in _factors_memorize(factors, data_iter_maker)
347 for factor in memorize_needed:
348 state = factor_states[factor]
--> 349 factor.memorize_chunk(state, which_pass, data)
350 for factor in list(memorize_needed):
351 factor.memorize_finish(factor_states[factor], which_pass)
/tmp/buildd/patsy-0.3.0/patsy/eval.py in memorize_chunk(self, state, which_pass, data)
470 def memorize_chunk(self, state, which_pass, data):
471 for obj_name in state["pass_bins"][which_pass]:
--> 472 self._eval(state["memorize_code"][obj_name], state, data)
473
474 def memorize_finish(self, state, which_pass):
/tmp/buildd/patsy-0.3.0/patsy/eval.py in _eval(self, code, memorize_state, data)
466 self,
467 self._eval_env.eval,
--> 468 code, inner_namespace=inner_namespace)
469
470 def memorize_chunk(self, state, which_pass, data):
/tmp/buildd/patsy-0.3.0/patsy/compat.py in call_and_wrap_exc(msg, origin, f, *args, **kwargs)
115 def call_and_wrap_exc(msg, origin, f, *args, **kwargs):
116 try:
--> 117 return f(*args, **kwargs)
118 except Exception as e:
119 if sys.version_info[0] >= 3:
/tmp/buildd/patsy-0.3.0/patsy/eval.py in eval(self, expr, source_name, inner_namespace)
125 code = compile(expr, source_name, "eval", self.flags, False)
126 return eval(code, {}, VarLookupDict([inner_namespace]
--> 127 + self._namespaces))
128
129 @classmethod
<string> in <module>()
/tmp/buildd/patsy-0.3.0/patsy/mgcv_cubic_splines.py in transform(self, x, df, knots, lower_bound, upper_bound, constraints)
678 % (self._name,))
679 dm = _get_crs_dmatrix(x, self._all_knots,
--> 680 self._constraints, cyclic=self._cyclic)
681 if have_pandas:
682 if isinstance(x_orig, (pandas.Series, pandas.DataFrame)):
/tmp/buildd/patsy-0.3.0/patsy/mgcv_cubic_splines.py in _get_crs_dmatrix(x, knots, constraints, cyclic)
362 :return: The (2-d array) design matrix.
363 """
--> 364 dm = _get_free_crs_dmatrix(x, knots, cyclic)
365 if constraints is not None:
366 dm = _absorb_constraints(dm, constraints)
/tmp/buildd/patsy-0.3.0/patsy/mgcv_cubic_splines.py in _get_free_crs_dmatrix(x, knots, cyclic)
336 f = _get_cyclic_f(knots)
337 else:
--> 338 f = _get_natural_f(knots)
339
340 dmt = ajm * i[j, :].T + ajp * i[j1, :].T + \
/tmp/buildd/patsy-0.3.0/patsy/mgcv_cubic_splines.py in _get_natural_f(knots)
33 from scipy import linalg
34 except ImportError: # pragma: no cover
---> 35 raise ImportError("Cubic spline functionality requires scipy.")
36
37 h = knots[1:] - knots[:-1]
ImportError: Cubic spline functionality requires scipy.
In [40]: new_data = {"x1": [0.1, 0.2],
....: "x2": [0.2, 0.3],
....: "x3": [0.3, 0.4]}
....:
In [41]: new_design_matrix = build_design_matrices([design_matrix.design_info.builder], new_data)[0]
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-41-6e953bb8a417> in <module>()
----> 1 new_design_matrix = build_design_matrices([design_matrix.design_info.builder], new_data)[0]
NameError: name 'design_matrix' is not defined
In [42]: new_design_matrix
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-42-0e3c2d7d9308> in <module>()
----> 1 new_design_matrix
NameError: name 'new_design_matrix' is not defined
In [43]: np.asarray(new_design_matrix)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-43-440af3f34c34> in <module>()
----> 1 np.asarray(new_design_matrix)
NameError: name 'new_design_matrix' is not defined