{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# How to Python at McGill\n", "\n", "Python is great because is has so many packages. However, you will quickly discover that installing packages without administrative privileges can become challenging. There is [virtualenv](http://www.virtualenv.org/en/latest/) that lets you install packages locally but it can be a nightmare when you have C librairies to build. If you want to do scientific computing with Python, I advise you to go with the [Anaconda](https://store.continuum.io/cshop/anaconda/) distribution. It will save you a great deal of time at McGill and will make the SOCS sysadmins life easier. " ] }, { "cell_type": "raw", "metadata": {}, "source": [ "$ chmod +x \n", "$ ./\n", "$ conda update conda\n", "$ conda update ipython" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Dataset\n", "\n", "For this demonstration, we will work on Jordan Frank's gait dataset. A complete description of the dataset can be found at http://www.cs.mcgill.ca/~jfrank8/data/gait-dataset.html" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%%bash\n", "curl -O http://www.cs.mcgill.ca/~jfrank8/data/gait-dataset.tar.gz\n", "tar xzf gait-dataset.tar.gz" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stderr", "text": [ " % Total % Received % Xferd Average Speed Time Time Time Current\n", " Dload Upload Total Spent Left Speed\n", "\r", " 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\r", " 0 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0\r", " 0 0 0 0 0 0 0 0 --:--:-- 0:00:02 --:--:-- 0\r", " 0 0 0 0 0 0 0 0 --:--:-- 0:00:03 --:--:-- 0\r", " 0 0 0 0 0 0 0 0 --:--:-- 0:00:04 --:--:-- 0\r", " 0 45.0M 0 1008 0 0 209 0 62:48:52 0:00:04 62:48:48 209\r", " 1 45.0M 1 636k 0 0 121k 0 0:06:18 0:00:05 0:06:13 153k\r", " 7 45.0M 7 3359k 0 0 540k 0 0:01:25 0:00:06 0:01:19 812k\r", " 12 45.0M 12 5990k 0 0 829k 0 0:00:55 0:00:07 0:00:48 1449k\r", " 18 45.0M 18 8366k 0 0 952k 0 0:00:48 0:00:08 0:00:40 1780k\r", " 20 45.0M 20 9292k 0 0 1007k 0 0:00:45 0:00:09 0:00:36 2109k\r", " 25 45.0M 25 11.7M 0 0 1174k 0 0:00:39 0:00:10 0:00:29 2274k\r", " 31 45.0M 31 14.3M 0 0 1308k 0 0:00:35 0:00:11 0:00:24 2264k\r", " 37 45.0M 37 16.9M 0 0 1423k 0 0:00:32 0:00:12 0:00:20 2280k\r", " 43 45.0M 43 19.6M 0 0 1521k 0 0:00:30 0:00:13 0:00:17 2650k\r", " 49 45.0M 49 22.3M 0 0 1607k 0 0:00:28 0:00:14 0:00:14 2714k\r", " 55 45.0M 55 25.0M 0 0 1685k 0 0:00:27 0:00:15 0:00:12 2731k\r", " 60 45.0M 60 27.2M 0 0 1719k 0 0:00:26 0:00:16 0:00:10 2633k\r", " 65 45.0M 65 29.6M 0 0 1763k 0 0:00:26 0:00:17 0:00:09 2593k\r", " 71 45.0M 71 32.2M 0 0 1815k 0 0:00:25 0:00:18 0:00:07 2591k\r", " 77 45.0M 77 34.9M 0 0 1860k 0 0:00:24 0:00:19 0:00:05 2577k\r", " 83 45.0M 83 37.6M 0 0 1904k 0 0:00:24 0:00:20 0:00:04 2571k\r", " 89 45.0M 89 40.3M 0 0 1946k 0 0:00:23 0:00:21 0:00:02 2691k\r", " 95 45.0M 95 43.0M 0 0 1981k 0 0:00:23 0:00:22 0:00:01 2735k\r", "100 45.0M 100 45.0M 0 0 2008k 0 0:00:22 0:00:22 --:--:-- 2746k\n" ] } ], "prompt_number": 1 }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Loading the data in Pandas\n", "\n", "We could also have chosen to load the data through [numpy.loadtxt](http://docs.scipy.org/doc/numpy/reference/generated/numpy.loadtxt.html). However, we will use fit an Autoregressive Moving Average [ARAMA](http://statsmodels.sourceforge.net/devel/generated/statsmodels.tsa.arima_model.ARMA.html) model using [statsmodels](http://statsmodels.sourceforge.net/) which tends to prefer Pandas dataframes." ] }, { "cell_type": "code", "collapsed": false, "input": [ "import statsmodels.api as sm\n", "import pandas as pd\n", "import os\n", "\n", "dta_path = 'gait-dataset'\n", "\n", "files_byday = lambda dta_path, day: [os.path.join(dta_path, name) \n", " for name in os.listdir(dta_path) \n", " if name.endswith('.csv') and 'day'+str(day) in name]\n", "day1 = files_byday(dta_path, 1)\n", "\n", "dta = pd.read_csv(day1[0], header=0, sep=\"\\t\", usecols=['timestamp', 'accel_mag'])\n", "dta.index = dta['timestamp'].astype('M8[ms]')\n", "del dta['timestamp']\n", "\n", "dta.plot(figsize=(12,8));" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "display_data", "png": "iVBORw0KGgoAAAANSUhEUgAAAsMAAAHXCAYAAABZI1dSAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3Xe41FT6B/DvACoWEBAp/riILjaKgK6KAm4sYENExcK6\nLlhXrLuiwqqrgA1XxUWx4VpwUXYtK6IIKi5BARUVLggqCtJ77/Xe/P6IYVp6TnKSyffzPPeZySQ5\n570zk+Sdk5OTjKZpGoiIiIiIUqiK7ACIiIiIiGRhMkxEREREqcVkmIiIiIhSi8kwEREREaUWk2Ei\nIiIiSi0mw0RERESUWoGS4UWLFuG0005D8+bN0aJFCzz11FMAgLVr16Jjx4448sgj0alTJ6xfv15I\nsEREREREImWCjDO8fPlyLF++HK1bt8bmzZtx/PHHY+TIkXjllVdQt25d3HXXXXj00Uexbt06DBw4\nUGTcRERERESBBWoZbtCgAVq3bg0AOOCAA3DMMcdgyZIlGDVqFHr06AEA6NGjB0aOHBk8UiIiIiIi\nwQK1DOeaP38+fve732HmzJlo3Lgx1q1bBwDQNA116tTZM01EREREFBdCLqDbvHkzLr74YgwePBg1\natTIm5fJZJDJZERUQ0REREQkVLWgBezatQsXX3wxrrzySnTt2hUAUL9+fSxfvhwNGjTAsmXLUK9e\nvaL1mjZtirlz5watnoiIiIjIVqtWrVBeXm46L1A3CU3T0KNHDxx00EF48skn97x+11134aCDDkKf\nPn0wcOBArF+/vugCukwmA0E9NIgSoV+/fujXr5/sMIhShdsdUbTius3Z5Z2BWoYnTZqE4cOH49hj\nj0WbNm0AAI888gj69u2LSy+9FC+99BKaNGmCN998M0g1RCVh/vz5skMgSh1ud0TRSuI2FygZbt++\nPSorK03njRs3LkjRRERERESh4x3oiCLSs2dP2SEQpQ63O6JoJXGbEza0mueK2WeYiIiIiCJgl3ey\nZZgoIqqqyg6BKHW43ZFIderU2TNkLP/i+VenTh3Pn2vgodWIiIiI0mDdunU8qx1zfu5twW4SRERE\nRC4wd4k/q8+I3SSIiIiIiEwwGSaKCPsuEkWP2x0ROWEyTERERESuValSBb/88ovsMIRhn2EiIiIi\nF5i76KpUqYI5c+bg8MMPlx1KEfYZJiIiIiLygMkwUUTYd5EoetzuKC0GDhyIpk2bombNmmjevDlG\njhy5Z96LL76IZs2a7Zk3bdo0AMCiRYtw0UUXoV69eqhbty5uueWWPeu8/PLLaNasGerUqYOzzz4b\nCxcu9BRPz549ceONN+Lcc89FjRo10KFDByxfvhy33XYbateujWOOOQbl5eWu4q+srETv3r1x8MEH\n4/DDD8eQIUNQpUoVVFZW+n278jAZJiIiIkq4pk2bYuLEidi4cSPuv/9+/OEPf8Dy5cvx1ltvoX//\n/vjXv/6FjRs3YtSoUTjooINQUVGBzp0747DDDsOCBQuwZMkSXH755QCA9957D4888gjeffddrF69\nGh06dED37t09x/TWW2/hoYcewurVq7H33nujbdu2OOGEE7B27Vp069YNt99+u238K1asAAAMHToU\nY8eOxfTp0zF16lSMHDnS13jCVthnmIiIiMgFp9xFVH4mIj1q06YN+vfvj2effRbnnXdeXqsvAHzx\nxRe44IILsHz5clSpkt82es455+CSSy7B1VdfDUBvma1RowZ+/PFHlJWVueozfNVVV2HvvffGCy+8\nAAAYMmQInnvuOcyaNQsA8N133+HUU0/FunXrLOMfMGAAzj//fJx++uno3r07rrvuOgDAp59+io4d\nO2L37t1FsbPPMBEREZEkmibmz4/XXnsNbdq0Qe3atVG7dm3MnDkTq1evxqJFi/Cb3/ymaPlFixbh\n0EMPLUomAWDBggV7ujPUrl0bBx10EABgyZIlnmKqV6/enufVq1fPm953332xefNmx/gBYNmyZSgr\nK9uzbKNGjTzF4YTJMFFE2HeRKHrc7igNFixYgOuvvx7PPPMM1q5di3Xr1qFFixbQNA1lZWWYM2dO\n0TplZWVYuHAhKioqiuY1btwYQ4cOxbp16/b8bdmyBW3bto08fgBo2LAhFi1atGf53OciMBkmIiIi\nSrAtW7Ygk8mgbt26qKysxCuvvIKZM2cik8ng2muvxeOPP46pU6dC0zTMmTMHCxcuxEknnYSGDRui\nb9++2Lp1K7Zv347JkycDAG644QY8/PDD+P777wEAGzZswFtvveUpJi9dYa3iN1x66aUYPHgwli5d\nivXr1+PRRx8V2meYyTBRRBRFkR0CUepwu6M0aNasGXr37o2TTz4ZDRo0wMyZM9G+fXsAQLdu3XDP\nPffg97//PWrWrImLLroI69atQ5UqVfD+++9jzpw5aNy4McrKyvDmm28CALp27Yo+ffrg8ssvx4EH\n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\n", "text": [ "" ] } ], "prompt_number": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Feature extraction\n", "\n", "We will attempt to differentiate people using only the magniture of the accelerometer values. The idea will be to produce features using a local ARMA model which will then be leveraged for classification using an SVM. We will fist tackle the problem of iterating through sliding windows." ] }, { "cell_type": "code", "collapsed": false, "input": [ "def arma_featurizer(filename, nwin=500, nparam=2):\n", " import numpy as np\n", " import pandas as pd\n", " import statsmodels.api as sm\n", "\n", " dta = pd.read_csv(filename, header=0, sep=\"\\t\", usecols=['timestamp', 'accel_mag'])\n", " dta.index = pd.to_datetime(dta['timestamp'], unit='ms')\n", " del dta['timestamp']\n", "\n", " nwin, nparam = 10, nparam\n", " X = np.zeros((nwin, nparam+1))\n", " for i, subseries in enumerate(np.array_split(dta, nwin)):\n", " model = sm.tsa.ARMA(subseries, (nparam,0)).fit()\n", " X[i] = model.params\n", " \n", " return X" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 3 }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can start a local cluster with two engines using the following shell command:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "!ipcluster start -n=2 --daemon" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "2014-04-15 11:15:23.944 [IPClusterStart] Using existing profile dir: u'/Users/pierrelucbacon/.ipython/profile_default'\r\n" ] } ], "prompt_number": 4 }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython import parallel\n", "rc = parallel.Client()\n", "rc.block = True\n", "all_engines = rc[:]" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 5 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Similar to the idea to the corresponding idea in database, we access the cluster through either a [DirectView](http://ipython.org/ipython-doc/stable/parallel/parallel_multiengine.html#creating-a-directview-instance) or [LoadBalancedView](http://ipython.org/ipython-doc/stable/parallel/parallel_task.html#creating-a-loadbalancedview-instance)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can now map an array of filenames through the ARMA featurizer. A different parellization model could have been chosen by mapping windows to engines. However, I would expect it creates more overhead than it saves computing time. In the code below, we will instead map the full time series associated with one person to one single engine. Within one engine, the local ARMA models will be computed sequentially." ] }, { "cell_type": "code", "collapsed": false, "input": [ "Y = all_engines.map(arma_featurizer, day1[:2])" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 6 }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Classification\n", "\n", "In order to assess the performance of our classifier, we will use stratified kfold cross-validation. Using the ARMA features that we computed above, we will form the matrix of *instances* $X$ and corresponding label vector $y$. In order to minimize the data exchange over the network, we will upload the dataset to the cluster and open a mmap view in each engine. " ] }, { "cell_type": "code", "collapsed": false, "input": [ "def fit_svm(fold):\n", " import numpy as np\n", " from sklearn import svm\n", " from sklearn.metrics import accuracy_score\n", "\n", " X = np.load('instances.npy', mmap_mode='r')\n", " y = np.load('labels.npy', mmap_mode='r')\n", " train, test = fold\n", "\n", " clf = svm.SVC()\n", " clf.fit(X[train], y[train])\n", " ypred = clf.predict(X[test])\n", " return accuracy_score(y[test], ypred)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 7 }, { "cell_type": "code", "collapsed": false, "input": [ "from sklearn import cross_validation\n", "\n", "np.save('instances', np.vstack(Y))\n", "labels = np.repeat(range(len(Y)), len(Y[0]))\n", "np.save('labels', labels)\n", "\n", "accuracy_scores = all_engines.map(fit_svm, cross_validation.StratifiedKFold(labels, n_folds=2))" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 8 }, { "cell_type": "code", "collapsed": false, "input": [ "print accuracy_scores" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[0.90000000000000002, 0.69999999999999996]\n" ] } ], "prompt_number": 9 }, { "cell_type": "code", "collapsed": false, "input": [ "!ipcluster stop" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "2014-04-15 11:17:37.881 [IPClusterStop] Using existing profile dir: u'/Users/pierrelucbacon/.ipython/profile_default'\r\n" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "2014-04-15 11:17:37.917 [IPClusterStop] Stopping cluster [pid=4463] with [signal=2]\r\n" ] } ], "prompt_number": 10 }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Amazon Elastic Compute Cloud (EC2)\n", "\n", "We will use the Amazon Elastic Compute Cloud (Amazon EC2) infrastructure to deploy our cluster. This will require you to create an account at https://aws.amazon.com/ec2/ and enter payment details. Fortunately, you won't have to pay much more than a few dollars for each experiment. To give you an idea of the prices, you can take a look at https://aws.amazon.com/ec2/pricing/. The pricing model is per hour of compute time and depends on the hardware that you choose. \n", "\n", "Depending on the robustness of your code, you can also go with the *spot instances* model where you bid for hardware resources. The drawback is that you might wait indefinitely long of your precious experiment might get shutdown because another client outbid your price. You help place an educated guess, you can use the `spothistory` subcommand:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Starcluster\n", "\n", "You can install Starcluster autmatically from conda or PIP using:" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "$ pip install starcluster" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A default configuration file can be created by calling `starcluster` and choosing \"2\" at the menu:" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "$ starcluster help\n", "StarCluster - (http://web.mit.edu/starcluster)\n", "Software Tools for Academics and Researchers (STAR)\n", "Please submit bug reports to starcluster@mit.edu\n", "\n", "cli.py:87 - ERROR - config file /home/user/.starcluster/config does not exist\n", "\n", "Options:\n", "--------\n", "[1] Show the StarCluster config template\n", "[2] Write config template to /home/user/.starcluster/config\n", "[q] Quit\n", "\n", "Please enter your selection:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "In order to use IPython with Starcluster, you will need to add the following section to your `.starcluster/.config/`. As a reference, I have put my config file here https://gist.github.com/pierrelux/10695188" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "[plugin ipcluster]\n", "setup_class = starcluster.plugins.ipcluster.IPCluster" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "and add `ipcluster` to the list of plugins to load" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "PLUGINS = ipcluster" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also set the default type of instances through the `NODE_INSTANCE_TYPE` directive. For example:" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "NODE_INSTANCE_TYPE = m1.small" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You will need to set the name of the SSH key that you wish to install on the cluster. Here \"rllab\" is the name of an existing SSH key created under `.ssh/rllab.rsa`" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "[key rllab]\n", "KEY_LOCATION=~/.ssh/rllab.rsa\n", "KEYNAME = rllab" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can create an RSA key as follow:" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "$ starcluster createkey mykey -o ~/.ssh/rllab.rsa" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "$ starcluster spothistory m1.small\n", "StarCluster - (http://star.mit.edu/cluster) (v. 0.95.2)\n", "Software Tools for Academics and Researchers (STAR)\n", "Please submit bug reports to starcluster@mit.edu\n", "\n", ">>> Fetching spot history for m1.small (VPC)\n", ">>> Current price: $0.0071\n", ">>> Max price: $0.5000\n", ">>> Average price: $0.0459" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can then start a 2 nodes cluster on spotinstances with the command:" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "$ starcluster start -s 2 -b 0.05 rllab" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "After a little while, you should have a cluster up and running to which you can SSH using:" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "$ starcluster sshmaster rllab -u sgeadmin" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Local notebook, remote cluster\n", "\n", "You can choose to run IPython notebook completly remotly on the cluster or use connect your local instance to the remote ipcluster engines. In this case, the only modification to our code consists in:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "rc = parallel.Client('/Users/pierrelucbacon/.starcluster/ipcluster/SecurityGroup:@sc-rllab-us-east-1.json', sshkey='/Users/pierrelucbacon/.ssh/rllab.rsa') \n", "rc.block = True\n", "all_engines = rc[:]" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 11 }, { "cell_type": "code", "collapsed": false, "input": [ "%%px\n", "!ifconfig eth0 | grep 'inet addr'" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[stdout:10] inet addr:172.31.40.36 Bcast:172.31.47.255 Mask:255.255.240.0\r\n", "[stdout:11] inet addr:172.31.37.163 Bcast:172.31.47.255 Mask:255.255.240.0\r\n", "[stdout:12] inet addr:172.31.41.111 Bcast:172.31.47.255 Mask:255.255.240.0\r\n", "[stdout:13] inet addr:172.31.41.229 Bcast:172.31.47.255 Mask:255.255.240.0\r\n", "[stdout:14] inet addr:172.31.41.85 Bcast:172.31.47.255 Mask:255.255.240.0\r\n", "[stdout:15] inet addr:172.31.44.187 Bcast:172.31.47.255 Mask:255.255.240.0\r\n", "[stdout:16] inet addr:172.31.39.207 Bcast:172.31.47.255 Mask:255.255.240.0\r\n", "[stdout:17] inet addr:172.31.45.236 Bcast:172.31.47.255 Mask:255.255.240.0\r\n", "[stdout:18] inet addr:172.31.41.187 Bcast:172.31.47.255 Mask:255.255.240.0\r\n", "[stdout:19] inet addr:172.31.38.164 Bcast:172.31.47.255 Mask:255.255.240.0\r\n" ] } ], "prompt_number": 12 }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Dataset provisioning\n", "\n", "When working with a remote cluster, you will probably need to first copy your dataset. The `DirectView` interview provides a dict-like mechanism to scatter the data on each engine. I prefer to avoid this solution since not only does it saturates my bandwidth, but it also creates memory duplicates. Since starcluster will setup an NFS share, it suffice to download the dataset from a single engine. Instead of uploading the dataset through SSH, we will fetch it from the cluster by running the following bash commands remotely:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%%px --targets=10\n", "%%bash\n", "curl -O http://www.cs.mcgill.ca/~jfrank8/data/gait-dataset.tar.gz\n", "tar xzf gait-dataset.tar.gz" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stderr", "text": [ " % Total % Received % Xferd Average Speed Time Time Time Current\n", " Dload Upload Total Spent Left Speed\n", "\r", " 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\r", " 0 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0\r", " 0 0 0 0 0 0 0 0 --:--:-- 0:00:02 --:--:-- 0\r", " 0 45.0M 0 1082 0 0 433 0 30:19:09 0:00:02 30:19:07 441\r", " 1 45.0M 1 727k 0 0 221k 0 0:03:28 0:00:03 0:03:25 224k\r", " 3 45.0M 3 1844k 0 0 430k 0 0:01:47 0:00:04 0:01:43 434k\r", " 6 45.0M 6 2970k 0 0 561k 0 0:01:22 0:00:05 0:01:17 704k\r", " 8 45.0M 8 4079k 0 0 648k 0 0:01:11 0:00:06 0:01:05 967k\r", " 11 45.0M 11 5194k 0 0 712k 0 0:01:04 0:00:07 0:00:57 1082k\r", " 13 45.0M 13 6296k 0 0 759k 0 0:01:00 0:00:08 0:00:52 1113k\r", " 15 45.0M 15 7284k 0 0 784k 0 0:00:58 0:00:09 0:00:49 1087k\r", " 18 45.0M 18 8352k 0 0 811k 0 0:00:56 0:00:10 0:00:46 1076k\r", " 20 45.0M 20 9451k 0 0 837k 0 0:00:55 0:00:11 0:00:44 1074k\r", " 22 45.0M 22 10.2M 0 0 852k 0 0:00:54 0:00:12 0:00:42 1056k\r", " 24 45.0M 24 11.2M 0 0 863k 0 0:00:53 0:00:13 0:00:40 1036k\r", " 27 45.0M 27 12.2M 0 0 877k 0 0:00:52 0:00:14 0:00:38 1050k\r", " 29 45.0M 29 13.2M 0 0 890k 0 0:00:51 0:00:15 0:00:36 1052k\r", " 31 45.0M 31 14.1M 0 0 890k 0 0:00:51 0:00:16 0:00:35 1010k\r", " 33 45.0M 33 14.9M 0 0 886k 0 0:00:52 0:00:17 0:00:35 967k\r", " 35 45.0M 35 15.8M 0 0 887k 0 0:00:51 0:00:18 0:00:33 950k\r", " 36 45.0M 36 16.4M 0 0 873k 0 0:00:52 0:00:19 0:00:33 863k\r", " 38 45.0M 38 17.3M 0 0 873k 0 0:00:52 0:00:20 0:00:32 821k\r", " 40 45.0M 40 18.1M 0 0 870k 0 0:00:52 0:00:21 0:00:31 807k\r", " 42 45.0M 42 19.0M 0 0 877k 0 0:00:52 0:00:22 0:00:30 845k\r", " 44 45.0M 44 20.0M 0 0 880k 0 0:00:52 0:00:23 0:00:29 855k\r", " 46 45.0M 46 21.0M 0 0 885k 0 0:00:52 0:00:24 0:00:28 931k\r", " 48 45.0M 48 22.0M 0 0 892k 0 0:00:51 0:00:25 0:00:26 969k\r", " 51 45.0M 51 23.0M 0 0 896k 0 0:00:51 0:00:26 0:00:25 1006k\r", " 53 45.0M 53 24.0M 0 0 903k 0 0:00:51 0:00:27 0:00:24 1021k\r", " 55 45.0M 55 25.1M 0 0 909k 0 0:00:50 0:00:28 0:00:22 1045k\r", " 58 45.0M 58 26.1M 0 0 915k 0 0:00:50 0:00:29 0:00:21 1063k\r", " 60 45.0M 60 27.3M 0 0 922k 0 0:00:50 0:00:30 0:00:20 1077k\r", " 62 45.0M 62 28.3M 0 0 928k 0 0:00:49 0:00:31 0:00:18 1098k\r", " 65 45.0M 65 29.4M 0 0 934k 0 0:00:49 0:00:32 0:00:17 1104k\r", " 67 45.0M 67 30.4M 0 0 935k 0 0:00:49 0:00:33 0:00:16 1083k\r", " 69 45.0M 69 31.4M 0 0 939k 0 0:00:49 0:00:34 0:00:15 1078k\r", " 72 45.0M 72 32.5M 0 0 943k 0 0:00:48 0:00:35 0:00:13 1068k\r", " 74 45.0M 74 33.5M 0 0 947k 0 0:00:48 0:00:36 0:00:12 1060k\r", " 76 45.0M 76 34.6M 0 0 950k 0 0:00:48 0:00:37 0:00:11 1054k\r", " 79 45.0M 79 35.7M 0 0 955k 0 0:00:48 0:00:38 0:00:10 1085k\r", " 81 45.0M 81 36.6M 0 0 954k 0 0:00:48 0:00:39 0:00:09 1059k\r", " 83 45.0M 83 37.7M 0 0 959k 0 0:00:48 0:00:40 0:00:08 1067k\r", " 86 45.0M 86 38.8M 0 0 962k 0 0:00:47 0:00:41 0:00:06 1076k\r", " 88 45.0M 88 39.8M 0 0 964k 0 0:00:47 0:00:42 0:00:05 1065k\r", " 90 45.0M 90 40.8M 0 0 967k 0 0:00:47 0:00:43 0:00:04 1058k\r", " 93 45.0M 93 41.9M 0 0 970k 0 0:00:47 0:00:44 0:00:03 1094k\r", " 95 45.0M 95 43.0M 0 0 973k 0 0:00:47 0:00:45 0:00:02 1086k\r", " 97 45.0M 97 44.1M 0 0 976k 0 0:00:47 0:00:46 0:00:01 1085k\r", "100 45.0M 100 45.0M 0 0 977k 0 0:00:47 0:00:47 --:--:-- 1092k\n" ] } ], "prompt_number": 13 }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Complete remote pipeline\n", "\n", "Let's now repeat the above experiment but run it completely on the cluster. As before, we first featurize the dataset and then cross-validate our results. " ] }, { "cell_type": "code", "collapsed": false, "input": [ "Y = all_engines.map(arma_featurizer, day1)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 17 }, { "cell_type": "code", "collapsed": false, "input": [ "np.save('instances', np.vstack(Y))\n", "labels = np.repeat(range(len(Y)), len(Y[0]))\n", "np.save('labels', labels)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 18 }, { "cell_type": "code", "collapsed": false, "input": [ "%%bash\n", "starcluster put rllab -u sgeadmin instances.npy /home/sgeadmin\n", "starcluster put rllab -u sgeadmin labels.npy /home/sgeadmin" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stderr", "text": [ "StarCluster - (http://star.mit.edu/cluster) (v. 0.95.4)\n", "Software Tools for Academics and Researchers (STAR)\n", "Please submit bug reports to starcluster@mit.edu\n", "\n", "instances.npy 0% | | ETA: --:--:-- 0.00 B/s\r", "instances.npy 100% |||||||||||||||||||||||||||||||||| Time: 00:00:00 1.95 M/s\n", "StarCluster - (http://star.mit.edu/cluster) (v. 0.95.4)\n", "Software Tools for Academics and Researchers (STAR)\n", "Please submit bug reports to starcluster@mit.edu\n", "\n", "labels.npy 0% | | ETA: --:--:-- 0.00 B/s\r", "labels.npy 100% ||||||||||||||||||||||||||||||||||||| Time: 00:00:00 793.25 K/s\n" ] } ], "prompt_number": 20 }, { "cell_type": "code", "collapsed": false, "input": [ "accuracy_scores = all_engines.map(fit_svm, cross_validation.StratifiedKFold(labels, n_folds=4))" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 24 }, { "cell_type": "code", "collapsed": false, "input": [ "print accuracy_scores" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "[0.23999999999999999, 0.29999999999999999, 0.23999999999999999, 0.22]\n" ] } ], "prompt_number": 23 }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }