├── LICENSE ├── README.md ├── ancPopSizeRegressionExample.ipynb ├── demographicModelSelectionExample.ipynb ├── ms.tar.gz ├── msTools.py └── sweepDetectionExample.ipynb /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Kern Lab 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # popGenMachineLearningExamples 2 | 3 | This repository is meant to house a series of jupyter notebooks that showcase some simple examples of using supervised machine learning for population genetics inference. 4 | 5 | The first notebook that we have added `demographicModelSelectionExample.ipynb` is meant as a companion to our recent review-- Schrider and Kern (2017) "Machine learning for population genetics: a new paradigm." That paper can be found on bioRxiv here: https://www.biorxiv.org/content/early/2017/10/20/206482 6 | 7 | The subsequent notebooks really build on ideas presented in the first one. We aim to present a diversity of applications within population genetics that highlight a number of algorithms and ML practices. We recommend going through these in something like the following order: 8 | 1. `demographicModelSelectionExample.ipynb`- using a Random Forest classifier for doing demographic model selection 9 | 2. `sweepDetectionExample.ipynb` - using a Support Vector Machine classifier for detecting & categorizing sweeps 10 | 3. `ancPopSizeRegressionExample.ipynb` - using Random Forest regression to estimate past population size 11 | -------------------------------------------------------------------------------- /ancPopSizeRegressionExample.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Using a random forest to infer past population size\n", 8 | "In this example we are going to try to infer the past population size after an instantenous population contraction/expansion. Technically what we are inferring is the ratio of the ancestral size to the current size. We are also assuming the time of the size change is known. Again for the purposes of this simple example we are taking the unusal step of doing some demographic inference when examining one locus rather than many loci, but hopefully the exercise will still be illustrative." 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "metadata": {}, 14 | "source": [ 15 | "## Preliminaries\n", 16 | "The road map here will be to 1) simulate a bunch of loci each with a randomly drawn ancestral population size (which we will record) 2) to train a regressor to infer this size on the basis of a feature vector of summary statistics 3) test our accurracy on a set of simulations not used during training 4) to graphically present how well our trained classifier works.\n", 17 | "\n", 18 | "To do this we will use coalescent simulations as implemented in our Dick Hudson's `ms` and will again use `scikit-learn` for our machine learning. For our statistics, we will use Alistair Miles' `scikit-allel` python package.\n", 19 | "\n", 20 | "(Note: `scikit-allel` is an excellent package for this sort of thing. There are other nice packages that are equally excellent and well suited for our task here, but `scikit-allel` is up and running on the machine I am writing this from so that is what we are using. Don't hate on me, friends!)" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "### Install and compile `ms`\n", 28 | "We have put a copy of the `ms` tarball in this repo, so the following should work upon cloning. (Note that this step is not required if you have already gone through `demographicModelSelectionExample.ipynb`.)" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": 4, 34 | "metadata": { 35 | "collapsed": true, 36 | "scrolled": true 37 | }, 38 | "outputs": [], 39 | "source": [ 40 | "#untar and compile ms and sample_stats\n", 41 | "!tar zxf ms.tar.gz; cd msdir; gcc -o ms ms.c streec.c rand1.c -lm\n", 42 | "#I get three compiler warnings from ms, but everything should be fine\n", 43 | "#now I'll just move the program into the current working dir\n", 44 | "!mv msdir/ms .;" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "metadata": {}, 50 | "source": [ 51 | "### Install `scikit-learn`\n", 52 | "If you use anaconda or have gone through any of our other examples, you may already have these modules installed, but if not you can install with either of the following:" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "metadata": { 59 | "collapsed": true 60 | }, 61 | "outputs": [], 62 | "source": [ 63 | "!conda install scikit-learn --yes" 64 | ] 65 | }, 66 | { 67 | "cell_type": "markdown", 68 | "metadata": {}, 69 | "source": [ 70 | "or if you don't use `conda`, you can use `pip` to install scikit-learn with" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": null, 76 | "metadata": { 77 | "collapsed": true 78 | }, 79 | "outputs": [], 80 | "source": [ 81 | "!pip install -U scikit-learn" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "### Install `scikit-allel`\n", 89 | "See https://scikit-allel.readthedocs.io/en/latest/, but this is easy to do if you have anaconda installed:" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": null, 95 | "metadata": { 96 | "collapsed": true 97 | }, 98 | "outputs": [], 99 | "source": [ 100 | "!conda install -c conda-forge scikit-allel --yes" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "Alternatively, you could use pip, provided you have already installed the following dependencies: numpy, scipy, matplotlib, seaborn, pandas, scikit-learn, h5py, numexpr, bcolz, zarr and dask. " 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": null, 113 | "metadata": { 114 | "collapsed": true 115 | }, 116 | "outputs": [], 117 | "source": [ 118 | "!pip install scikit-allel" 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": {}, 124 | "source": [ 125 | "# Step 1: create a training set and a testing set\n", 126 | "We will use `ms` and its `tbs` feature to generate 10000 replicates each with its own randomly selected recombination rate. Let's start by drawing the rates and recording them in a file." 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "execution_count": 2, 132 | "metadata": { 133 | "collapsed": true 134 | }, 135 | "outputs": [], 136 | "source": [ 137 | "import random\n", 138 | "\n", 139 | "with open(\"random_pop_size.sizes\", \"w\") as f:\n", 140 | " for i in range(10000):\n", 141 | " #we will let the present:ancient ratio range from 0.1 to 10\n", 142 | " popSize = 10**(random.random()*2-1)\n", 143 | " f.write(\"%f\\n\" %(popSize))\n" 144 | ] 145 | }, 146 | { 147 | "cell_type": "markdown", 148 | "metadata": {}, 149 | "source": [ 150 | "Now that we have our rates in hand we will feed them into `ms` and perform our simulations." 151 | ] 152 | }, 153 | { 154 | "cell_type": "code", 155 | "execution_count": 5, 156 | "metadata": { 157 | "collapsed": true 158 | }, 159 | "outputs": [], 160 | "source": [ 161 | "#simulate under the various two epoch models where ancient population size is determined at random from list made above\n", 162 | "!./ms 20 10000 -t 100 -r 100 10000 -en 0.5 1 tbs < random_pop_size.sizes > random_pop_size.msOut" 163 | ] 164 | }, 165 | { 166 | "cell_type": "markdown", 167 | "metadata": {}, 168 | "source": [ 169 | "Now we have to read in our simulation output and convert it into a data structure used by `scikit-allel` called a HaplotypeArray. The script msTools.py which we have included in this repository does this for us. Then we can calculate our statistics for each replicate. This is slow, so be patient.\n", 170 | "\n", 171 | "(One weird trick: we have to map our polymorphisms from a contiuous space to discrete space in order to use `scikit-allel`. The code below does that but we have to specify a number of sites we are mapping too, which must be greater than the number of polymorphisms. The 10000 sites we specified for `ms`'s recombination routine should suffice.)" 172 | ] 173 | }, 174 | { 175 | "cell_type": "code", 176 | "execution_count": null, 177 | "metadata": { 178 | "collapsed": true 179 | }, 180 | "outputs": [], 181 | "source": [ 182 | "from msTools import *\n", 183 | "import numpy as np\n", 184 | "import sys, allel\n", 185 | "\n", 186 | "totalPhysLen=10000\n", 187 | "hapArraysIn, positionArrays = msOutToHaplotypeArrayIn(\"random_pop_size.msOut\", totalPhysLen)\n", 188 | "X = []\n", 189 | "for i in range(len(hapArraysIn)):\n", 190 | " if i % 1000 == 0:\n", 191 | " sys.stdout.write(\"done with %d instances\\n\" %(i))\n", 192 | " #some of the statistics that we are going to calculate here require a HaplotypeArray as input, made thusly\n", 193 | " haps = allel.HaplotypeArray(hapArraysIn[i], dtype='i1')\n", 194 | " \n", 195 | " #others require an AlleleCountsArray, which contains the minor allele frequencu for each polymorphism\n", 196 | " #First we need to make GenotypeArray as an intermediate\n", 197 | " genos = haps.to_genotypes(ploidy=2)\n", 198 | " ac = genos.count_alleles()\n", 199 | " \n", 200 | " #now we build our feature vector, using various statistics calculated by scikit-allel.\n", 201 | " #for more information on the usage of these see https://scikit-allel.readthedocs.io/en/latest/\n", 202 | " currVec = []\n", 203 | " currVec.append(allel.stats.diversity.tajima_d(ac, pos=positionArrays[i]))# Tajima's D\n", 204 | " currVec.append(allel.stats.diversity.sequence_diversity(positionArrays[i], ac))# pi\n", 205 | " currVec.append(allel.stats.diversity.watterson_theta(positionArrays[i], ac))# theta W\n", 206 | " currVec.append(allel.stats.selection.garud_h(haps)[0])# avg. haplotype homozygosity\n", 207 | " \n", 208 | " X.append(currVec)\n", 209 | "\n", 210 | "X = np.array(X)\n", 211 | "\n", 212 | "#reading in our target output\n", 213 | "Y = np.loadtxt(\"random_pop_size.sizes\")\n", 214 | "\n", 215 | "#now split our data into training and test sets\n", 216 | "from sklearn.model_selection import train_test_split\n", 217 | "X_train, X_test, Y_train, Y_test = train_test_split(X,Y,test_size=0.1)\n" 218 | ] 219 | }, 220 | { 221 | "cell_type": "code", 222 | "execution_count": 3, 223 | "metadata": { 224 | "collapsed": true 225 | }, 226 | "outputs": [], 227 | "source": [ 228 | "#the last step in this process will be to shuffle the data, and then split it into a training set and a testing set\n", 229 | "#the testing set will NOT be used during training, and will allow us to check how well the classifier is doing\n", 230 | "#scikit-learn has a very convenient function for doing this shuffle and split operation\n", 231 | "#\n", 232 | "# will will keep out 10% of the data for testing\n", 233 | "\n", 234 | "from sklearn.model_selection import train_test_split\n", 235 | "X_train, X_test, Y_train, Y_test = train_test_split(X,Y,test_size=0.1)" 236 | ] 237 | }, 238 | { 239 | "cell_type": "markdown", 240 | "metadata": {}, 241 | "source": [ 242 | "# Step 2: train our regressor\n", 243 | "Now that we have a training and testing set ready to go, we can move on to training our regressor. For this example we will use a random forest regressor as implemented by `scikit-learn`." 244 | ] 245 | }, 246 | { 247 | "cell_type": "code", 248 | "execution_count": null, 249 | "metadata": { 250 | "collapsed": true 251 | }, 252 | "outputs": [], 253 | "source": [ 254 | "from sklearn.ensemble import RandomForestRegressor\n", 255 | "from sklearn import svm\n", 256 | "\n", 257 | "clf = RandomForestRegressor(n_estimators=100,n_jobs=10)\n", 258 | "clf.fit(X_train, Y_train)" 259 | ] 260 | }, 261 | { 262 | "cell_type": "markdown", 263 | "metadata": {}, 264 | "source": [ 265 | "Piece of cake!" 266 | ] 267 | }, 268 | { 269 | "cell_type": "markdown", 270 | "metadata": {}, 271 | "source": [ 272 | "# Step 3: benchmark our classifier\n", 273 | "Since we are doing regression, a sensible place to start might be to plot our true versus predicted values on our independent test set." 274 | ] 275 | }, 276 | { 277 | "cell_type": "code", 278 | "execution_count": 5, 279 | "metadata": {}, 280 | "outputs": [ 281 | { 282 | "data": { 283 | "image/png": "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\nAAAASUVORK5CYII=\n", 284 | "text/plain": [ 285 | "" 286 | ] 287 | }, 288 | "metadata": {}, 289 | "output_type": "display_data" 290 | } 291 | ], 292 | "source": [ 293 | "#now the actual work\n", 294 | "#first get the predictions\n", 295 | "preds=clf.predict(X_test)\n", 296 | "\n", 297 | "#now plot them\n", 298 | "import matplotlib.pyplot as plt\n", 299 | "fig,ax= plt.subplots(1,1)\n", 300 | "ax.scatter(Y_test, preds)\n", 301 | "ax.set_xlabel(\"True ancestral/current pop size ratio\")\n", 302 | "ax.set_ylabel(\"Predicted ancestral/current pop size ratio\")\n", 303 | "ax.set_xscale(\"log\")\n", 304 | "ax.set_yscale(\"log\")\n", 305 | "plt.show()" 306 | ] 307 | }, 308 | { 309 | "cell_type": "markdown", 310 | "metadata": {}, 311 | "source": [ 312 | "Not too shabby! Let's look at some quantitative measures of this fit. In particular we will look at the mean squared error (lower is better) and the variance explained by the regression (a.k.a. R^2 -- 1 would be perfect)" 313 | ] 314 | }, 315 | { 316 | "cell_type": "code", 317 | "execution_count": 13, 318 | "metadata": {}, 319 | "outputs": [ 320 | { 321 | "name": "stdout", 322 | "output_type": "stream", 323 | "text": [ 324 | "mean square error = 0.489478484226\n", 325 | "R^2 = 0.92324762797\n" 326 | ] 327 | } 328 | ], 329 | "source": [ 330 | "print 'mean squared error = ',np.mean((preds-Y_test)**2)\n", 331 | "print 'R^2 = ', clf.score(X_test, Y_test)" 332 | ] 333 | }, 334 | { 335 | "cell_type": "markdown", 336 | "metadata": {}, 337 | "source": [ 338 | "So this is doing quite well indeed." 339 | ] 340 | } 341 | ], 342 | "metadata": { 343 | "kernelspec": { 344 | "display_name": "Python 2", 345 | "language": "python", 346 | "name": "python2" 347 | }, 348 | "language_info": { 349 | "codemirror_mode": { 350 | "name": "ipython", 351 | "version": 2 352 | }, 353 | "file_extension": ".py", 354 | "mimetype": "text/x-python", 355 | "name": "python", 356 | "nbconvert_exporter": "python", 357 | "pygments_lexer": "ipython2", 358 | "version": "2.7.13" 359 | } 360 | }, 361 | "nbformat": 4, 362 | "nbformat_minor": 2 363 | } 364 | -------------------------------------------------------------------------------- /demographicModelSelectionExample.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Using a random forest for demographic model selection\n", 8 | "In Schrider and Kern (2017) we give a toy example of demographic model selection via supervised machine learning in Figure Box 1. Following a discussion on twitter, Vince Buffalo had the great idea of our providing a simple example of supervised ML in population genetics using a jupyter notebook; this notebook aims to serve that purpose by showing you exactly how we produced that figure in our paper" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "metadata": {}, 14 | "source": [ 15 | "## Preliminaries\n", 16 | "The road map here will be to 1) do some simulation of three demographic models, 2) to train a classifier to distinguish among those models, 3) test that classifier with new simulation data, and 4) to graphically present how well our trained classifier works. \n", 17 | "\n", 18 | "To do this we will use coalescent simulations as implemented in Dick Hudson's well known `ms` software and for the ML side of things we will use the `scikit-learn` package. Let's start by installing these dependencies (if you don't have them installed already)" 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": {}, 24 | "source": [ 25 | "### Install, and compile `ms`\n", 26 | "We have put a copy of the `ms` tarball in this repo, so the following should work upon cloning" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": 1, 32 | "metadata": { 33 | "collapsed": true, 34 | "scrolled": true 35 | }, 36 | "outputs": [], 37 | "source": [ 38 | "#untar and compile ms and sample_stats\n", 39 | "!tar zxf ms.tar.gz; cd msdir; gcc -o ms ms.c streec.c rand1.c -lm; gcc -o sample_stats sample_stats.c tajd.c -lm\n", 40 | "#I get three compiler warnings from ms, but everything should be fine\n", 41 | "#now I'll just move the programs into the current working dir\n", 42 | "!mv msdir/ms . ; mv msdir/sample_stats .;" 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": {}, 48 | "source": [ 49 | "### Install `scikit-learn`\n", 50 | "If you use anaconda, you may already have these modules installed, but if not you can install with either of the following" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": null, 56 | "metadata": { 57 | "collapsed": true 58 | }, 59 | "outputs": [], 60 | "source": [ 61 | "!conda install scikit-learn --yes" 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "or if you don't use `conda`, you can use `pip` to install scikit-learn with" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": null, 74 | "metadata": { 75 | "collapsed": true 76 | }, 77 | "outputs": [], 78 | "source": [ 79 | "!pip install -U scikit-learn" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "metadata": {}, 85 | "source": [ 86 | "# Step 1: create a training set and a testing set\n", 87 | "We will create a training set using simulations from three different demographic models: equilibrium population size, instantaneous population growth, and instantaneous population contraction. As you'll see this is really just a toy example because we will perform classification based on data from a single locus; in practice this would be ill-advised and you would want to use data from many loci simulataneously. \n", 88 | "\n", 89 | "So lets do some simulation using `ms` and summarize those simulations using the `sample_stats` program that Hudson provides. Ultimately we will only use two summary stats for classification, but one could use many more. Each of these simulations should take a few seconds to run." 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": 2, 95 | "metadata": { 96 | "collapsed": true 97 | }, 98 | "outputs": [], 99 | "source": [ 100 | "#simulate under the equilibrium model\n", 101 | "!./ms 20 2000 -t 100 -r 100 10000 | ./sample_stats > equilibrium.msOut.stats" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": 3, 107 | "metadata": { 108 | "collapsed": true 109 | }, 110 | "outputs": [], 111 | "source": [ 112 | "#simulate under the contraction model\n", 113 | "!./ms 20 2000 -t 100 -r 100 10000 -en 0 1 0.5 -en 0.2 1 1 | ./sample_stats > contraction.msOut.stats" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": 4, 119 | "metadata": { 120 | "collapsed": true 121 | }, 122 | "outputs": [], 123 | "source": [ 124 | "#simulate under the growth model\n", 125 | "!./ms 20 2000 -t 100 -r 100 10000 -en 0.2 1 0.5 | ./sample_stats > growth.msOut.stats" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": 8, 131 | "metadata": { 132 | "collapsed": true 133 | }, 134 | "outputs": [], 135 | "source": [ 136 | "#now lets suck up the data columns we want for each of these files, and create one big training set; we will use numpy for this\n", 137 | "# note that we are only using two columns of the data- these correspond to segSites and Fay & Wu's H\n", 138 | "import numpy as np\n", 139 | "X1 = np.loadtxt(\"equilibrium.msOut.stats\",usecols=(3,9))\n", 140 | "X2 = np.loadtxt(\"contraction.msOut.stats\",usecols=(3,9))\n", 141 | "X3 = np.loadtxt(\"growth.msOut.stats\",usecols=(3,9))\n", 142 | "X = np.concatenate((X1,X2,X3))\n", 143 | "\n", 144 | "#create associated 'labels' -- these will be the targets for training\n", 145 | "y = [0]*len(X1) + [1]*len(X2) + [2]*len(X3)\n", 146 | "Y = np.array(y)\n" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": 9, 152 | "metadata": { 153 | "collapsed": true 154 | }, 155 | "outputs": [], 156 | "source": [ 157 | "#the last step in this process will be to shuffle the data, and then split it into a training set and a testing set\n", 158 | "#the testing set will NOT be used during training, and will allow us to check how well the classifier is doing\n", 159 | "#scikit-learn has a very convenient function for doing this shuffle and split operation\n", 160 | "#\n", 161 | "# will will keep out 10% of the data for testing\n", 162 | "\n", 163 | "from sklearn.model_selection import train_test_split\n", 164 | "X_train, X_test, Y_train, Y_test = train_test_split(X,Y,test_size=0.1)" 165 | ] 166 | }, 167 | { 168 | "cell_type": "markdown", 169 | "metadata": {}, 170 | "source": [ 171 | "# Step 2: train our classifier and visualize decision surface\n", 172 | "Now that we have a training and testing set ready to go, we can move on to training our classifier. For this example we will use a random forest classifier (Breiman 2001). This is all implemented in `scikit-learn` and so the code is very brief. " 173 | ] 174 | }, 175 | { 176 | "cell_type": "code", 177 | "execution_count": 10, 178 | "metadata": { 179 | "collapsed": true 180 | }, 181 | "outputs": [], 182 | "source": [ 183 | "from sklearn.ensemble import RandomForestClassifier\n", 184 | "\n", 185 | "rfClf = RandomForestClassifier(n_estimators=100,n_jobs=10)\n", 186 | "clf = rfClf.fit(X_train, Y_train)\n" 187 | ] 188 | }, 189 | { 190 | "cell_type": "markdown", 191 | "metadata": {}, 192 | "source": [ 193 | "That's it! The classifier is trained. This Random Forest classifer used 100 decision trees in its ensemble, a pretty large number considering that we are only using two summary stats to represent our data. Nevertheless it trains on the data very, very quickly.\n", 194 | "\n", 195 | "Confession: the real reason we are using only two summary statistics right here is because it makes it really easy to visualize that classifier's decision surface: which regions of the feature space would be assigned to which class? Let's have a look!\n", 196 | "\n", 197 | "(Note: I have increased the h argument for the call to `make_meshgrid` below, coarsening the contour plot in the interest of efficiency. Decreasing this will yield a smoother plot, but may take a while and use up a lot more memory. Adjust at your own risk!)" 198 | ] 199 | }, 200 | { 201 | "cell_type": "code", 202 | "execution_count": 17, 203 | "metadata": { 204 | "scrolled": true 205 | }, 206 | "outputs": [ 207 | { 208 | "data": { 209 | "image/png": "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\n", 210 | "text/plain": [ 211 | "" 212 | ] 213 | }, 214 | "metadata": {}, 215 | "output_type": "display_data" 216 | } 217 | ], 218 | "source": [ 219 | "from sklearn.preprocessing import normalize\n", 220 | "\n", 221 | "#These two functions (taken from scikit-learn.org) plot the decision boundaries for a classifier.\n", 222 | "def plot_contours(ax, clf, xx, yy, **params):\n", 223 | " Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])\n", 224 | " Z = Z.reshape(xx.shape)\n", 225 | " out = ax.contourf(xx, yy, Z, **params)\n", 226 | " return out\n", 227 | "\n", 228 | "def make_meshgrid(x, y, h=.05):\n", 229 | " x_min, x_max = x.min() - 1, x.max() + 1\n", 230 | " y_min, y_max = y.min() - 1, y.max() + 1\n", 231 | " xx, yy = np.meshgrid(np.arange(x_min, x_max, h),\n", 232 | " np.arange(y_min, y_max, h))\n", 233 | " return xx, yy\n", 234 | "\n", 235 | "#Let's do the plotting\n", 236 | "import matplotlib.pyplot as plt\n", 237 | "fig,ax= plt.subplots(1,1)\n", 238 | "X0, X1 = X[:, 0], X[:, 1]\n", 239 | "xx, yy = make_meshgrid(X0, X1, h=0.2)\n", 240 | "plot_contours(ax, clf, xx, yy, cmap=plt.cm.coolwarm, alpha=0.8)\n", 241 | "# plotting only a subset of our data to keep things from getting too cluttered\n", 242 | "ax.scatter(X_test[:200, 0], X_test[:200, 1], c=Y_test[:200], cmap=plt.cm.coolwarm, edgecolors='k')\n", 243 | "ax.set_xlabel(r\"$\\theta_{w}$\", fontsize=14)\n", 244 | "ax.set_ylabel(r\"Fay and Wu's $H$\", fontsize=14)\n", 245 | "ax.set_xticks(())\n", 246 | "ax.set_yticks(())\n", 247 | "ax.set_title(\"Classifier decision surface\", fontsize=14)\n", 248 | "plt.show()" 249 | ] 250 | }, 251 | { 252 | "cell_type": "markdown", 253 | "metadata": {}, 254 | "source": [ 255 | "Above we can see which regions of our feature space are assigned to each class: dark blue shaded areas will be classified as Equilibrium, faint blue as Contraction, and red as Growth. Note the non-linear decision surface. Looks pretty cool! And also illustrates how this type of classifier might be useful for discriminating among classes that are difficult to linearly separate. Also plotted are a subset of our test examples, as dots colored according to their true class. Looks like we are doing pretty well but have a few misclassifications. Would be nice to quantify this somehow, which brings us to...\n", 256 | "\n", 257 | "# Step 3: benchmark our classifier\n", 258 | "The last step of the process is to use our trained classifier to predict which demographic models our test data are drawn from. Recall that the classifier hasn't seen these test data so this should be a fair test of how well the classifier will perform on any new data we throw at it in the future. We will visualize performance using a confusion matrix. " 259 | ] 260 | }, 261 | { 262 | "cell_type": "code", 263 | "execution_count": 19, 264 | "metadata": {}, 265 | "outputs": [ 266 | { 267 | "data": { 268 | "image/png": "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\n", 269 | "text/plain": [ 270 | "" 271 | ] 272 | }, 273 | "metadata": {}, 274 | "output_type": "display_data" 275 | } 276 | ], 277 | "source": [ 278 | "#here's the confusion matrix function\n", 279 | "def makeConfusionMatrixHeatmap(data, title, trueClassOrderLs, predictedClassOrderLs, ax):\n", 280 | " data = np.array(data)\n", 281 | " data = normalize(data, axis=1, norm='l1')\n", 282 | " heatmap = ax.pcolor(data, cmap=plt.cm.Blues, vmin=0.0, vmax=1.0)\n", 283 | "\n", 284 | " for i in range(len(predictedClassOrderLs)):\n", 285 | " for j in reversed(range(len(trueClassOrderLs))):\n", 286 | " val = 100*data[j, i]\n", 287 | " if val > 50:\n", 288 | " c = '0.9'\n", 289 | " else:\n", 290 | " c = 'black'\n", 291 | " ax.text(i + 0.5, j + 0.5, '%.2f%%' % val, horizontalalignment='center', verticalalignment='center', color=c, fontsize=9)\n", 292 | "\n", 293 | " cbar = plt.colorbar(heatmap, cmap=plt.cm.Blues, ax=ax)\n", 294 | " cbar.set_label(\"Fraction of simulations assigned to class\", rotation=270, labelpad=20, fontsize=11)\n", 295 | "\n", 296 | " # put the major ticks at the middle of each cell\n", 297 | " ax.set_xticks(np.arange(data.shape[1]) + 0.5, minor=False)\n", 298 | " ax.set_yticks(np.arange(data.shape[0]) + 0.5, minor=False)\n", 299 | " ax.axis('tight')\n", 300 | " ax.set_title(title)\n", 301 | "\n", 302 | " #labels\n", 303 | " ax.set_xticklabels(predictedClassOrderLs, minor=False, fontsize=9, rotation=45)\n", 304 | " ax.set_yticklabels(reversed(trueClassOrderLs), minor=False, fontsize=9)\n", 305 | " ax.set_xlabel(\"Predicted class\")\n", 306 | " ax.set_ylabel(\"True class\")\n", 307 | " \n", 308 | "#now the actual work\n", 309 | "#first get the predictions\n", 310 | "preds=clf.predict(X_test)\n", 311 | "\n", 312 | "counts=[[0.,0.,0.],[0.,0.,0.],[0.,0.,0.]]\n", 313 | "for i in range(len(Y_test)):\n", 314 | " counts[Y_test[i]][preds[i]] += 1\n", 315 | "counts.reverse()\n", 316 | "classOrderLs=['equil','contraction','growth']\n", 317 | "\n", 318 | "#now do the plotting\n", 319 | "fig,ax= plt.subplots(1,1)\n", 320 | "makeConfusionMatrixHeatmap(counts, \"Confusion matrix\", classOrderLs, classOrderLs, ax)\n", 321 | "plt.show()" 322 | ] 323 | }, 324 | { 325 | "cell_type": "markdown", 326 | "metadata": {}, 327 | "source": [ 328 | "Looks pretty good. But can we make it better? Well a simple way might be to increase the number of features (i.e. summary statistics) we use as input. Let's give that a whirl using all of the output from Hudson's `sample_stats`" 329 | ] 330 | }, 331 | { 332 | "cell_type": "code", 333 | "execution_count": 20, 334 | "metadata": {}, 335 | "outputs": [ 336 | { 337 | "data": { 338 | "image/png": "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\n", 339 | "text/plain": [ 340 | "" 341 | ] 342 | }, 343 | "metadata": {}, 344 | "output_type": "display_data" 345 | } 346 | ], 347 | "source": [ 348 | "X1 = np.loadtxt(\"equilibrium.msOut.stats\",usecols=(1,3,5,7,9))\n", 349 | "X2 = np.loadtxt(\"contraction.msOut.stats\",usecols=(1,3,5,7,9))\n", 350 | "X3 = np.loadtxt(\"growth.msOut.stats\",usecols=(1,3,5,7,9))\n", 351 | "X = np.concatenate((X1,X2,X3))\n", 352 | "#create associated 'labels' -- these will be the targets for training\n", 353 | "y = [0]*len(X1) + [1]*len(X2) + [2]*len(X3)\n", 354 | "Y = np.array(y)\n", 355 | "X_train, X_test, Y_train, Y_test = train_test_split(X,Y,test_size=0.1)\n", 356 | "rfClf = RandomForestClassifier(n_estimators=100,n_jobs=10)\n", 357 | "clf = rfClf.fit(X_train, Y_train)\n", 358 | "preds=clf.predict(X_test)\n", 359 | "counts=[[0.,0.,0.],[0.,0.,0.],[0.,0.,0.]]\n", 360 | "for i in range(len(Y_test)):\n", 361 | " counts[Y_test[i]][preds[i]] += 1\n", 362 | "counts.reverse()\n", 363 | "fig,ax= plt.subplots(1,1)\n", 364 | "makeConfusionMatrixHeatmap(counts, \"Confusion matrix\", classOrderLs, classOrderLs, ax)\n", 365 | "plt.show()" 366 | ] 367 | }, 368 | { 369 | "cell_type": "markdown", 370 | "metadata": {}, 371 | "source": [ 372 | "Even better!\n", 373 | "\n", 374 | "Hopefully this simple example gives you the gist of how supervised ML can be used. In the future we will populate this GitHub repository with further examples that might be illustrative. " 375 | ] 376 | } 377 | ], 378 | "metadata": { 379 | "kernelspec": { 380 | "display_name": "Python 2", 381 | "language": "python", 382 | "name": "python2" 383 | }, 384 | "language_info": { 385 | "codemirror_mode": { 386 | "name": "ipython", 387 | "version": 2 388 | }, 389 | "file_extension": ".py", 390 | "mimetype": "text/x-python", 391 | "name": "python", 392 | "nbconvert_exporter": "python", 393 | "pygments_lexer": "ipython2", 394 | "version": "2.7.13" 395 | } 396 | }, 397 | "nbformat": 4, 398 | "nbformat_minor": 2 399 | } 400 | -------------------------------------------------------------------------------- /ms.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/andrewkern/popGenMachineLearningExamples/3c659ea7b6a46e26fc8c0aa2230962dd4686bc89/ms.tar.gz -------------------------------------------------------------------------------- /msTools.py: -------------------------------------------------------------------------------- 1 | import sys, gzip, bisect 2 | 3 | def sortedFlankingPositionsByDistToTargSite(targetPos, flankingPositionsToExamine, desiredNumPositions, physLen): 4 | i=1 5 | sortedFlankingPositions = [] 6 | 7 | while len(sortedFlankingPositions) < desiredNumPositions: 8 | lPos = targetPos-i 9 | rPos = targetPos+i 10 | if lPos >= 0 and lPos in flankingPositionsToExamine: 11 | sortedFlankingPositions.append(lPos) 12 | if rPos < physLen and rPos in flankingPositionsToExamine and len(sortedFlankingPositions) < desiredNumPositions: 13 | sortedFlankingPositions.append(rPos) 14 | i += 1 15 | 16 | return sortedFlankingPositions 17 | 18 | def getNearestEmptyPositions(donorPos, snpCountAtPos, physLen): 19 | numColliders = snpCountAtPos[donorPos]-1 20 | 21 | freeSlots = {} 22 | for pos in snpCountAtPos: 23 | if snpCountAtPos[pos] == 0: 24 | freeSlots[pos] = 1 25 | assert len(freeSlots) >= numColliders 26 | 27 | return sortedFlankingPositionsByDistToTargSite(donorPos, freeSlots, numColliders, physLen) 28 | 29 | def resolveCollision(donorPos, snpCountAtPos, physLen): 30 | for recipientPos in getNearestEmptyPositions(donorPos, snpCountAtPos, physLen): 31 | snpCountAtPos[recipientPos] += 1 32 | assert snpCountAtPos[recipientPos] == 1 33 | snpCountAtPos[donorPos] -= 1 34 | 35 | def msPositionsToIntegerPositions(positions, physLen): 36 | assert physLen >= len(positions) 37 | 38 | snpCountAtPos = {} 39 | for i in range(physLen): 40 | snpCountAtPos[i] = 0 41 | for position in positions: 42 | intPos = int(physLen*position) 43 | if intPos == physLen: 44 | intPos = physLen-1 45 | snpCountAtPos[intPos] += 1 46 | 47 | collisions = {} 48 | for pos in snpCountAtPos: 49 | if snpCountAtPos[pos] > 1: 50 | collisions[pos] = 1 51 | 52 | midPos = physLen/2 53 | collisionPositions = [] 54 | midHasCollision=0 55 | if midPos in collisions: 56 | collisionPositions.append(midPos) 57 | midHasCollision=1 58 | collisionPositions += sortedFlankingPositionsByDistToTargSite(midPos, collisions, len(collisions)-midHasCollision, physLen) 59 | for pos in collisionPositions: 60 | resolveCollision(pos, snpCountAtPos, physLen) 61 | 62 | assert max(snpCountAtPos.values()) == 1 63 | newPositions = [x for x in sorted(snpCountAtPos) if snpCountAtPos[x] > 0] 64 | assert newPositions[0] >= 0 and newPositions[-1] < physLen 65 | 66 | return newPositions 67 | 68 | def msRepToHaplotypeArrayIn(samples, positions, totalPhysLen): 69 | for i in range(len(samples)): 70 | assert len(samples[i]) == len(positions) 71 | 72 | positions = msPositionsToIntegerPositions(positions, totalPhysLen) 73 | 74 | hapArrayIn = [] 75 | for j in range(len(positions)): 76 | hapArrayIn.append([]) 77 | for i in range(len(samples)): 78 | hapArrayIn[j].append(samples[i][j]) 79 | return hapArrayIn, positions 80 | 81 | def msOutToHaplotypeArrayIn(msOutputFileName, totalPhysLen): 82 | if msOutputFileName == "stdin": 83 | isFile = False 84 | msStream = sys.stdin 85 | else: 86 | isFile = True 87 | if msOutputFileName.endswith(".gz"): 88 | msStream = gzip.open(msOutputFileName) 89 | else: 90 | msStream = open(msOutputFileName) 91 | 92 | header = msStream.readline() 93 | program,numSamples,numSims = header.strip().split()[:3] 94 | numSamples,numSims = int(numSamples),int(numSims) 95 | 96 | hapArraysIn = [] 97 | positionArrays = [] 98 | #advance to first simulation 99 | line = msStream.readline() 100 | while not line.strip().startswith("//"): 101 | line = msStream.readline() 102 | while line: 103 | if not line.strip().startswith("//"): 104 | sys.exit("Malformed ms-style output file: read '%s' instead of '//'. AAAARRRRGGHHH!!!!!\n" %(line.strip())) 105 | segsitesBlah,segsites = msStream.readline().strip().split() 106 | segsites = int(segsites) 107 | if segsitesBlah != "segsites:": 108 | sys.exit("Malformed ms-style output file. AAAARRRRGGHHH!!!!!\n") 109 | 110 | positionsLine = msStream.readline().strip().split() 111 | if not positionsLine[0] == "positions:": 112 | sys.exit("Malformed ms-style output file. AAAARRRRGGHHH!!!!!\n") 113 | positions = [float(x) for x in positionsLine[1:]] 114 | 115 | samples = [] 116 | for i in range(numSamples): 117 | sampleLine = msStream.readline().strip() 118 | if len(sampleLine) != segsites: 119 | sys.exit("Malformed ms-style output file %s segsites but %s columns in line: %s; line %s of %s samples AAAARRRRGGHHH!!!!!\n" %(segsites,len(sampleLine),sampleLine,i,numSamples)) 120 | samples.append(sampleLine) 121 | if len(samples) != numSamples: 122 | raise Exception 123 | hapArrayIn, positions = msRepToHaplotypeArrayIn(samples, positions, totalPhysLen) 124 | hapArraysIn.append(hapArrayIn) 125 | positionArrays.append(positions) 126 | line = msStream.readline() 127 | #advance to the next non-empty line or EOF 128 | while line and line.strip() == "": 129 | line = msStream.readline() 130 | #sys.stderr.write("finished rep %d\n" %(len(hapArraysIn))) 131 | if len(hapArraysIn) != numSims: 132 | sys.exit("Malformed ms-style output file: %s of %s sims processed. AAAARRRRGGHHH!!!!!\n" %(len(hapArraysIn), numSims)) 133 | 134 | if isFile: 135 | msStream.close() 136 | return hapArraysIn, positionArrays 137 | --------------------------------------------------------------------------------