Friday, March 18, 2016

SiS Repost: Monte Carlo methods, nonparametric tests and you

Often when people first are introduced to ENMTools, a point of confusion arises when they come to the point of having to compare their empirical observations to a null distribution: it’s not something they’ve done so explicitly before, and they’re not quite sure how to do it.  In this post I’m going to try to explain in the simplest possible terms how hypothesis testing, and in particular nonparametric tests based on Monte Carlo methods, work.

Let’s say we’ve got some observation based on real data.  In our case, we’ll say it’s a measurement of niche overlap between ENMs built from real occurrence points for a pair of species (figure partially  adapted (okay, stolen) from a figure by Rich Glor).  We have ENMs for two species, and going grid cell by grid cell, we sum up the differences between those ENMs to calculate a summary statistic measuring overlap, in this case D.
Due to some evolutionary or ecological question we’re trying to answer, we’d like to know whether this overlap is what we’d expect under some null hypothesis.  For the sake of example, we’ll talk about the “niche identity” test of Warren et al. 2008.  In this case, we are asking whether the occurrence points from two species are effectively drawn from the same distribution of environmental variables.  If that is the case, then whatever overlap we see between our real species should be statistically indistinguishable from the overlap we would see under that null hypothesis.  But how do we test that idea quantitatively?

In the case of good old parametric statistics, we would do that by comparing our empirical measurement to a parametric estimate of the overlap expected between two species (i.e., we would say "if the null hypothesis is true, we would expect an overlap of 0.5 with a standard deviation of .05", or something like that).  That would be fine if we could accurately make a parametric estimate of the expected distribution of overlaps under that null hypothesis, i.e., we need to be able to specify a mean and variance for expected overlap under that null hypothesis.  How do we do that?  Well, unfortunately, in our case we can’t.  For one thing we simply can’t state that null in a manner that makes it possible for us to put numbers on those expectations.  For another, standard parametric statistics mostly require the assumption that the distribution of expected measurements under the null hypothesis meets some criteria, the most frequent being that the distribution is normal.  In many cases we don’t know whether or not that’s true, but in the case of ENM overlaps we know it’s probably not true most of the time.  Overlap metrics are bound between 0 and 1, and if the null hypothesis generates expectations that are near one of those extremes, the distribution of expected overlaps is highly unlikely to be even approximately normal.  There can also be (and this is based on experience), multiple peaks in those null distributions, and a whole lot of skew and kurtosis as well.  So a specification of our null based on a normal distribution would be a poor description of our actual expectations under the null hypothesis, and as a result any statistical test based on parametric stats would be untrustworthy.  I have occasionally been asked whether it’s okay to do t-tests or other parametric tests on niche overlap statistics, and, for the reasons I’ve just listed, I feel that the answer has to be a resounding “no”.

So what’s the alternative?  Luckily, it’s actually quite easy.  It’s just a little less familiar to most people than parametric stats are, and requires us to think very precisely about the ideas we’re trying to test.  In our case, what we need to do is to find some way to estimate the distribution of overlaps expected between a pair of species using this landscape and these sample sizes if they were effectively drawn from the same distribution of environments.  What would that imply?  Well, if each of these sets of points were drawn from the same distribution, we should be able to generate overlap values similar to our empirical measurement by repeating that process.  So that’s exactly what we do!

We take all of the points for these two species and we throw them in a big pool.  Then we randomly pull out points for two species from that pool, keeping the sample sizes consistent with our empirical data.  Then we build ENMs for those sets of points and measure overlaps between them.  That gives us a single estimate of expected overlaps under the null hypothesis.  So now we’ve got our empirical estimate (red) and one realization of the null hypothesis (blue)
All right, so it looks like based on that one draw from the null distribution, our empirical overlap is a lot lower than you’d expect.  But how much confidence can we have in this conclusion can we have based on one single draw from the null distribution?  Not very much.  Let’s do it a bunch more times and make a histogram:
All right, now we see that, in 100 draws from that null distribution, we never once drew an overlap value that was as low as the actual value that we get from our empirical data.  This is pretty strong evidence that, whatever process generated our empirical data, it doesn’t look much like the process that generated that null distribution, and based on this evidence we can statistically reject that null hypothesis.  But how do we put a number on that?  Easy!  All we need to do is figure out what the percentile in that distribution is that corresponds to our empirical measurement.  In this case our empirical value is lower than the lowest number in our null distribution.  That being the case, we can’t specify exactly what the probability of getting our empirical result is, only that it’s lower than the lowest value we obtained, so it’s p < (whatever that number is).  Since we did 100 iterations of that null hypothesis (and since our empirical result is also a data point), the resolution of our null distribution is 1/(100 + 1) ~= .01.  Given our resolution, that means p is between 0 and .01 or, as we normally phrase it, p < .01.  If we’d done 500 simulation runs and our empirical value was still lower than our lowest value, it would be p < 1/(500 + 1), or p < .0002.  If we’d done 500 runs and found that our empirical value was between the lowest value and the second lowest value, we would know that .0002 < p < .0004, although typically we just report these things as p < .0004.  Basically the placement of our empirical value in the distribution of expected values from our null hypothesis is an estimate of the probability of getting that value if that hypothesis were true.  This is exactly how hypothesis testing works in parametric statistics, the only difference being that in our case we generated the null distribution from simulations rather than specifying it mathematically.

So there you go!  We now have a nonparametric test of our hypothesis.  All we had to do was (1) figure out precisely what our null hypothesis was, (2) devise a way to generate the expected statistics if that hypothesis were true, (3) generate a bunch of replicate realizations of that null hypothesis to get an expected distribution under that null, and (4) compare our empirical observations to that distribution.  Although this approach is certainly less easy than simply plugging your data into Excel and doing a t-test or whatnot, there are many strengths to the Monte Carlo approach. For instance, we can use this approach to test pretty much any hypothesis that we can simulate – as long as we can produce summary statistics from a simulation that are comparable to our empirical data, we can test the probability of observing our empirical data under the set of assumptions that went into that simulated data.  It also means we don’t have to make assumptions about the distributions that we’re trying to test – by generating those distributions directly and comparing our empirical results to those distributions, we manage to step around many of the assumptions that can be problematic for parametric statistics.

The chief difficulty in applying this method is in steps 2 and 3 above – we have to be able to explicitly state our null hypothesis, and we have to be able to generate the distribution of expected measurements under that null.  Honestly, though, I think this is actually one of the greatest strengths of Monte Carlo methods: while this process may be more intensive than sticking our data into some plug-and-chug stats package, it requires us to think very carefully about what precisely our null hypothesis means, and what it means to reject it.  It requires more work, but more importantly it requires a more thorough understanding of our own data and hypotheses.

Wednesday, March 16, 2016

Symposium at Evolution 2016: Putting evolution into ecological niche modeling: Building the connection between phylogenies, paleobiology, and species distribution models

Just a heads up that Nick Matzke and I are organizing a symposium on integrating evolutionary thinking with niche and distribution modeling at this year's Evolution conference in Austin.  We've got some great speakers lined up, and are looking forward to a very productive and informative exchange of ideas.  Make sure to attend if you're at the meeting!

Thursday, January 21, 2016

Workshop: Model-based statistical inference in ecological and evolutionary biogeography. Barcelona, Spain, Nov. 28 - Dec. 2 2016.

Hey everybody!  Nick Matzke and I are working up a course to run down some of the standard methods in ecological and evolutionary biogeography, including some of the new methods he and I are working on for integrating evolution into species distribution models.  There are still some bits of it in flux, but at the bare minimum this is a chance to learn BioGeoBears and ENMTools (via the R package, which is developing rapidly) from their respective sources.  Our first iteration of the course will be this November/December in Barcelona.  Feel free to contact me if your institution would be interested in hosting a similar workshop sometime in 2017 or later, and please do enroll for Barcelona if you're interested!

Here's the official course announcement:
Nick Matzke and Dan Warren will be teaching a course entitled "Model-based Statistical Inference in Ecological and Evolutionary Biogeography" in Barcelona from November 28 to Dec 2 this year.
This course will cover the theory and practice of widely used methods in evolutionary and ecological biogeography, namely ecological niche modelling / species distribution modelling, and ancestral range estimation on phylogenies.
The course will cover both the practical challenges to using these techniques (the basics of R, obtaining and processing geographical occurrence data from GBIF, setting up and using the models), and the assumptions that various models and methods make.
R packages we will use include rgbif, dismo, ENMTools, and BioGeoBEARS.
Finally, this course will introduce several new approaches being developed by the instructors for linking ecological and evolutionary models.
For more details or to enroll, please see the Transmitting Science web site.

Tuesday, November 3, 2015

Hey what's the deal with the ENMTools R package?

It has come to my attention that at least one person is actually using the ENMTools R package I sorta half-made a couple of years ago, for which I would like to express my deepest condolences.

Seriously, though, I did want to at least acknowledge its existence and the absolutely massive caveats that should come with any attempt to use it in its current state.  

The package exists because I needed a project in order to learn R; I've found that reading a book and doing examples is one thing, but to really assimilate a new language I need to have a project that makes me sit down and work on it every day.  When I started my postdoc at ANU a few years ago, I said to myself "I am going to do everything in R from this day forward, and in order to learn R I will rewrite as much of ENMTools as I need to to feel like I've mastered it".  

So that's what I did.  I wrote bits to generate reps for most of the major tests in ENMTools, including the background, identity, and rangebreak tests.  I also wrote code to measure breadth and overlap using the metrics in ENMTools, and a couple of other little utility functions.  That helped me get comfortable with the basics in R, and at that point I got busy enough with my actual postdoc work that I had to drop it.  

And that's pretty much where it stands today, a couple of years later.  It mostly works, but it ain't exactly pretty or well documented - it was my first R project, after all.  While some of its functionality has already been duplicated elsewhere (e.g., the identity and background tests in phylocom), some of it hasn't (e.g., the rangebreak tests).  Now that I've been writing R pretty much daily for the past three years, I see a million things I did sub-optimally, and a bunch of areas where I could have taken advantage of existing functionality to do things more quickly, more cleanly, and with a lot more cool bells and whistles.

So why do I bring this up?  First, as I mentioned, because apparently some people are actually using it.  I'm not sure whether that's due to masochism or desperation, but they are.  Second, and more importantly, because I'm going to try to bash it into a somewhat more useful form over the next however-long.  It's probably not going to duplicate all of the functionality of the original ENMTools, but the eventual goal is to include a lot of very cool stuff that the old version didn't have.  If you want to contribute or are brave enough to muck around with it in its current state, it's here:

Wednesday, October 28, 2015

Handy little snippet of R code for thinning occurrence data

I came up with this a few months back.  I was using the R package spThin, by Aiello-Lammens et al, but found that it didn't quite do what I wanted it to do.  The purpose of that package is to return the maximum number of records for a given thinning distance, which is obviously very valuable in situations where you (1) don't have a ton of data and (2) are concerned about spatial autocorrelation.

However, it wasn't quite what I needed for two reasons.  First, I didn't need to maximize the number of points given a specified thinning distance; I needed to grab a fixed number of points that did the best possible job of spanning the variation (spatial or otherwise) in my initial data set.  Second, the spThin algorithm, because it's trying to optimize sample size, can take a very long time to run for larger data sets.

Here's the algorithm I fudged together:

1. Pick a single random point from your input data set X and move it to your output set Y.

Then, while the number of points in Y is less than the number you want:
2. Calculate the distance between the points in X and the points in Y.
3. Pick the point from X that has the highest minimum distance to points in Y (i.e., is the furthest away from any of the points you've already decided to keep).

Lather, rinse, repeat.  Stop when you've got the number of points you want.

Just so you can get an idea of what's going on, here's some data on Leucadendron discolor from a project I'm working on with Haris Saslis-Lagoudakis:

That's a lot of points!  4,874, to be exact.  Now let's run it through thin.max and ask for 100 output points:

Lovely!  We've got a pretty good approximation of the spatial coverage of the initial data set, but with a lot fewer points.  What's extra-nice about this approach is that you can use it for pretty much any set of variables that you can use to calculate Euclidean distances.  That means you can thin data based on geographic distance, environmental distance, or a combination of both!  Just pass it the right column names, and it should work.  Of course since it's Euclidean distances you might run into some scaling issues if you try to use a combination of geographic and environmental variables, but you could probably fix that by rescaling axes before selecting points in some useful way.

Also, since it starts from a randomly chosen point, you will get somewhat different solutions each time you run it.  Could be useful for some sort of spatially-overdispersed jackknife if you want to do something like that for some reason.

There's no R package as such for this, but it will probably be folded into the R version of ENMTools when I get around to working on that again.  For now, you can get the code here:

Tuesday, September 29, 2015

Big Changes Coming!

Hey all,

Increasingly, I've been thinking that this blog would be a good place for some more general-purpose biogeography talk, and open to more people than just me and Rich.  I've talked to the authors of the old Species in Space blog that I contributed to, and we've decided we're going to move all of that content (and people) over here.

Some time in the next few weeks, you will see a bunch of posts from Species In Space show up here, and soon after that you will start seeing new content from some very cool people doing very cool biogeography things.  If any of you out there are looking for a place to blog some biogeography stuff, give me a shout!

In order to fit the new focus, we'll also gradually rebrand this to be the Species in Space blog, rather than strictly ENMTools.  That'll mean a new look, a new logo, and pointing the Species in Space URL over here.  No worries, though, I'll keep the old URL pointed here too, in case people have bookmarks to that.

I'm busy as can be at the moment, so this is all going to happen in fits and starts.  I think it will be pretty cool when we get it together, though, and hopefully you'll all enjoy it.


Tuesday, August 4, 2015

Tutorials on Maxent and ENMTools

A few months ago, I gave a workshop at James Cook University in Townsville, Australia.  We covered some basic concepts for niche modeling and ecological biogeography, and then ran through some sample exercises in Maxent, ENMTools, and ecospat.

First, here's a tutorial on basic ideas and procedures for niche modeling:

Then a very brief foray into the different assumptions that need to be made when using niche models for different purposes in ecological biogeography:

The main event was a two hour demo of ENMTools.  Unfortunately we had a serious issue with the recording: there was no audio at all!  I'll try to replicate the talk on my own and upload it one of these days.

For those of you who want to play along at home, the demo data is here:

I really want to thank JCU for having me out, and in particular Megan Higgie and Conrad Hoskin for their hospitality.