I hope it's appealing :)
> researchers.
> I do most of my computational work in python but for nonparametric
> estimation I am currently using the package “np” in R and I am
> accessing it through rpy2 and rpy which has some drawbacks. This is
> why I think it would be great if we could have a python library that
> could implement these models.
>
> Please let me know if you have any suggestions and if you think that
> this would fit into the statsmodels project. I will post a complete
> draft of my GSoC proposal by early next week, but I would appreciate
> any input you may have in the meantime.
Hi George,
We want to expand in this area and it is a good topic. Skipper and I
were looking at various papers by Jeffrey Racine for our short to
medium term wishlist, and it would be a desired contribution.
The only possible problem I see with the proposal is that it's not
large enough for a GSoC. Given the work by Skipper and Mike (on kernel
regression), the enhancements might not fill up the time.
I don't think it's a problem with the topic, since nonparametrics is
pretty big, but it might require some thought and planning in the
proposal about the amount of time various parts might take.
If you have some useful methods coming out of the micro-structure
analysis, then this might also make an interesting extra part.
Thanks,
Josef
>
> Thanks,
> George
A few months ago we added an optional joblib dependency with some
wrapper code. It's what scikit-learn uses for parallel processing. I
think we don't use it much yet, but that would be the easiest
solution.
It will be interesting for statsmodels if we gain more experience with
it or other parallel tools, so we will be able to use it more often.
I don't think we want to go into parallel tool development itself,
since we can leave it to ipython, Gael and the "experts", but we
should make it easy to use it, and use it ourselves as an option for
time consuming code.
Josef
To add briefly to this. I think having parallelization for
nonparametric methods is definitely worth some time as part of the
project. That said, with the use of joblib it's almost trivial to
handle embarrassingly parallel problems. It becomes only one line of
code. See, for example,
http://packages.python.org/joblib/parallel.html
And my first stab at cross validation for univariate density estimation
If we do need to incorporate message passing, then more thought would
be needed, but we'd still leverage existing tools. I don't think it
would be necessary with this code though.
Skipper
I think now it's too much or too ambitious for a GSoC.
But I like it as a future roadmap for possible extensions. Especially,
if you have references that show where to get started.
The outline by topic is also useful, but the actual sequence of coding
would have to be different, I assume. So I would suggest and
additional "time line" that gives the sequence in which the parts are
written. (I don't expect that it will be possible to guess very well
how long the different parts will take)
Also you need to allocate time for writing tests. I would recommend
writing the tests for each part first or along the way, especially if
you are already familiar with the np package. And this test driven
development makes coding much easier.
>
> The main reference for the models that follow is the text
> Nonparametric Econometrics by Qi Li and Jeff Racine but a detailed
> reference section will be coming soon.
>
> I would like to extend the nonparametric capabilities of statsmodels
> in the following areas:
>
> *Nonparametric Density Estimators*
>
> - Develop a class of density estimators that is able to estimate and
> plot unconditional probability densities (PDFs) of the form
> P(x_1,x_2,x_3,…,x_n) and cumulative probability densities (CDFs) of
> the form P(x_1<X_1,…,x_n<X_n) for mixed data types
>
> - Develop a class of density estimators that is able to estimate and
> plot conditional PDFs of the form P(x_1,x_2,…,x_n|y_1,y_2,…,y_n) and
> similarly conditional CDFs (based on the generalized product kernel
> estimator)
>
> *Nonparametric Models*
>
> - Develop a class that fits nonparametric regression models of the
> type y=g(x)+e and implements the local constant kernel estimator and
Is x univariate or multivariate?
> the local linear kernel estimator proposed by Stone(1977) and
> Cleveland (1979) with appropriate significance tests and marginal
> effects
> - Develop a class that fits nonparametric quantile regression
I don't know much about any details
> - Fit nonparametric simultaneous equation models
> - Fit nonparametric panel data models
The last two here should go at the very end, and I doubt there will be
enough time for it.
Both require supporting code that is still unclear or missing, and
might require some time. It will be easier to extend once simultaneous
equation and panel data models are available.
If you have references, I'm interested in it since I don't know what
has been done in this area in the literature.
>
>
> *Semiparametric Models*
>
> - Fit semiparametric partially linear models of the type y=X’b+g(Z)+u
> - Fit semiparametric single index models of the type y=g(X’b)+u
> - Fit semiparametric partially linear time series model of the type
> Y_t=X_t’b + g(Z_t) +u_t
I think these are the best candidates for getting good applications out of the
> - Fit semiparametric Tobit models
> - Fit semiparametric Censored Regression Models
overlap with Skipper's Tobit and with survival/duration models?
>
> *Bandwidth Selection Procedures*
should be early on timeline
very early on time line
>
> - I don’t think that statsmodels currently has kernels that can handle
> discrete ordered an unordered variables. Also I don’t think we could
> work with higher-order kernels (please let me know if this isn’t the
> case). I would like to develop this further so statsmodels can handle
> mixed data estimation.
One additional part might be bootstrap and bootstrap confidence
intervals, since in many cases convergence to the asymptotic
distribution is too slow (to be very useful in small samples), as far
as I remember.
>
> *Copulas*
>
> - Estimate nonparametric copulas (this is a huge topic but perhaps
> some basic capabilities could be introduced)
I would say only as far as there might be common code.
>
> *Documentation and Examples*
>
> - Introduce examples from economics, finance and financial market
> microstructure (possibly recreate some of the examples given by Li and
> Racine and implemented in R’s np package)
>
>
> I suspect that a thorough coverage (including testing) of each of the
> bullets above could take about a week to complete and possibly more if
> there are some unexpected computational difficulties (such as
> convergence problems with bandwidth selection methods).
>
> Do you feel that this general outline would fit within the GSoC
> requirements and within the statsmodels goals? Is it too ambitious or
> still too short? Should I eliminate and/or expand certain sections?
>
> Thanks for the input
I just remembered that I have borrowed Li, Racine 3 months ago, so I
will be able to check some details.
Thanks,
Josef
>
> George
Whay not submit it, like, NOW, and update the draft on Thursday? :)
From a quick look, the proposal looks good, but I will go through it
in detail tomorrow.
Thanks,
Josef
Yes, I would go ahead and submit to melange now. I am going to be
doing reviews on there, but a few brief comments below. There have
been many warnings from GSoC/PSF that _melange will break_ sometime
during the application period. It's best to have the application on
there because there won't be another chance.
You may want to add to your before GSoC duties to get familiar with
profiling tools for Python (if you aren't already). I imagine some
time (after everything works) will be spent on trying to optimize the
data-driven methods for speed. I don't find my good profiling tutorial
links right now, but remind me. We'll be able to help here.
> > Week 2 – 4 (June 4 – June 17)
> > Begin work on two major classes: multivariate unconditional density
> > estimator and multivariate conditional density estimators. Adapt the
> > existing bandwidth selection procedures to handle the multivariate
> > density estimation. Create two more classes that will estimate the
> > cumulative densities in the conditional and unconditional case.
> >
> > Week 4 – 6 (June 18 – July 1)
> > Develop a class that fits nonparametric regression models of the type
> > y=g(x)+e, where x is multivariate, and implements the local constant
> > kernel estimator and the local linear kernel estimator proposed by
> > Stone(1977) and Cleveland (1979) with appropriate significance tests
> > and marginal effects
> >
FYI, I have found coding marginal effects efficiently and reusably to
be a big time sink.
> > Week 6 – 8 (July 2 – July 15)
> > Midterm (July 13) . The work between week 1 and week 6 will form the
> > backbone of the models to come. Code the appropriate tests for the
> > conditional, unconditional density estimators and the nonparametric
> > regression. Cross-check results with the nonparametric package “np”
> > written for R and make sure all computational methods are working
> > properly.
> >
> >
> > Week 8 – 10 (July 16 – July 29)
> > Begin work on extending the model library. Write two classes that can
> > fit semiparametric Tobit models and semiparametric censored regression
> > models.
> >
Is the idea of the semiparametric Tobit that it's just a Tobit model
with an unknown underlying distribution?
>
> > Week 10 – 12 (July 30 – August 12)
> > Start work on fitting nonparametric simultaneous equation models and
> > nonparametric panel data models. These should overlap with the current
> > existing capabilities of statsmodels[?]. Begin work on the
> > documentation for the models and start writing tests for the
> > nonparametric models developed in the second half of the summer.
> > Compare with results with other existing packages.
> >
This last part is very ambitious. I don't know that we'll make it here
and if we do that 2 weeks will be enough time to cover this. Overall
though the proposal looks good and properly focused.
Skipper
Go ahead and submit. You can edit until the deadline. They keep
warning that Melange will crash in the next 24 hours and that people
always have problems and don't get to submit but the deadline is still
final.
I read the melange version (in case there are differences)
I think in the following parts the word "kernel" should be used once
or twice to emphasise that it is for kernel based non-parametrics, not
splines or orthogonal polynomials for example.
>
> Week 1 – 2 (May 21 – June 3)
> Start work on the bandwidth selection methods. Add to the current
> “rule-of-thumb” methods, fully data-driven methods such as likelihood
> cross and least-squares cross validation and the Hurvich, Simonoff and
> Tsai (1998) bandwidth selection method. Introduce several “plug-in”
> bandwidth selection procedures for some of the more popular
> distributions. This should improve the current univariate kernel
> density estimation procedures in statsmodels.
What happened to the kernels for categorical variables?
>
> Week 2 – 4 (June 4 – June 17)
> Begin work on two major classes: multivariate unconditional density
> estimator and multivariate conditional density estimators. Adapt the
> existing bandwidth selection procedures to handle the multivariate
> density estimation. Create two more classes that will estimate the
> cumulative densities in the conditional and unconditional case.
>
> Week 4 – 6 (June 18 – July 1)
> Develop a class that fits nonparametric regression models of the type
> y=g(x)+e, where x is multivariate, and implements the local constant
> kernel estimator and the local linear kernel estimator proposed by
> Stone(1977) and Cleveland (1979) with appropriate significance tests
> and marginal effects
statsmodels has lowess which is based on one of the Cleveland papers,
but without statistical results, like confidence intervals
maybe y=g(x) + Z beta + e as extension ?
>
> Week 6 – 8 (July 2 – July 15)
> Midterm (July 13) . The work between week 1 and week 6 will form the
> backbone of the models to come. Code the appropriate tests for the
> conditional, unconditional density estimators and the nonparametric
> regression. Cross-check results with the nonparametric package “np”
> written for R and make sure all computational methods are working
> properly [4].
>
>
> Week 8 – 10 (July 16 – July 29)
> Begin work on extending the model library. Write two classes that can
> fit semiparametric Tobit models and semiparametric censored regression
> models.
>
> Week 10 – 12 (July 30 – August 12)
> Explore the feasibility of including more advanced models such as
> nonparametric simultaneous equation models and nonparametric panel
> data models. Check if there is existing code that overlaps and start
> the groundwork. These should overlap with the current existing
> capabilities of statsmodels [1]. Begin work on the documentation for
> the models and start writing tests for the nonparametric models
> developed in the second half of the summer. Compare with results with
> other existing packages.
Instead of nonparametric simultaneous equations (which might not be
easy) applying the kernel methods to statistical tests might be more
interesting.
e.g non-parametric specification tests: compare/test of a parametric
model against a kernel-based non-parametric alternative.
Overall it looks good,
I also recommend test and document as you go, and consider the time at
the end more for cleanup and filling some holes in documentation and
tests.
Josef
No, I don't think it's necessary to add it everywhere. At most mention it once.
I just wanted to clarify that having a section "testing and
documentation" doesn't mean it's done only during that time.
Josef
I think the statsmodels.nonparametric.kde is a partially rewritten
version by Skipper, but as far as I know Skipper then focused on
binned kernel density estimation with fft.
sandbox.nonparametric.kernels is a class that is used and has helper
methods for kernel density and kernel regression/smoothers. The main
KernelSmoother class is the one in sandbox.nonparametric.smoothers, I
think.
How these classes will look like at the end is still a bit open, I guess.
Both KDE, and KernelSmoother use methods from CustomKernel and it's
subclasses under the hood.
> Wouldn't it be better if our kernel library consist only of kernel
> functions which take two inputs and return a single value i.e --
>
> value=K((X_i - x)/h)
>
> and then perform the kernel density estimation separately --
>
> f(x)=(1/nh)*SUM_i [K((X_i - x)/h)].
>
>
> I think this would make it much easier to transition from univariate
> to multivariate density estimation with the "generalized product
> kernels" method.
I think we should somewhere have a "pure" kernel window module,
similar to the windows in numpy or scipy. But I don't think it will
make the additional methods that CustomKernel has obsolete, since they
are useful. There are usages for kernel windows in tsa, and for GMM.
The advantage of sticking kernels into a class is that we can add
other things that we might need, domain, derivative, integral (cdf),
... (I don't know what we might need).
On the other hand, when we go more to cython for the expensive code in
this area, we might just want to duplicate the kernel windows in
cython.
>
> (I also keep getting errors when I try to work with the
> CustomKernel.density() method... )
>
> Of course it is possible that I am missing/misreading something...
> Please let me know if this is the case.
It's possible that there are refactoring victims, I cannot find an
example script right now, and I don't see any unit tests.
Thanks,
Josef
On Sat, Apr 14, 2012 at 8:53 PM, George PanterovI think the statsmodels.nonparametric.kde is a partially rewritten
<econgp...@gmail.com> wrote:
> Hi All,
> I am working on my code submission for the PSF requirements and I have
> a quick question about the API for the nonparametric methods.
>
> So I am looking at the kernels.py file and the CustomKernel class has
> a density method that is supposed to return the density. However we
> also have kernel density estimators in kde.py. Isn't this redundant?
version by Skipper, but as far as I know Skipper then focused on
binned kernel density estimation with fft.
sandbox.nonparametric.kernels is a class that is used and has helper
methods for kernel density and kernel regression/smoothers. The main
KernelSmoother class is the one in sandbox.nonparametric.smoothers, I
think.
How these classes will look like at the end is still a bit open, I guess.
Both KDE, and KernelSmoother use methods from CustomKernel and it's
subclasses under the hood.
> Wouldn't it be better if our kernel library consist only of kernel
> functions which take two inputs and return a single value i.e --
>
> value=K((X_i - x)/h)
>
> and then perform the kernel density estimation separately --
>
> f(x)=(1/nh)*SUM_i [K((X_i - x)/h)].
>
>
> I think this would make it much easier to transition from univariate
> to multivariate density estimation with the "generalized product
> kernels" method.
Sorry I need to catch up on this thread. IIRC that density method is a
naive density estimator ie., it does the sums over a grid. My version
uses fft for the gaussian kernel.
>
> Is everything in sandbox considered unstable (so modifiable whenever that would be convenient)? sandbox.nonparametric.kernels is used by nonparametric.kde, but I assume that if kde keeps working as advertised sandbox code can be changed?
>
I think this is fair. My impression from the sandbox kernels was that
they could be made to benefit from a refactor. I'll have to
refamiliarize myself with this code.
Essentially yes, there are a few places where sandbox code get's imported
into the main statsmodels, where we might want to be cautious but sandbox
code is mostly in the sandbox because it needs to be refactored.
So, essentially no constraint on improving the code.
>
>>
>> How these classes will look like at the end is still a bit open, I guess.
>> Both KDE, and KernelSmoother use methods from CustomKernel and it's
>> subclasses under the hood.
>>
>>
>> > Wouldn't it be better if our kernel library consist only of kernel
>> > functions which take two inputs and return a single value i.e --
>> >
>> > value=K((X_i - x)/h)
>> >
>> > and then perform the kernel density estimation separately --
>> >
>> > f(x)=(1/nh)*SUM_i [K((X_i - x)/h)].
>>
>> >
>> >
>> > I think this would make it much easier to transition from univariate
>> > to multivariate density estimation with the "generalized product
>> > kernels" method.
>
>
> I haven't read the original Li and Racine 2003 paper on this in too much
> detail yet, but the basic idea is to simply calculate simple product kernels
> for continuous and discrete variables separately, then multiply those? At
> first sight I don't see anything that would cause you to make different
> choices for your software design here with respect to the case of only
> having product kernels of continuous variables.
On the other hand, it might be better to outsource some code to
functions if it is used by different classes for different purposes.
Josef
If you click on history, you can follow it back to the old file in
github. Mike had originally written them for Kernel Regression. My
vague recollection is I took only the parts I needed and did the rest
for small speed gains.
starting at line 21
https://github.com/statsmodels/statsmodels/blob/master/statsmodels/sandbox/nonparametric/smoothers.py
KernelSmoother uses the methods that are attached to kernels
one possibility, if it works, would be to separate the pure kernel
(windows) code from the code that uses it, kde or kernel regression,
1d versus nd.
But I also haven't looked at all the details
Josef
On Mon, Apr 16, 2012 at 4:49 PM, Ralf Gommers
If you click on history, you can follow it back to the old file in<ralf.g...@googlemail.com> wrote:
>
>
> On Mon, Apr 16, 2012 at 10:38 PM, Skipper Seabold <jsse...@gmail.com>
> wrote:
>>
>> On Mon, Apr 16, 2012 at 4:34 PM, Ralf Gommers
>> <ralf.g...@googlemail.com> wrote:
>>
>> >
>> > Is everything in sandbox considered unstable (so modifiable whenever
>> > that would be convenient)? sandbox.nonparametric.kernels is used by
>> > nonparametric.kde, but I assume that if kde keeps working as advertised
>> > sandbox code can be changed?
>> >
>>
>> I think this is fair. My impression from the sandbox kernels was that
>> they could be made to benefit from a refactor. I'll have to
>> refamiliarize myself with this code.
>
>
> Do you know where they came from? Git isn't helpful with the history after
> the scikits-->statsmodels rename.
github.
One problem is where to put kernel specific auxiliary code.
KernelSmoother looks like a generic class that doesn't have kernel
specific info. smooth, smoothvar and similar might have kernel
specific explicit expressions (mostly guessing, only Gaussian has
explicit smooth).
A bit similar to the families and links in genmod.
Josef
browsing the code a bit more:
Biweight also has smooth and smoothvar.
I think we shouldn't kill/strip these classes in kernels until we have
a better idea how kernel regression/smoothing will be designed.
It looks to me that the `shape` lambda functions in the __init__
method are the kernel windows that we want to outsource, or could be
made into methods of the subclasses.
My guess is that many of the list comprehension could be replaced by
numpy array operations.
I think for kernel distribution (cdf not density) estimation it would
also be good to add the integral of the kernel windows as methods.
Josef
digging in the history and trying to find runable examples
statsmodels\sandbox\examples\try_smoothers.py
has examples with plots for the KernelSmoother that uses kernels.py
the second plot has lowess and polynomial fit overlayed for comparison
The example in __main__ of statsmodels\sandbox\nonparametric\kde2.py
runs after updating the imports
2d might not work
Josef
I think we shouldn't kill/strip these classes in kernels until we have
a better idea how kernel regression/smoothing will be designed.
It looks to me that the `shape` lambda functions in the __init__
method are the kernel windows that we want to outsource, or could be
made into methods of the subclasses.
My guess is that many of the list comprehension could be replaced by
numpy array operations.
I think for kernel distribution (cdf not density) estimation it would
also be good to add the integral of the kernel windows as methods.
Can the dependent variables also be ordered or categorical?
When I looked at the nd kde version in the sandbox, I thought you
would need a list of kernels for each dependent variable, if you work
with product kernels?
kde_conditional(endog, exog, kernels=a list of kernels).
kde_mv(endog, kernels=a list of kernels).
another way would be to require an idx for the type of variable as
keyword argument, if the variable is not continuous,
kde_conditional(endog, exog, vartype= [.....]).
kde_conditional(endog, exog, isordered=[1,3]), iscategorical=2).
(separate for exog endog or encoded?)
In general, required information should go into the arguments of the
__init__ of a class, and it should not be required to attach
information after creating an instance.
For now, I would just add keyword arguments with all the additional
information that you need, and we decide on fine-tuning the user
interface later.
for categorical variables, all you get is different kde's for each
level of the variable, is it?
For other models I was thinking of adding a BY keyword similar to SAS
for stratas/subsamples. It's not clear to me yet how to add this, but
Scott has added stratification in survival which might be useful also
with other models.
Josef
>
> Thanks
> George
You mean, with the built in types ...
So that is the basic decisison: to work with builtin types
and NumPy arrays, or to create your own types.
In either case, the information you want to associate with
the variables must either be added at estimation type or
be somehow tagged to the variable.
Here are one possibility.
Estimator((Y1,Y2),(X1,X2,X3),deptypes='co',indtypes='cfc')
(You may prefer to be more verbose/explicit.)
You may also want to explore whether you can adapt
the work on formulae:
http://statsmodels.sourceforge.net/dev/roadmap_todo.html
Alan Isaac
On 4/21/2012 3:18 PM, George Panterov wrote:You mean, with the built in types ...
npcdens(Y1 + ordered(Y2) ~ X1 + factor(X2) + X3, bw)
returns the conditional density P(Y1, Y2 | X1,X2, X3) given a
bandwidth bw. However, this is not so easy to do in Python.
So that is the basic decisison: to work with builtin types
and NumPy arrays, or to create your own types.
In either case, the information you want to associate with
the variables must either be added at estimation type or
be somehow tagged to the variable.
Here are one possibility.
Estimator((Y1,Y2),(X1,X2,X3),deptypes='co',indtypes='cfc')
I'm +1 for the lists of column indices like this.
To avoid the endog/exog, it might make sense to have
kde_conditional_cont
kde_conditional_ordered
kde_conditional_categorical
Where _cont, _ordered, and _categorical are to indicate the nature of
the endogenous variable.
I wouldn't worry too much about this. Soon, I think, users will never
see this, and you'll be able to just pass in "Y1 + ordered(Y2) ~ X1 +
factor(X2) + X3" to kde_conditional and then under the hood it figures
things out and delegates to this more verbose API. The Formula stuff
is coming along. Next on my list is to add support for ordered and
unordered factors to formula.
And we can always rethink the design later when things are nicer. This
will be cheap.
Skipper
Though I already see that this doesn't work on the below example. Maye
we can't avoid the differentiated column indices for now.
And some point we need to discuss more generally the API both for
internal use and user facing for models that require more than a few
keywords, so we can get a roughly consistent structure.
In one-way panel/repeated mixed I need groups indicators, the old
Mixed class still requires Units, Scott in survival uses a Survival
class as endog that holds the timing and censoring information, Tobit
requires extra data, ...
right now I would decide mostly on internal demand, e.g. do ordered
and categorical need to be integers or can they be floats?
string based formulas won't be convenient for internal/programmatic use.
Josef
>>
>> Skipper
https://github.com/gpanterov/statsmodels/commit/4be284ecc7ce01003b0f2c3cfe72627670e7fc60#L0L78
if you do equality checks then it would be best just to work with
integers, and then having a separate array argument would save some
copying
kde_conditional(endog, exog, endog_cat=y2, exog_cat=x2)
where do I specify which kernel I want? What about kernels with a
boundary support?
>>> And we can always rethink the design later when things are nicer. This
>>> will be cheap.
Josef