{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# Artificial Intelligence Engineer Nanodegree - Probabilistic Models\n",
    "## Project: Sign Language Recognition System\n",
    "- [Introduction](#intro)\n",
    "- [Part 1 Feature Selection](#part1_tutorial)\n",
    "    - [Tutorial](#part1_tutorial)\n",
    "    - [Features Submission](#part1_submission)\n",
    "    - [Features Unittest](#part1_test)\n",
    "- [Part 2 Train the models](#part2_tutorial)\n",
    "    - [Tutorial](#part2_tutorial)\n",
    "    - [Model Selection Score Submission](#part2_submission)\n",
    "    - [Model Score Unittest](#part2_test)\n",
    "- [Part 3 Build a Recognizer](#part3_tutorial)\n",
    "    - [Tutorial](#part3_tutorial)\n",
    "    - [Recognizer Submission](#part3_submission)\n",
    "    - [Recognizer Unittest](#part3_test)\n",
    "- [Part 4 (OPTIONAL) Improve the WER with Language Models](#part4_info)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='intro'></a>\n",
    "## Introduction\n",
    "The overall goal of this project is to build a word recognizer for American Sign Language video sequences, demonstrating the power of probabalistic models.  In particular, this project employs  [hidden Markov models (HMM's)](https://en.wikipedia.org/wiki/Hidden_Markov_model) to analyze a series of measurements taken from videos of American Sign Language (ASL) collected for research (see the [RWTH-BOSTON-104 Database](http://www-i6.informatik.rwth-aachen.de/~dreuw/database-rwth-boston-104.php)).  In this video, the right-hand x and y locations are plotted as the speaker signs the sentence.\n",
    "[![ASLR demo](http://www-i6.informatik.rwth-aachen.de/~dreuw/images/demosample.png)](https://drive.google.com/open?id=0B_5qGuFe-wbhUXRuVnNZVnMtam8)\n",
    "\n",
    "The raw data, train, and test sets are pre-defined.  You will derive a variety of feature sets (explored in Part 1), as well as implement three different model selection criterion to determine the optimal number of hidden states for each word model (explored in Part 2). Finally, in Part 3 you will implement the recognizer and compare the effects the different combinations of feature sets and model selection criteria.  \n",
    "\n",
    "At the end of each Part, complete the submission cells with implementations, answer all questions, and pass the unit tests.  Then submit the completed notebook for review!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='part1_tutorial'></a>\n",
    "## PART 1: Data\n",
    "\n",
    "### Features Tutorial\n",
    "##### Load the initial database\n",
    "A data handler designed for this database is provided in the student codebase as the `AslDb` class in the `asl_data` module.  This handler creates the initial [pandas](http://pandas.pydata.org/pandas-docs/stable/) dataframe from the corpus of data included in the `data` directory as well as dictionaries suitable for extracting data in a format friendly to the [hmmlearn](https://hmmlearn.readthedocs.io/en/latest/) library.  We'll use those to create models in Part 2.\n",
    "\n",
    "To start, let's set up the initial database and select an example set of features for the training set.  At the end of Part 1, you will create additional feature sets for experimentation. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>left-x</th>\n",
       "      <th>left-y</th>\n",
       "      <th>right-x</th>\n",
       "      <th>right-y</th>\n",
       "      <th>nose-x</th>\n",
       "      <th>nose-y</th>\n",
       "      <th>speaker</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>video</th>\n",
       "      <th>frame</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"5\" valign=\"top\">98</th>\n",
       "      <th>0</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             left-x  left-y  right-x  right-y  nose-x  nose-y  speaker\n",
       "video frame                                                           \n",
       "98    0         149     181      170      175     161      62  woman-1\n",
       "      1         149     181      170      175     161      62  woman-1\n",
       "      2         149     181      170      175     161      62  woman-1\n",
       "      3         149     181      170      175     161      62  woman-1\n",
       "      4         149     181      170      175     161      62  woman-1"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from asl_data import AslDb\n",
    "\n",
    "\n",
    "asl = AslDb() # initializes the database\n",
    "asl.df.head() # displays the first five rows of the asl database, indexed by video and frame"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "left-x         149\n",
       "left-y         181\n",
       "right-x        170\n",
       "right-y        175\n",
       "nose-x         161\n",
       "nose-y          62\n",
       "speaker    woman-1\n",
       "Name: (98, 1), dtype: object"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "asl.df.ix[98,1]  # look at the data available for an individual frame"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The frame represented by video 98, frame 1 is shown here:  \n",
    "\n",
    "![Video 98](http://www-i6.informatik.rwth-aachen.de/~dreuw/database/rwth-boston-104/overview/images/orig/098-start.jpg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Feature selection for training the model\n",
    "The objective of feature selection when training a model is to choose the most relevant variables while keeping the model as simple as possible, thus reducing training time.  We can use the raw features already provided or derive our own and add columns to the pandas dataframe `asl.df` for selection. As an example, in the next cell a feature named `'grnd-ry'` is added. This feature is the difference between the right-hand y value and the nose y value, which serves as the \"ground\" right y value. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>left-x</th>\n",
       "      <th>left-y</th>\n",
       "      <th>right-x</th>\n",
       "      <th>right-y</th>\n",
       "      <th>nose-x</th>\n",
       "      <th>nose-y</th>\n",
       "      <th>speaker</th>\n",
       "      <th>grnd-ry</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>video</th>\n",
       "      <th>frame</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"5\" valign=\"top\">98</th>\n",
       "      <th>0</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "      <td>113</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "      <td>113</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "      <td>113</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "      <td>113</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "      <td>113</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             left-x  left-y  right-x  right-y  nose-x  nose-y  speaker  \\\n",
       "video frame                                                              \n",
       "98    0         149     181      170      175     161      62  woman-1   \n",
       "      1         149     181      170      175     161      62  woman-1   \n",
       "      2         149     181      170      175     161      62  woman-1   \n",
       "      3         149     181      170      175     161      62  woman-1   \n",
       "      4         149     181      170      175     161      62  woman-1   \n",
       "\n",
       "             grnd-ry  \n",
       "video frame           \n",
       "98    0          113  \n",
       "      1          113  \n",
       "      2          113  \n",
       "      3          113  \n",
       "      4          113  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "asl.df['grnd-ry'] = asl.df['right-y'] - asl.df['nose-y']\n",
    "asl.df.head()  # the new feature 'grnd-ry' is now in the frames dictionary"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Try it!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "asl.df sample\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>left-x</th>\n",
       "      <th>left-y</th>\n",
       "      <th>right-x</th>\n",
       "      <th>right-y</th>\n",
       "      <th>nose-x</th>\n",
       "      <th>nose-y</th>\n",
       "      <th>speaker</th>\n",
       "      <th>grnd-ry</th>\n",
       "      <th>grnd-rx</th>\n",
       "      <th>grnd-ly</th>\n",
       "      <th>grnd-lx</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>video</th>\n",
       "      <th>frame</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"5\" valign=\"top\">98</th>\n",
       "      <th>0</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "      <td>113</td>\n",
       "      <td>9</td>\n",
       "      <td>119</td>\n",
       "      <td>-12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "      <td>113</td>\n",
       "      <td>9</td>\n",
       "      <td>119</td>\n",
       "      <td>-12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "      <td>113</td>\n",
       "      <td>9</td>\n",
       "      <td>119</td>\n",
       "      <td>-12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "      <td>113</td>\n",
       "      <td>9</td>\n",
       "      <td>119</td>\n",
       "      <td>-12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "      <td>113</td>\n",
       "      <td>9</td>\n",
       "      <td>119</td>\n",
       "      <td>-12</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             left-x  left-y  right-x  right-y  nose-x  nose-y  speaker  \\\n",
       "video frame                                                              \n",
       "98    0         149     181      170      175     161      62  woman-1   \n",
       "      1         149     181      170      175     161      62  woman-1   \n",
       "      2         149     181      170      175     161      62  woman-1   \n",
       "      3         149     181      170      175     161      62  woman-1   \n",
       "      4         149     181      170      175     161      62  woman-1   \n",
       "\n",
       "             grnd-ry  grnd-rx  grnd-ly  grnd-lx  \n",
       "video frame                                      \n",
       "98    0          113        9      119      -12  \n",
       "      1          113        9      119      -12  \n",
       "      2          113        9      119      -12  \n",
       "      3          113        9      119      -12  \n",
       "      4          113        9      119      -12  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<font color=green>Correct!</font><br/>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from asl_utils import test_features_tryit\n",
    "# TODO add df columns for 'grnd-rx', 'grnd-ly', 'grnd-lx' representing differences between hand and nose locations\n",
    "asl.df['grnd-rx'] = asl.df['right-x'] - asl.df['nose-x']\n",
    "asl.df['grnd-ly'] = asl.df['left-y'] - asl.df['nose-y']\n",
    "asl.df['grnd-lx'] = asl.df['left-x'] - asl.df['nose-x']\n",
    "\n",
    "# test the code\n",
    "test_features_tryit(asl)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[9, 113, -12, 119]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# collect the features into a list\n",
    "features_ground = ['grnd-rx','grnd-ry','grnd-lx','grnd-ly']\n",
    " #show a single set of features for a given (video, frame) tuple\n",
    "[asl.df.ix[98,1][v] for v in features_ground]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Build the training set\n",
    "Now that we have a feature list defined, we can pass that list to the `build_training` method to collect the features for all the words in the training set.  Each word in the training set has multiple examples from various videos.  Below we can see the unique words that have been loaded into the training set:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training words: ['JOHN', 'WRITE', 'HOMEWORK', 'IX-1P', 'SEE', 'YESTERDAY', 'IX', 'LOVE', 'MARY', 'CAN', 'GO', 'GO1', 'FUTURE', 'GO2', 'PARTY', 'FUTURE1', 'HIT', 'BLAME', 'FRED', 'FISH', 'WONT', 'EAT', 'BUT', 'CHICKEN', 'VEGETABLE', 'CHINA', 'PEOPLE', 'PREFER', 'BROCCOLI', 'LIKE', 'LEAVE', 'SAY', 'BUY', 'HOUSE', 'KNOW', 'CORN', 'CORN1', 'THINK', 'NOT', 'PAST', 'LIVE', 'CHICAGO', 'CAR', 'SHOULD', 'DECIDE', 'VISIT', 'MOVIE', 'WANT', 'SELL', 'TOMORROW', 'NEXT-WEEK', 'NEW-YORK', 'LAST-WEEK', 'WILL', 'FINISH', 'ANN', 'READ', 'BOOK', 'CHOCOLATE', 'FIND', 'SOMETHING-ONE', 'POSS', 'BROTHER', 'ARRIVE', 'HERE', 'GIVE', 'MAN', 'NEW', 'COAT', 'WOMAN', 'GIVE1', 'HAVE', 'FRANK', 'BREAK-DOWN', 'SEARCH-FOR', 'WHO', 'WHAT', 'LEG', 'FRIEND', 'CANDY', 'BLUE', 'SUE', 'BUY1', 'STOLEN', 'OLD', 'STUDENT', 'VIDEOTAPE', 'BORROW', 'MOTHER', 'POTATO', 'TELL', 'BILL', 'THROW', 'APPLE', 'NAME', 'SHOOT', 'SAY-1P', 'SELF', 'GROUP', 'JANA', 'TOY1', 'MANY', 'TOY', 'ALL', 'BOY', 'TEACHER', 'GIRL', 'BOX', 'GIVE2', 'GIVE3', 'GET', 'PUTASIDE']\n"
     ]
    }
   ],
   "source": [
    "training = asl.build_training(features_ground)\n",
    "print(\"Training words: {}\".format(training.words))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The training data in `training` is an object of class `WordsData` defined in the `asl_data` module.  in addition to the `words` list, data can be accessed with the `get_all_sequences`, `get_all_Xlengths`, `get_word_sequences`, and `get_word_Xlengths` methods. We need the `get_word_Xlengths` method to train multiple sequences with the `hmmlearn` library.  In the following example, notice that there are two lists; the first is a concatenation of all the sequences(the X portion) and the second is a list of the sequence lengths (the Lengths portion)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([[-11,  48,   7, 120],\n",
       "        [-11,  48,   8, 109],\n",
       "        [ -8,  49,  11,  98],\n",
       "        [ -7,  50,   7,  87],\n",
       "        [ -4,  54,   7,  77],\n",
       "        [ -4,  54,   6,  69],\n",
       "        [ -4,  54,   6,  69],\n",
       "        [-13,  52,   6,  69],\n",
       "        [-13,  52,   6,  69],\n",
       "        [ -8,  51,   6,  69],\n",
       "        [ -8,  51,   6,  69],\n",
       "        [ -8,  51,   6,  69],\n",
       "        [ -8,  51,   6,  69],\n",
       "        [ -8,  51,   6,  69],\n",
       "        [-10,  59,   7,  71],\n",
       "        [-15,  64,   9,  77],\n",
       "        [-17,  75,  13,  81],\n",
       "        [ -4,  48,  -4, 113],\n",
       "        [ -2,  53,  -4, 113],\n",
       "        [ -4,  55,   2,  98],\n",
       "        [ -4,  58,   2,  98],\n",
       "        [ -1,  59,   2,  89],\n",
       "        [ -1,  59,  -1,  84],\n",
       "        [ -1,  59,  -1,  84],\n",
       "        [ -7,  63,  -1,  84],\n",
       "        [ -7,  63,  -1,  84],\n",
       "        [ -7,  63,   3,  83],\n",
       "        [ -7,  63,   3,  83],\n",
       "        [ -7,  63,   3,  83],\n",
       "        [ -7,  63,   3,  83],\n",
       "        [ -7,  63,   3,  83],\n",
       "        [ -7,  63,   3,  83],\n",
       "        [ -7,  63,   3,  83],\n",
       "        [ -4,  70,   3,  83],\n",
       "        [ -4,  70,   3,  83],\n",
       "        [ -2,  73,   5,  90],\n",
       "        [ -3,  79,  -4,  96],\n",
       "        [-15,  98,  13, 135],\n",
       "        [ -6,  93,  12, 128],\n",
       "        [ -2,  89,  14, 118],\n",
       "        [  5,  90,  10, 108],\n",
       "        [  4,  86,   7, 105],\n",
       "        [  4,  86,   7, 105],\n",
       "        [  4,  86,  13, 100],\n",
       "        [ -3,  82,  14,  96],\n",
       "        [ -3,  82,  14,  96],\n",
       "        [  6,  89,  16, 100],\n",
       "        [  6,  89,  16, 100],\n",
       "        [  7,  85,  17, 111]], dtype=int64), [17, 20, 12])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "training.get_word_Xlengths('CHOCOLATE')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "###### More feature sets\n",
    "So far we have a simple feature set that is enough to get started modeling.  However, we might get better results if we manipulate the raw values a bit more, so we will go ahead and set up some other options now for experimentation later.  For example, we could normalize each speaker's range of motion with grouped statistics using [Pandas stats](http://pandas.pydata.org/pandas-docs/stable/api.html#api-dataframe-stats) functions and [pandas groupby](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.groupby.html).  Below is an example for finding the means of all speaker subgroups."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false,
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>left-x</th>\n",
       "      <th>left-y</th>\n",
       "      <th>right-x</th>\n",
       "      <th>right-y</th>\n",
       "      <th>nose-x</th>\n",
       "      <th>nose-y</th>\n",
       "      <th>grnd-ry</th>\n",
       "      <th>grnd-rx</th>\n",
       "      <th>grnd-ly</th>\n",
       "      <th>grnd-lx</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>speaker</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>man-1</th>\n",
       "      <td>206.248203</td>\n",
       "      <td>218.679449</td>\n",
       "      <td>155.464350</td>\n",
       "      <td>150.371031</td>\n",
       "      <td>175.031756</td>\n",
       "      <td>61.642600</td>\n",
       "      <td>88.728430</td>\n",
       "      <td>-19.567406</td>\n",
       "      <td>157.036848</td>\n",
       "      <td>31.216447</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>woman-1</th>\n",
       "      <td>164.661438</td>\n",
       "      <td>161.271242</td>\n",
       "      <td>151.017865</td>\n",
       "      <td>117.332462</td>\n",
       "      <td>162.655120</td>\n",
       "      <td>57.245098</td>\n",
       "      <td>60.087364</td>\n",
       "      <td>-11.637255</td>\n",
       "      <td>104.026144</td>\n",
       "      <td>2.006318</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>woman-2</th>\n",
       "      <td>183.214509</td>\n",
       "      <td>176.527232</td>\n",
       "      <td>156.866295</td>\n",
       "      <td>119.835714</td>\n",
       "      <td>170.318973</td>\n",
       "      <td>58.022098</td>\n",
       "      <td>61.813616</td>\n",
       "      <td>-13.452679</td>\n",
       "      <td>118.505134</td>\n",
       "      <td>12.895536</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             left-x      left-y     right-x     right-y      nose-x  \\\n",
       "speaker                                                               \n",
       "man-1    206.248203  218.679449  155.464350  150.371031  175.031756   \n",
       "woman-1  164.661438  161.271242  151.017865  117.332462  162.655120   \n",
       "woman-2  183.214509  176.527232  156.866295  119.835714  170.318973   \n",
       "\n",
       "            nose-y    grnd-ry    grnd-rx     grnd-ly    grnd-lx  \n",
       "speaker                                                          \n",
       "man-1    61.642600  88.728430 -19.567406  157.036848  31.216447  \n",
       "woman-1  57.245098  60.087364 -11.637255  104.026144   2.006318  \n",
       "woman-2  58.022098  61.813616 -13.452679  118.505134  12.895536  "
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_means = asl.df.groupby('speaker').mean()\n",
    "df_means"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To select a mean that matches by speaker, use the pandas [map](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.map.html) method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>left-x</th>\n",
       "      <th>left-y</th>\n",
       "      <th>right-x</th>\n",
       "      <th>right-y</th>\n",
       "      <th>nose-x</th>\n",
       "      <th>nose-y</th>\n",
       "      <th>speaker</th>\n",
       "      <th>grnd-ry</th>\n",
       "      <th>grnd-rx</th>\n",
       "      <th>grnd-ly</th>\n",
       "      <th>grnd-lx</th>\n",
       "      <th>left-x-mean</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>video</th>\n",
       "      <th>frame</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"5\" valign=\"top\">98</th>\n",
       "      <th>0</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "      <td>113</td>\n",
       "      <td>9</td>\n",
       "      <td>119</td>\n",
       "      <td>-12</td>\n",
       "      <td>164.661438</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "      <td>113</td>\n",
       "      <td>9</td>\n",
       "      <td>119</td>\n",
       "      <td>-12</td>\n",
       "      <td>164.661438</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "      <td>113</td>\n",
       "      <td>9</td>\n",
       "      <td>119</td>\n",
       "      <td>-12</td>\n",
       "      <td>164.661438</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "      <td>113</td>\n",
       "      <td>9</td>\n",
       "      <td>119</td>\n",
       "      <td>-12</td>\n",
       "      <td>164.661438</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>149</td>\n",
       "      <td>181</td>\n",
       "      <td>170</td>\n",
       "      <td>175</td>\n",
       "      <td>161</td>\n",
       "      <td>62</td>\n",
       "      <td>woman-1</td>\n",
       "      <td>113</td>\n",
       "      <td>9</td>\n",
       "      <td>119</td>\n",
       "      <td>-12</td>\n",
       "      <td>164.661438</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "             left-x  left-y  right-x  right-y  nose-x  nose-y  speaker  \\\n",
       "video frame                                                              \n",
       "98    0         149     181      170      175     161      62  woman-1   \n",
       "      1         149     181      170      175     161      62  woman-1   \n",
       "      2         149     181      170      175     161      62  woman-1   \n",
       "      3         149     181      170      175     161      62  woman-1   \n",
       "      4         149     181      170      175     161      62  woman-1   \n",
       "\n",
       "             grnd-ry  grnd-rx  grnd-ly  grnd-lx  left-x-mean  \n",
       "video frame                                                   \n",
       "98    0          113        9      119      -12   164.661438  \n",
       "      1          113        9      119      -12   164.661438  \n",
       "      2          113        9      119      -12   164.661438  \n",
       "      3          113        9      119      -12   164.661438  \n",
       "      4          113        9      119      -12   164.661438  "
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "asl.df['left-x-mean']= asl.df['speaker'].map(df_means['left-x'])\n",
    "asl.df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Try it!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "df_std\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>left-x</th>\n",
       "      <th>left-y</th>\n",
       "      <th>right-x</th>\n",
       "      <th>right-y</th>\n",
       "      <th>nose-x</th>\n",
       "      <th>nose-y</th>\n",
       "      <th>grnd-ry</th>\n",
       "      <th>grnd-rx</th>\n",
       "      <th>grnd-ly</th>\n",
       "      <th>grnd-lx</th>\n",
       "      <th>left-x-mean</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>speaker</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>man-1</th>\n",
       "      <td>15.154425</td>\n",
       "      <td>36.328485</td>\n",
       "      <td>18.901917</td>\n",
       "      <td>54.902340</td>\n",
       "      <td>6.654573</td>\n",
       "      <td>5.520045</td>\n",
       "      <td>53.487999</td>\n",
       "      <td>20.269032</td>\n",
       "      <td>36.572749</td>\n",
       "      <td>15.080360</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>woman-1</th>\n",
       "      <td>17.573442</td>\n",
       "      <td>26.594521</td>\n",
       "      <td>16.459943</td>\n",
       "      <td>34.667787</td>\n",
       "      <td>3.549392</td>\n",
       "      <td>3.538330</td>\n",
       "      <td>33.972660</td>\n",
       "      <td>16.764706</td>\n",
       "      <td>27.117393</td>\n",
       "      <td>17.328941</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>woman-2</th>\n",
       "      <td>15.388711</td>\n",
       "      <td>28.825025</td>\n",
       "      <td>14.890288</td>\n",
       "      <td>39.649111</td>\n",
       "      <td>4.099760</td>\n",
       "      <td>3.416167</td>\n",
       "      <td>39.128572</td>\n",
       "      <td>16.191324</td>\n",
       "      <td>29.320655</td>\n",
       "      <td>15.050938</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            left-x     left-y    right-x    right-y    nose-x    nose-y  \\\n",
       "speaker                                                                   \n",
       "man-1    15.154425  36.328485  18.901917  54.902340  6.654573  5.520045   \n",
       "woman-1  17.573442  26.594521  16.459943  34.667787  3.549392  3.538330   \n",
       "woman-2  15.388711  28.825025  14.890288  39.649111  4.099760  3.416167   \n",
       "\n",
       "           grnd-ry    grnd-rx    grnd-ly    grnd-lx  left-x-mean  \n",
       "speaker                                                           \n",
       "man-1    53.487999  20.269032  36.572749  15.080360          0.0  \n",
       "woman-1  33.972660  16.764706  27.117393  17.328941          0.0  \n",
       "woman-2  39.128572  16.191324  29.320655  15.050938          0.0  "
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<font color=green>Correct!</font><br/>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from asl_utils import test_std_tryit\n",
    "# TODO Create a dataframe named `df_std` with standard deviations grouped by speaker\n",
    "df_std = asl.df.groupby('speaker').std()\n",
    "\n",
    "# test the code\n",
    "test_std_tryit(df_std)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='part1_submission'></a>\n",
    "### Features Implementation Submission\n",
    "Implement four feature sets and answer the question that follows.\n",
    "- normalized Cartesian coordinates\n",
    "    - use *mean* and *standard deviation* statistics and the [standard score](https://en.wikipedia.org/wiki/Standard_score) equation to account for speakers with different heights and arm length\n",
    "    \n",
    "- polar coordinates\n",
    "    - calculate polar coordinates with [Cartesian to polar equations](https://en.wikipedia.org/wiki/Polar_coordinate_system#Converting_between_polar_and_Cartesian_coordinates)\n",
    "    - use the [np.arctan2](https://docs.scipy.org/doc/numpy-1.10.0/reference/generated/numpy.arctan2.html) function and *swap the x and y axes* to move the $0$ to $2\\pi$ discontinuity to 12 o'clock instead of 3 o'clock;  in other words, the normal break in radians value from $0$ to $2\\pi$ occurs directly to the left of the speaker's nose, which may be in the signing area and interfere with results.  By swapping the x and y axes, that discontinuity move to directly above the speaker's head, an area not generally used in signing.\n",
    "\n",
    "- delta difference\n",
    "    - as described in Thad's lecture, use the difference in values between one frame and the next frames as features\n",
    "    - pandas [diff method](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.diff.html) and [fillna method](http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.fillna.html) will be helpful for this one\n",
    "\n",
    "- custom features\n",
    "    - These are your own design; combine techniques used above or come up with something else entirely. We look forward to seeing what you come up with! \n",
    "    Some ideas to get you started:\n",
    "        - normalize using a [feature scaling equation](https://en.wikipedia.org/wiki/Feature_scaling)\n",
    "        - normalize the polar coordinates\n",
    "        - adding additional deltas\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# TODO add features for normalized by speaker values of left, right, x, y\n",
    "# Name these 'norm-rx', 'norm-ry', 'norm-lx', and 'norm-ly'\n",
    "# using Z-score scaling (X-Xmean)/Xstd\n",
    "\n",
    "features_norm = ['norm-rx', 'norm-ry', 'norm-lx','norm-ly']\n",
    "\n",
    "mean_right_x = asl.df['speaker'].map(df_means['right-x'])\n",
    "mean_right_y = asl.df['speaker'].map(df_means['right-y'])\n",
    "mean_left_x  = asl.df['speaker'].map(df_means['left-x'])\n",
    "mean_left_y  = asl.df['speaker'].map(df_means['left-y'])\n",
    "\n",
    "std_right_x = asl.df['speaker'].map(df_std['right-x'])\n",
    "std_right_y = asl.df['speaker'].map(df_std['right-y'])\n",
    "std_left_x  = asl.df['speaker'].map(df_std['left-x'])\n",
    "std_left_y  = asl.df['speaker'].map(df_std['left-y'])\n",
    "\n",
    "asl.df['norm-rx'] = (asl.df['right-x'] - mean_right_x) / std_right_x\n",
    "asl.df['norm-ry'] = (asl.df['right-y'] - mean_right_y) / std_right_y\n",
    "asl.df['norm-lx'] = (asl.df['left-x'] - mean_left_x) / std_left_x\n",
    "asl.df['norm-ly'] = (asl.df['left-y'] - mean_left_y) / std_left_y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# TODO add features for polar coordinate values where the nose is the origin\n",
    "# Name these 'polar-rr', 'polar-rtheta', 'polar-lr', and 'polar-ltheta'\n",
    "# Note that 'polar-rr' and 'polar-rtheta' refer to the radius and angle\n",
    "\n",
    "features_polar = ['polar-rr', 'polar-rtheta', 'polar-lr', 'polar-ltheta']\n",
    "\n",
    "grnd_rx =  asl.df['grnd-rx']\n",
    "grnd_ry = asl.df['grnd-ry']\n",
    "grnd_lx = asl.df['grnd-lx']\n",
    "grnd_ly = asl.df['grnd-ly']\n",
    "\n",
    "asl.df['polar-rr'] = np.sqrt(grnd_rx*grnd_rx + grnd_ry*grnd_ry)\n",
    "asl.df['polar-rtheta'] = np.arctan2(grnd_rx, grnd_ry)\n",
    "asl.df['polar-lr'] = np.sqrt(grnd_lx*grnd_lx + grnd_ly*grnd_ly)\n",
    "asl.df['polar-ltheta'] = np.arctan2(grnd_lx, grnd_ly)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# TODO add features for left, right, x, y differences by one time step, i.e. the \"delta\" values discussed in the lecture\n",
    "# Name these 'delta-rx', 'delta-ry', 'delta-lx', and 'delta-ly'\n",
    "\n",
    "features_delta = ['delta-rx', 'delta-ry', 'delta-lx', 'delta-ly']\n",
    "\n",
    "asl.df['delta-rx'] = asl.df['right-x'].diff().fillna(0)\n",
    "asl.df['delta-ry'] = asl.df['right-y'].diff().fillna(0)\n",
    "asl.df['delta-lx'] = asl.df['left-x'].diff().fillna(0)\n",
    "asl.df['delta-ly'] = asl.df['left-y'].diff().fillna(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# TODO add features of your own design, which may be a combination of the above or something else\n",
    "# Name these whatever you would like\n",
    "\n",
    "# TODO define a list named 'features_custom' for building the training set\n",
    "\n",
    "# Need to calculate mean and std again to include 'polar-rr' and 'polar-lr'\n",
    "df_means = asl.df.groupby('speaker').mean()\n",
    "df_std = asl.df.groupby('speaker').std()\n",
    "\n",
    "# Normalize right arm radius\n",
    "mean_polar_rr = asl.df['speaker'].map(df_means['polar-rr'])\n",
    "std_polar_rr = asl.df['speaker'].map(df_std['polar-rr'])\n",
    "asl.df['norm-polar-rr'] = (asl.df['polar-rr'] - mean_polar_rr) / std_polar_rr\n",
    "\n",
    "# Normalize left arm radius\n",
    "mean_polar_lr = asl.df['speaker'].map(df_means['polar-lr'])\n",
    "std_polar_lr = asl.df['speaker'].map(df_std['polar-lr'])\n",
    "asl.df['norm-polar-lr'] = (asl.df['polar-lr'] - mean_polar_lr) / std_polar_lr"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question 1:**  What custom features did you choose for the features_custom set and why?\n",
    "\n",
    "**Answer 1:** Added new features - *norm-polar-lr* & *norm-polar-rr* which normalize the polar radius to account for differences in arm length. \n",
    "\n",
    "Also, as noted from the lectures, delta between values in consecutive time steps gives us an indication of speed. Hence, delta of normalized data might be a good metric."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='part1_test'></a>\n",
    "### Features Unit Testing\n",
    "Run the following unit tests as a sanity check on the defined \"ground\", \"norm\", \"polar\", and 'delta\"\n",
    "feature sets.  The test simply looks for some valid values but is not exhaustive.  However, the project should not be submitted if these tests don't pass."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "....\n",
      "----------------------------------------------------------------------\n",
      "Ran 4 tests in 0.018s\n",
      "\n",
      "OK\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<unittest.runner.TextTestResult run=4 errors=0 failures=0>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import unittest\n",
    "# import numpy as np\n",
    "\n",
    "class TestFeatures(unittest.TestCase):\n",
    "\n",
    "    def test_features_ground(self):\n",
    "        sample = (asl.df.ix[98, 1][features_ground]).tolist()\n",
    "        self.assertEqual(sample, [9, 113, -12, 119])\n",
    "\n",
    "    def test_features_norm(self):\n",
    "        sample = (asl.df.ix[98, 1][features_norm]).tolist()\n",
    "        np.testing.assert_almost_equal(sample, [ 1.153,  1.663, -0.891,  0.742], 3)\n",
    "\n",
    "    def test_features_polar(self):\n",
    "        sample = (asl.df.ix[98,1][features_polar]).tolist()\n",
    "        np.testing.assert_almost_equal(sample, [113.3578, 0.0794, 119.603, -0.1005], 3)\n",
    "\n",
    "    def test_features_delta(self):\n",
    "        sample = (asl.df.ix[98, 0][features_delta]).tolist()\n",
    "        self.assertEqual(sample, [0, 0, 0, 0])\n",
    "        sample = (asl.df.ix[98, 18][features_delta]).tolist()\n",
    "        self.assertTrue(sample in [[-16, -5, -2, 4], [-14, -9, 0, 0]], \"Sample value found was {}\".format(sample))\n",
    "                         \n",
    "suite = unittest.TestLoader().loadTestsFromModule(TestFeatures())\n",
    "unittest.TextTestRunner().run(suite)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "<a id='part2_tutorial'></a>\n",
    "## PART 2: Model Selection\n",
    "### Model Selection Tutorial\n",
    "The objective of Model Selection is to tune the number of states for each word HMM prior to testing on unseen data.  In this section you will explore three methods: \n",
    "- Log likelihood using cross-validation folds (CV)\n",
    "- Bayesian Information Criterion (BIC)\n",
    "- Discriminative Information Criterion (DIC) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Train a single word\n",
    "Now that we have built a training set with sequence data, we can \"train\" models for each word.  As a simple starting example, we train a single word using Gaussian hidden Markov models (HMM).   By using the `fit` method during training, the [Baum-Welch Expectation-Maximization](https://en.wikipedia.org/wiki/Baum%E2%80%93Welch_algorithm) (EM) algorithm is invoked iteratively to find the best estimate for the model *for the number of hidden states specified* from a group of sample seequences. For this example, we *assume* the correct number of hidden states is 3, but that is just a guess.  How do we know what the \"best\" number of states for training is?  We will need to find some model selection technique to choose the best parameter."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of states trained in model for BOOK is 3\n",
      "logL = -2331.1138127433196\n"
     ]
    }
   ],
   "source": [
    "import warnings\n",
    "from hmmlearn.hmm import GaussianHMM\n",
    "\n",
    "def train_a_word(word, num_hidden_states, features):\n",
    "    \n",
    "    warnings.filterwarnings(\"ignore\", category=DeprecationWarning)\n",
    "    training = asl.build_training(features)  \n",
    "    X, lengths = training.get_word_Xlengths(word)\n",
    "    model = GaussianHMM(n_components=num_hidden_states, n_iter=1000).fit(X, lengths)\n",
    "    logL = model.score(X, lengths)\n",
    "    return model, logL\n",
    "\n",
    "demoword = 'BOOK'\n",
    "model, logL = train_a_word(demoword, 3, features_ground)\n",
    "print(\"Number of states trained in model for {} is {}\".format(demoword, model.n_components))\n",
    "print(\"logL = {}\".format(logL))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The HMM model has been trained and information can be pulled from the model, including means and variances for each feature and hidden state.  The [log likelihood](http://math.stackexchange.com/questions/892832/why-we-consider-log-likelihood-instead-of-likelihood-in-gaussian-distribution) for any individual sample or group of samples can also be calculated with the `score` method."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of states trained in model for BOOK is 3\n",
      "hidden state #0\n",
      "mean =  [ -1.12415027  69.44164191  17.02866283  77.7231196 ]\n",
      "variance =  [ 19.70434594  16.83041492  30.51552305  11.03678246]\n",
      "\n",
      "hidden state #1\n",
      "mean =  [ -11.45300909   94.109178     19.03512475  102.2030162 ]\n",
      "variance =  [  77.403668    203.35441965   26.68898447  156.12444034]\n",
      "\n",
      "hidden state #2\n",
      "mean =  [ -3.46504869  50.66686933  14.02391587  52.04731066]\n",
      "variance =  [ 49.12346305  43.04799144  39.35109609  47.24195772]\n",
      "\n"
     ]
    }
   ],
   "source": [
    "def show_model_stats(word, model):\n",
    "    print(\"Number of states trained in model for {} is {}\".format(word, model.n_components))    \n",
    "    variance=np.array([np.diag(model.covars_[i]) for i in range(model.n_components)])    \n",
    "    for i in range(model.n_components):  # for each hidden state\n",
    "        print(\"hidden state #{}\".format(i))\n",
    "        print(\"mean = \", model.means_[i])\n",
    "        print(\"variance = \", variance[i])\n",
    "        print()\n",
    "    \n",
    "show_model_stats(demoword, model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Try it!\n",
    "Experiment by changing the feature set, word, and/or num_hidden_states values in the next cell to see changes in values.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of states trained in model for CHOCOLATE is 3\n",
      "hidden state #0\n",
      "mean =  [   0.58333333   87.91666667   12.75        108.5       ]\n",
      "variance =  [  39.41055556   18.74388889    9.855       144.4175    ]\n",
      "\n",
      "hidden state #1\n",
      "mean =  [ -9.30211403  55.32333876   6.92259936  71.24057775]\n",
      "variance =  [ 16.16920957  46.50917372   3.81388185  15.79446427]\n",
      "\n",
      "hidden state #2\n",
      "mean =  [ -5.40587658  60.1652424    2.32479599  91.3095432 ]\n",
      "variance =  [   7.95073876   64.13103127   13.68077479  129.5912395 ]\n",
      "\n",
      "logL = -601.3291470028619\n"
     ]
    }
   ],
   "source": [
    "my_testword = 'CHOCOLATE'\n",
    "model, logL = train_a_word(my_testword, 3, features_ground) # Experiment here with different parameters\n",
    "show_model_stats(my_testword, model)\n",
    "print(\"logL = {}\".format(logL))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Visualize the hidden states\n",
    "We can plot the means and variances for each state and feature.  Try varying the number of states trained for the HMM model and examine the variances.  Are there some models that are \"better\" than others?  How can you tell?  We would like to hear what you think in the classroom online."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x11c6fb390>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\nBEEQBJX8AceBcacrcAwzAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x11c85b898>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\nAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x11c99de80>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x11cae36d8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import math\n",
    "from matplotlib import (cm, pyplot as plt, mlab)\n",
    "\n",
    "def visualize(word, model):\n",
    "    \"\"\" visualize the input model for a particular word \"\"\"\n",
    "    variance=np.array([np.diag(model.covars_[i]) for i in range(model.n_components)])\n",
    "    figures = []\n",
    "    for parm_idx in range(len(model.means_[0])):\n",
    "        xmin = int(min(model.means_[:,parm_idx]) - max(variance[:,parm_idx]))\n",
    "        xmax = int(max(model.means_[:,parm_idx]) + max(variance[:,parm_idx]))\n",
    "        fig, axs = plt.subplots(model.n_components, sharex=True, sharey=False)\n",
    "        colours = cm.rainbow(np.linspace(0, 1, model.n_components))\n",
    "        for i, (ax, colour) in enumerate(zip(axs, colours)):\n",
    "            x = np.linspace(xmin, xmax, 100)\n",
    "            mu = model.means_[i,parm_idx]\n",
    "            sigma = math.sqrt(np.diag(model.covars_[i])[parm_idx])\n",
    "            ax.plot(x, mlab.normpdf(x, mu, sigma), c=colour)\n",
    "            ax.set_title(\"{} feature {} hidden state #{}\".format(word, parm_idx, i))\n",
    "\n",
    "            ax.grid(True)\n",
    "        figures.append(plt)\n",
    "    for p in figures:\n",
    "        p.show()\n",
    "        \n",
    "visualize(my_testword, model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#####  ModelSelector class\n",
    "Review the `ModelSelector` class from the codebase found in the `my_model_selectors.py` module.  It is designed to be a strategy pattern for choosing different model selectors.  For the project submission in this section, subclass `SelectorModel` to implement the following model selectors.  In other words, you will write your own classes/functions in the `my_model_selectors.py` module and run them from this notebook:\n",
    "\n",
    "- `SelectorCV `:  Log likelihood with CV\n",
    "- `SelectorBIC`: BIC \n",
    "- `SelectorDIC`: DIC\n",
    "\n",
    "You will train each word in the training set with a range of values for the number of hidden states, and then score these alternatives with the model selector, choosing the \"best\" according to each strategy. The simple case of training with a constant value for `n_components` can be called using the provided `SelectorConstant` subclass as follow:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of states trained in model for VEGETABLE is 3\n"
     ]
    }
   ],
   "source": [
    "from my_model_selectors import SelectorConstant\n",
    "\n",
    "training = asl.build_training(features_ground)  # Experiment here with different feature sets defined in part 1\n",
    "word = 'VEGETABLE' # Experiment here with different words\n",
    "model = SelectorConstant(training.get_all_sequences(), training.get_all_Xlengths(), word, n_constant=3).select()\n",
    "print(\"Number of states trained in model for {} is {}\".format(word, model.n_components))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Cross-validation folds\n",
    "If we simply score the model with the Log Likelihood calculated from the feature sequences it has been trained on, we should expect that more complex models will have higher likelihoods. However, that doesn't tell us which would have a better likelihood score on unseen data.  The model will likely be overfit as complexity is added.  To estimate which topology model is better using only the training data, we can compare scores using cross-validation.  One technique for cross-validation is to break the training set into \"folds\" and rotate which fold is left out of training.  The \"left out\" fold scored.  This gives us a proxy method of finding the best model to use on \"unseen data\". In the following example, a set of word sequences is broken into three folds using the [scikit-learn Kfold](http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.KFold.html) class object. When you implement `SelectorCV`, you will use this technique."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train fold indices:[2 3 4 5] Test fold indices:[0 1]\n",
      "Train fold indices:[0 1 4 5] Test fold indices:[2 3]\n",
      "Train fold indices:[0 1 2 3] Test fold indices:[4 5]\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import KFold\n",
    "\n",
    "training = asl.build_training(features_ground) # Experiment here with different feature sets\n",
    "word = 'VEGETABLE' # Experiment here with different words\n",
    "word_sequences = training.get_word_sequences(word)\n",
    "split_method = KFold()\n",
    "for cv_train_idx, cv_test_idx in split_method.split(word_sequences):\n",
    "    print(\"Train fold indices:{} Test fold indices:{}\".format(cv_train_idx, cv_test_idx))  # view indices of the folds"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Tip:** In order to run `hmmlearn` training using the X,lengths tuples on the new folds, subsets must be combined based on the indices given for the folds.  A helper utility has been provided in the `asl_utils` module named `combine_sequences` for this purpose."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Scoring models with other criterion\n",
    "Scoring model topologies with **BIC** balances fit and complexity within the training set for each word.  In the BIC equation, a penalty term penalizes complexity to avoid overfitting, so that it is not necessary to also use cross-validation in the selection process.  There are a number of references on the internet for this criterion.  These [slides](http://www2.imm.dtu.dk/courses/02433/doc/ch6_slides.pdf) include a formula you may find helpful for your implementation.\n",
    "\n",
    "The advantages of scoring model topologies with **DIC** over BIC are presented by Alain Biem in this [reference](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.58.6208&rep=rep1&type=pdf) (also found [here](https://pdfs.semanticscholar.org/ed3d/7c4a5f607201f3848d4c02dd9ba17c791fc2.pdf)).  DIC scores the discriminant ability of a training set for one word against competing words.  Instead of a penalty term for complexity, it provides a penalty if model liklihoods for non-matching words are too similar to model likelihoods for the correct word in the word set."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='part2_submission'></a>\n",
    "### Model Selection Implementation Submission\n",
    "Implement `SelectorCV`, `SelectorBIC`, and `SelectorDIC` classes in the `my_model_selectors.py` module.  Run the selectors on the following five words. Then answer the questions about your results.\n",
    "\n",
    "**Tip:** The `hmmlearn` library may not be able to train or score all models.  Implement try/except contructs as necessary to eliminate non-viable models from consideration."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "words_to_train = ['FISH', 'BOOK', 'VEGETABLE', 'FUTURE', 'JOHN']\n",
    "import timeit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training complete for FISH with 3 states with time 0.028000007005175576 seconds\n",
      "Training complete for BOOK with 15 states with time 2.330455476010684 seconds\n",
      "Training complete for VEGETABLE with 15 states with time 0.7969696299987845 seconds\n",
      "Training complete for FUTURE with 15 states with time 2.4186781469907146 seconds\n",
      "Training complete for JOHN with 15 states with time 25.637559488997795 seconds\n"
     ]
    }
   ],
   "source": [
    "# TODO: Implement SelectorCV in my_model_selector.py\n",
    "from my_model_selectors import SelectorCV\n",
    "\n",
    "training = asl.build_training(features_ground)  # Experiment here with different feature sets defined in part 1\n",
    "\n",
    "sequences = training.get_all_sequences()\n",
    "Xlengths = training.get_all_Xlengths()\n",
    "\n",
    "for word in words_to_train:\n",
    "    start = timeit.default_timer()\n",
    "    model = SelectorCV(sequences, Xlengths, word, \n",
    "                       min_n_components=2, max_n_components=15, random_state = 14).select()\n",
    "    end = timeit.default_timer() - start\n",
    "    if model is not None:\n",
    "        print(\"Training complete for {} with {} states with time {} seconds\".format(word, model.n_components, end))\n",
    "    else:\n",
    "        print(\"Training failed for {}\".format(word))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training complete for FISH with 2 states with time 0.09146881599735934 seconds\n",
      "Training complete for BOOK with 2 states with time 2.016845521997311 seconds\n",
      "Training complete for VEGETABLE with 2 states with time 0.7241176120005548 seconds\n",
      "Training complete for FUTURE with 2 states with time 2.1909853079996537 seconds\n",
      "Training complete for JOHN with 2 states with time 22.080462529993383 seconds\n"
     ]
    }
   ],
   "source": [
    "# TODO: Implement SelectorBIC in module my_model_selectors.py\n",
    "from my_model_selectors import SelectorBIC\n",
    "\n",
    "training = asl.build_training(features_ground)  # Experiment here with different feature sets defined in part 1\n",
    "sequences = training.get_all_sequences()\n",
    "Xlengths = training.get_all_Xlengths()\n",
    "for word in words_to_train:\n",
    "    start = timeit.default_timer()\n",
    "    model = SelectorBIC(sequences, Xlengths, word, \n",
    "                    min_n_components=2, max_n_components=15, random_state = 14).select()\n",
    "    end = timeit.default_timer()-start\n",
    "    if model is not None:\n",
    "        print(\"Training complete for {} with {} states with time {} seconds\".format(word, model.n_components, end))\n",
    "    else:\n",
    "        print(\"Training failed for {}\".format(word))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training complete for FISH with 3 states with time 0.09454512700904161 seconds\n",
      "Training complete for BOOK with 15 states with time 2.4017886569927214 seconds\n",
      "Training complete for VEGETABLE with 15 states with time 0.8214017159916693 seconds\n",
      "Training complete for FUTURE with 15 states with time 2.455093226992176 seconds\n",
      "Training complete for JOHN with 15 states with time 25.174293504998786 seconds\n"
     ]
    }
   ],
   "source": [
    "# TODO: Implement SelectorDIC in module my_model_selectors.py\n",
    "from my_model_selectors import SelectorDIC\n",
    "\n",
    "training = asl.build_training(features_ground)  # Experiment here with different feature sets defined in part 1\n",
    "sequences = training.get_all_sequences()\n",
    "Xlengths = training.get_all_Xlengths()\n",
    "for word in words_to_train:\n",
    "    start = timeit.default_timer()\n",
    "    model = SelectorDIC(sequences, Xlengths, word, \n",
    "                    min_n_components=2, max_n_components=15, random_state = 14).select()\n",
    "    end = timeit.default_timer()-start\n",
    "    if model is not None:\n",
    "        print(\"Training complete for {} with {} states with time {} seconds\".format(word, model.n_components, end))\n",
    "    else:\n",
    "        print(\"Training failed for {}\".format(word))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question 2:**  Compare and contrast the possible advantages and disadvantages of the various model selectors implemented.\n",
    "\n",
    "**Answer 2:** Selection using cross validation is the easier to implement compared to BIC & DIC. The idea in BIC to penalize model complexity is interesting as it may also have a side effect of faster running times. Yet, I also think it might be a doubled edged sword, as in some cases it will sacrifice complexity for performance. **DIC seems like the best selector** because it will use the model that gives the best distinction between the word of interest and all others. This should result in the best performing model but also the most sluggish as it needs to calculate the probabilities of each word.  \n",
    "\n",
    "A more formal listing of advantages & disadvantages is depicted below.\n",
    "\n",
    "### Cross Validation:\n",
    "**Advantages:** Does not need a lot of data for training – as the train data is folded to simulate the behavior that the model will have in test data.\n",
    "\n",
    "**Disadvantages:** It needs to split the sequences from the beginning each time a new state will be evaluated (overhead). \n",
    "\n",
    "### BIC:\n",
    "**Advantages:** It penalizes model's complexity (of parameters).\n",
    "\n",
    "**Disadvantages** Not as accurate as cross-validation – this could be possible because of the requirement of more training data (as there are no folds to simulate test data).\n",
    "\n",
    "### DIC:\n",
    "**Advantages:** Better performance than BIC.\n",
    "\n",
    "**Disadvantages:** Model complexity is not penalized which might lead to a large number of parameters."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='part2_test'></a>\n",
    "### Model Selector Unit Testing\n",
    "Run the following unit tests as a sanity check on the implemented model selectors.  The test simply looks for valid interfaces  but is not exhaustive. However, the project should not be submitted if these tests don't pass."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "....\n",
      "----------------------------------------------------------------------\n",
      "Ran 4 tests in 39.572s\n",
      "\n",
      "OK\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<unittest.runner.TextTestResult run=4 errors=0 failures=0>"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from asl_test_model_selectors import TestSelectors\n",
    "suite = unittest.TestLoader().loadTestsFromModule(TestSelectors())\n",
    "unittest.TextTestRunner().run(suite)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": false
   },
   "source": [
    "<a id='part3_tutorial'></a>\n",
    "## PART 3: Recognizer\n",
    "The objective of this section is to \"put it all together\".  Using the four feature sets created and the three model selectors, you will experiment with the models and present your results.  Instead of training only five specific words as in the previous section, train the entire set with a feature set and model selector strategy.  \n",
    "### Recognizer Tutorial\n",
    "##### Train the full training set\n",
    "The following example trains the entire set with the example `features_ground` and `SelectorConstant` features and model selector.  Use this pattern for you experimentation and final submission cells.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of word models returned = 112\n"
     ]
    }
   ],
   "source": [
    "# autoreload for automatically reloading changes made in my_model_selectors and my_recognizer\n",
    "%load_ext autoreload\n",
    "%autoreload 2\n",
    "\n",
    "from my_model_selectors import SelectorConstant\n",
    "\n",
    "def train_all_words(features, model_selector):\n",
    "    training = asl.build_training(features)  # Experiment here with different feature sets defined in part 1\n",
    "    sequences = training.get_all_sequences()\n",
    "    Xlengths = training.get_all_Xlengths()\n",
    "    model_dict = {}\n",
    "    for word in training.words:\n",
    "        model = model_selector(sequences, Xlengths, word, \n",
    "                        n_constant=3).select()\n",
    "        model_dict[word]=model\n",
    "    return model_dict\n",
    "\n",
    "models = train_all_words(features_ground, SelectorConstant)\n",
    "print(\"Number of word models returned = {}\".format(len(models)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##### Load the test set\n",
    "The `build_test` method in `ASLdb` is similar to the `build_training` method already presented, but there are a few differences:\n",
    "- the object is type `SinglesData` \n",
    "- the internal dictionary keys are the index of the test word rather than the word itself\n",
    "- the getter methods are `get_all_sequences`, `get_all_Xlengths`, `get_item_sequences` and `get_item_Xlengths`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of test set items: 178\n",
      "Number of test set sentences: 40\n"
     ]
    }
   ],
   "source": [
    "test_set = asl.build_test(features_ground)\n",
    "print(\"Number of test set items: {}\".format(test_set.num_items))\n",
    "print(\"Number of test set sentences: {}\".format(len(test_set.sentences_index)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='part3_submission'></a>\n",
    "### Recognizer Implementation Submission\n",
    "For the final project submission, students must implement a recognizer following guidance in the `my_recognizer.py` module.  Experiment with the four feature sets and the three model selection methods (that's 12 possible combinations). You can add and remove cells for experimentation or run the recognizers locally in some other way during your experiments, but retain the results for your discussion.  For submission, you will provide code cells of **only three** interesting combinations for your discussion (see questions below). At least one of these should produce a word error rate of less than 60%, i.e. WER < 0.60 . \n",
    "\n",
    "**Tip:** The hmmlearn library may not be able to train or score all models.  Implement try/except contructs as necessary to eliminate non-viable models from consideration."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "# TODO implement the recognize method in my_recognizer\n",
    "from my_recognizer import recognize\n",
    "from asl_utils import show_errors"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "**** WER = 0.5280898876404494\n",
      "Total correct: 84 out of 178\n",
      "Video  Recognized                                                    Correct\n",
      "=====================================================================================================\n",
      "    2: JOHN WRITE HOMEWORK                                           JOHN WRITE HOMEWORK\n",
      "    7: JOHN CAN GO CAN                                               JOHN CAN GO CAN\n",
      "   12: JOHN *WHAT *JOHN CAN                                          JOHN CAN GO CAN\n",
      "   21: JOHN *HOMEWORK *JOHN *PREFER BUT *WHAT *FUTURE *WHO           JOHN FISH WONT EAT BUT CAN EAT CHICKEN\n",
      "   25: JOHN *IX IX *WHO IX                                           JOHN LIKE IX IX IX\n",
      "   28: JOHN *FUTURE IX *FUTURE *LOVE                                 JOHN LIKE IX IX IX\n",
      "   30: JOHN LIKE *MARY *MARY *MARY                                   JOHN LIKE IX IX IX\n",
      "   36: *IX *VISIT *GIVE *GIVE *MARY *MARY                            MARY VEGETABLE KNOW IX LIKE CORN1\n",
      "   40: JOHN *GO *DECIDE *JOHN *MARY                                  JOHN IX THINK MARY LOVE\n",
      "   43: JOHN *IX BUY HOUSE                                            JOHN MUST BUY HOUSE\n",
      "   50: *JOHN *SEE BUY CAR *JOHN                                      FUTURE JOHN BUY CAR SHOULD\n",
      "   54: JOHN SHOULD NOT BUY HOUSE                                     JOHN SHOULD NOT BUY HOUSE\n",
      "   57: *MARY *GO *GO MARY                                            JOHN DECIDE VISIT MARY\n",
      "   67: *SHOULD FUTURE *MARY BUY HOUSE                                JOHN FUTURE NOT BUY HOUSE\n",
      "   71: JOHN *FUTURE *GIVE1 MARY                                      JOHN WILL VISIT MARY\n",
      "   74: *IX *GO *GO *VISIT                                            JOHN NOT VISIT MARY\n",
      "   77: *JOHN *GIVE1 MARY                                             ANN BLAME MARY\n",
      "   84: *HOMEWORK *GIVE1 *HOMEWORK *COAT                              IX-1P FIND SOMETHING-ONE BOOK\n",
      "   89: *MAN *GIVE *IX *IX IX *ARRIVE *BOOK                           JOHN IX GIVE MAN IX NEW COAT\n",
      "   90: JOHN GIVE IX SOMETHING-ONE WOMAN *ARRIVE                      JOHN GIVE IX SOMETHING-ONE WOMAN BOOK\n",
      "   92: JOHN *IX IX *IX *IX BOOK                                      JOHN GIVE IX SOMETHING-ONE WOMAN BOOK\n",
      "  100: POSS NEW CAR BREAK-DOWN                                       POSS NEW CAR BREAK-DOWN\n",
      "  105: JOHN *SEE                                                     JOHN LEG\n",
      "  107: JOHN POSS *HAVE HAVE *MARY                                    JOHN POSS FRIEND HAVE CANDY\n",
      "  108: *LOVE *HOMEWORK                                               WOMAN ARRIVE\n",
      "  113: IX CAR *IX *MARY *JOHN                                        IX CAR BLUE SUE BUY\n",
      "  119: *MARY *BUY1 IX *BLAME *IX                                     SUE BUY IX CAR BLUE\n",
      "  122: JOHN *GIVE1 BOOK                                              JOHN READ BOOK\n",
      "  139: JOHN *ARRIVE WHAT *MARY *ARRIVE                               JOHN BUY WHAT YESTERDAY BOOK\n",
      "  142: JOHN BUY YESTERDAY WHAT BOOK                                  JOHN BUY YESTERDAY WHAT BOOK\n",
      "  158: LOVE JOHN WHO                                                 LOVE JOHN WHO\n",
      "  167: JOHN *MARY *VISIT LOVE MARY                                   JOHN IX SAY LOVE MARY\n",
      "  171: *IX MARY BLAME                                                JOHN MARY BLAME\n",
      "  174: *JOHN *GIVE3 GIVE1 *YESTERDAY *JOHN                           PEOPLE GROUP GIVE1 JANA TOY\n",
      "  181: *EAT ARRIVE                                                   JOHN ARRIVE\n",
      "  184: ALL BOY *GIVE1 TEACHER *YESTERDAY                             ALL BOY GIVE TEACHER APPLE\n",
      "  189: *MARY *GO *YESTERDAY BOX                                      JOHN GIVE GIRL BOX\n",
      "  193: JOHN *GO *YESTERDAY BOX                                       JOHN GIVE GIRL BOX\n",
      "  199: *HOMEWORK *STUDENT *GO                                        LIKE CHOCOLATE WHO\n",
      "  201: JOHN *MAN *LOVE *JOHN BUY HOUSE                               JOHN TELL MARY IX-1P BUY HOUSE\n"
     ]
    }
   ],
   "source": [
    "# TODO Choose a feature set and model selector\n",
    "features = features_polar # change as needed\n",
    "model_selector = SelectorCV # change as needed\n",
    "\n",
    "# TODO Recognize the test set and display the result with the show_errors method\n",
    "models = train_all_words(features, model_selector)\n",
    "test_set = asl.build_test(features)\n",
    "probabilities, guesses = recognize(models, test_set)\n",
    "show_errors(guesses, test_set)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "**** WER = 0.5337078651685393\n",
      "Total correct: 83 out of 178\n",
      "Video  Recognized                                                    Correct\n",
      "=====================================================================================================\n",
      "    2: JOHN *NEW HOMEWORK                                            JOHN WRITE HOMEWORK\n",
      "    7: JOHN CAN GO CAN                                               JOHN CAN GO CAN\n",
      "   12: JOHN *WHAT *JOHN CAN                                          JOHN CAN GO CAN\n",
      "   21: JOHN *HOMEWORK *JOHN *PREFER *CAR *WHAT *FUTURE *WHO          JOHN FISH WONT EAT BUT CAN EAT CHICKEN\n",
      "   25: JOHN *IX IX *WHO IX                                           JOHN LIKE IX IX IX\n",
      "   28: JOHN *FUTURE IX *FUTURE *LOVE                                 JOHN LIKE IX IX IX\n",
      "   30: JOHN LIKE *MARY *MARY *MARY                                   JOHN LIKE IX IX IX\n",
      "   36: *IX *EAT *GIVE *GIVE *MARY *MARY                              MARY VEGETABLE KNOW IX LIKE CORN1\n",
      "   40: JOHN *GO *GIVE *JOHN *MARY                                    JOHN IX THINK MARY LOVE\n",
      "   43: JOHN *IX BUY HOUSE                                            JOHN MUST BUY HOUSE\n",
      "   50: *JOHN *SEE BUY CAR *JOHN                                      FUTURE JOHN BUY CAR SHOULD\n",
      "   54: JOHN SHOULD NOT BUY HOUSE                                     JOHN SHOULD NOT BUY HOUSE\n",
      "   57: *MARY *GO *GO MARY                                            JOHN DECIDE VISIT MARY\n",
      "   67: *SHOULD FUTURE *MARY BUY HOUSE                                JOHN FUTURE NOT BUY HOUSE\n",
      "   71: JOHN *FUTURE *GIVE1 MARY                                      JOHN WILL VISIT MARY\n",
      "   74: *IX *GO *GO *VISIT                                            JOHN NOT VISIT MARY\n",
      "   77: *JOHN *GIVE1 MARY                                             ANN BLAME MARY\n",
      "   84: *HOMEWORK *GIVE1 *HOMEWORK *COAT                              IX-1P FIND SOMETHING-ONE BOOK\n",
      "   89: *GIVE *GIVE *IX *IX IX *ARRIVE *BOOK                          JOHN IX GIVE MAN IX NEW COAT\n",
      "   90: JOHN GIVE IX SOMETHING-ONE WOMAN *ARRIVE                      JOHN GIVE IX SOMETHING-ONE WOMAN BOOK\n",
      "   92: JOHN *IX IX *IX *IX BOOK                                      JOHN GIVE IX SOMETHING-ONE WOMAN BOOK\n",
      "  100: POSS NEW CAR BREAK-DOWN                                       POSS NEW CAR BREAK-DOWN\n",
      "  105: JOHN *SEE                                                     JOHN LEG\n",
      "  107: JOHN POSS *HAVE HAVE *MARY                                    JOHN POSS FRIEND HAVE CANDY\n",
      "  108: *LOVE *HOMEWORK                                               WOMAN ARRIVE\n",
      "  113: IX CAR *IX *MARY *JOHN                                        IX CAR BLUE SUE BUY\n",
      "  119: *MARY *BUY1 IX *BLAME *IX                                     SUE BUY IX CAR BLUE\n",
      "  122: JOHN *GIVE1 BOOK                                              JOHN READ BOOK\n",
      "  139: JOHN *ARRIVE WHAT *MARY *ARRIVE                               JOHN BUY WHAT YESTERDAY BOOK\n",
      "  142: JOHN BUY YESTERDAY WHAT BOOK                                  JOHN BUY YESTERDAY WHAT BOOK\n",
      "  158: LOVE JOHN WHO                                                 LOVE JOHN WHO\n",
      "  167: JOHN *MARY *VISIT LOVE MARY                                   JOHN IX SAY LOVE MARY\n",
      "  171: *IX MARY BLAME                                                JOHN MARY BLAME\n",
      "  174: *JOHN GROUP GIVE1 *YESTERDAY *JOHN                            PEOPLE GROUP GIVE1 JANA TOY\n",
      "  181: *EAT ARRIVE                                                   JOHN ARRIVE\n",
      "  184: ALL BOY *GIVE1 TEACHER *YESTERDAY                             ALL BOY GIVE TEACHER APPLE\n",
      "  189: *MARY *GO *YESTERDAY BOX                                      JOHN GIVE GIRL BOX\n",
      "  193: JOHN *GO *YESTERDAY BOX                                       JOHN GIVE GIRL BOX\n",
      "  199: *HOMEWORK *STUDENT *GO                                        LIKE CHOCOLATE WHO\n",
      "  201: JOHN *GIVE *LOVE *JOHN BUY HOUSE                              JOHN TELL MARY IX-1P BUY HOUSE\n"
     ]
    }
   ],
   "source": [
    "# TODO Choose a feature set and model selector\n",
    "# TODO Recognize the test set and display the result with the show_errors method\n",
    "features = features_polar # change as needed\n",
    "model_selector = SelectorDIC # change as needed\n",
    "\n",
    "# TODO Recognize the test set and display the result with the show_errors method\n",
    "models = train_all_words(features, model_selector)\n",
    "test_set = asl.build_test(features)\n",
    "probabilities, guesses = recognize(models, test_set)\n",
    "show_errors(guesses, test_set)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "**** WER = 0.6067415730337079\n",
      "Total correct: 70 out of 178\n",
      "Video  Recognized                                                    Correct\n",
      "=====================================================================================================\n",
      "    2: JOHN WRITE HOMEWORK                                           JOHN WRITE HOMEWORK\n",
      "    7: *MARY *CAR GO *WHAT                                           JOHN CAN GO CAN\n",
      "   12: JOHN *CAR *WHAT CAN                                           JOHN CAN GO CAN\n",
      "   21: *MARY *BOX *JOHN *BLAME *CAR *CAR *CHICKEN *WRITE             JOHN FISH WONT EAT BUT CAN EAT CHICKEN\n",
      "   25: JOHN LIKE IX *MARY IX                                         JOHN LIKE IX IX IX\n",
      "   28: *ANN LIKE *ANN *ANN *ANN                                      JOHN LIKE IX IX IX\n",
      "   30: *IX-1P *CHOCOLATE *MARY *LOVE *LOVE                           JOHN LIKE IX IX IX\n",
      "   36: MARY *MARY *YESTERDAY *WOMAN LIKE *IX                         MARY VEGETABLE KNOW IX LIKE CORN1\n",
      "   40: *MARY *JOHN *FUTURE1 MARY *MARY                               JOHN IX THINK MARY LOVE\n",
      "   43: JOHN *FUTURE BUY HOUSE                                        JOHN MUST BUY HOUSE\n",
      "   50: *POSS *SEE *BOX CAR *IX                                       FUTURE JOHN BUY CAR SHOULD\n",
      "   54: JOHN *FUTURE *SHOULD *ARRIVE HOUSE                            JOHN SHOULD NOT BUY HOUSE\n",
      "   57: *LOVE *IX *JOHN *VISIT                                        JOHN DECIDE VISIT MARY\n",
      "   67: *MARY *IX *JOHN *ARRIVE HOUSE                                 JOHN FUTURE NOT BUY HOUSE\n",
      "   71: JOHN WILL VISIT MARY                                          JOHN WILL VISIT MARY\n",
      "   74: *GO *VISIT VISIT MARY                                         JOHN NOT VISIT MARY\n",
      "   77: *JOHN BLAME MARY                                              ANN BLAME MARY\n",
      "   84: *JOHN *BOX *VISIT BOOK                                        IX-1P FIND SOMETHING-ONE BOOK\n",
      "   89: *MARY *POSS *IX *IX IX *ARRIVE COAT                           JOHN IX GIVE MAN IX NEW COAT\n",
      "   90: *SELF *IX IX *IX WOMAN BOOK                                   JOHN GIVE IX SOMETHING-ONE WOMAN BOOK\n",
      "   92: JOHN *IX IX *IX *LOVE BOOK                                    JOHN GIVE IX SOMETHING-ONE WOMAN BOOK\n",
      "  100: POSS NEW CAR BREAK-DOWN                                       POSS NEW CAR BREAK-DOWN\n",
      "  105: JOHN *POSS                                                    JOHN LEG\n",
      "  107: *MARY POSS *BOX *MARY *MARY                                   JOHN POSS FRIEND HAVE CANDY\n",
      "  108: *LOVE *HOMEWORK                                               WOMAN ARRIVE\n",
      "  113: *SHOULD CAR *IX *JOHN *BOX                                    IX CAR BLUE SUE BUY\n",
      "  119: *PREFER *BUY1 IX *JOHN *GO                                    SUE BUY IX CAR BLUE\n",
      "  122: JOHN *GIVE1 BOOK                                              JOHN READ BOOK\n",
      "  139: JOHN *BUY1 *CAR *JOHN BOOK                                    JOHN BUY WHAT YESTERDAY BOOK\n",
      "  142: JOHN BUY YESTERDAY WHAT BOOK                                  JOHN BUY YESTERDAY WHAT BOOK\n",
      "  158: LOVE JOHN WHO                                                 LOVE JOHN WHO\n",
      "  167: JOHN IX *SAY-1P LOVE *IX                                      JOHN IX SAY LOVE MARY\n",
      "  171: *LIKE *JOHN BLAME                                             JOHN MARY BLAME\n",
      "  174: *CAR *GIVE1 GIVE1 *YESTERDAY *CAR                             PEOPLE GROUP GIVE1 JANA TOY\n",
      "  181: JOHN *BOX                                                     JOHN ARRIVE\n",
      "  184: *IX *IX *GIVE1 TEACHER APPLE                                  ALL BOY GIVE TEACHER APPLE\n",
      "  189: *JANA *MARY *YESTERDAY BOX                                    JOHN GIVE GIRL BOX\n",
      "  193: *IX *YESTERDAY *YESTERDAY BOX                                 JOHN GIVE GIRL BOX\n",
      "  199: *JOHN *BOX *JOHN                                              LIKE CHOCOLATE WHO\n",
      "  201: JOHN *GIVE1 *IX *WOMAN *ARRIVE HOUSE                          JOHN TELL MARY IX-1P BUY HOUSE\n"
     ]
    }
   ],
   "source": [
    "# TODO Choose a feature set and model selector\n",
    "# TODO Recognize the test set and display the result with the show_errors method\n",
    "features = features_norm # change as needed\n",
    "model_selector = SelectorCV # change as needed\n",
    "\n",
    "# TODO Recognize the test set and display the result with the show_errors method\n",
    "models = train_all_words(features, model_selector)\n",
    "test_set = asl.build_test(features)\n",
    "probabilities, guesses = recognize(models, test_set)\n",
    "show_errors(guesses, test_set)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question 3:**  Summarize the error results from three combinations of features and model selectors.  What was the \"best\" combination and why?  What additional information might we use to improve our WER?  For more insight on improving WER, take a look at the introduction to Part 4.\n",
    "\n",
    "**Answer 3:** \n",
    "\n",
    "| **Model**     | **Features**      | **WER**               | **Correct** | **Incorrect** |\n",
    "|-------------\t|----------------\t|--------------------\t|---------\t|-----------\t|\n",
    "| SelectorCV  \t| features_polar \t| 0.5280898876404494 \t| 84      \t| 94        \t|\n",
    "| SelectorDIC \t| features_polar \t| 0.5337078651685393 \t| 83      \t| 95        \t|\n",
    "| SelectorCV  \t| features_norm  \t| 0.6067415730337079 \t| 70      \t| 108       \t|\n",
    "\n",
    "The best results were obtained using the *SelectorCV* model selector which makes efficient use of the training data by folding it and attempting to simulate how the model would behave on test data. However, my preferred model DIC doesn't lag much. *features_polar* produced the lowest WER (with both *SelectorCV & SelectorDIC* model). This could be improved by computing the probability of a word being next to another using statistical language models (or other NLP techniques). "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='part3_test'></a>\n",
    "### Recognizer Unit Tests\n",
    "Run the following unit tests as a sanity check on the defined recognizer.  The test simply looks for some valid values but is not exhaustive. However, the project should not be submitted if these tests don't pass."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from asl_test_recognizer import TestRecognize\n",
    "suite = unittest.TestLoader().loadTestsFromModule(TestRecognize())\n",
    "unittest.TextTestRunner().run(suite)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<a id='part4_info'></a>\n",
    "## PART 4: (OPTIONAL)  Improve the WER with Language Models\n",
    "We've squeezed just about as much as we can out of the model and still only get about 50% of the words right! Surely we can do better than that.  Probability to the rescue again in the form of [statistical language models (SLM)](https://en.wikipedia.org/wiki/Language_model).  The basic idea is that each word has some probability of occurrence within the set, and some probability that it is adjacent to specific other words. We can use that additional information to make better choices.\n",
    "\n",
    "##### Additional reading and resources\n",
    "- [Introduction to N-grams (Stanford Jurafsky slides)](https://web.stanford.edu/class/cs124/lec/languagemodeling.pdf)\n",
    "- [Speech Recognition Techniques for a Sign Language Recognition System, Philippe Dreuw et al](https://www-i6.informatik.rwth-aachen.de/publications/download/154/Dreuw--2007.pdf) see the improved results of applying LM on *this* data!\n",
    "- [SLM data for *this* ASL dataset](ftp://wasserstoff.informatik.rwth-aachen.de/pub/rwth-boston-104/lm/)\n",
    "\n",
    "##### Optional challenge\n",
    "The recognizer you implemented in Part 3 is equivalent to a \"0-gram\" SLM.  Improve the WER with the SLM data provided with the data set in the link above using \"1-gram\", \"2-gram\", and/or \"3-gram\" statistics. The `probabilities` data you've already calculated will be useful and can be turned into a pandas DataFrame if desired (see next cell).  \n",
    "Good luck!  Share your results with the class!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# create a DataFrame of log likelihoods for the test word items\n",
    "df_probs = pd.DataFrame(data=probabilities)\n",
    "df_probs.head()"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python [default]",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  },
  "nbpresent": {
   "slides": {
    "0a2d4faf-9fb8-4cee-853b-ed68b90f3f8a": {
     "id": "0a2d4faf-9fb8-4cee-853b-ed68b90f3f8a",
     "prev": null,
     "regions": {
      "3fb9ce83-fbb2-4995-832a-f8f400734ad3": {
       "attrs": {
        "height": 0.8,
        "width": 0.8,
        "x": 0.1,
        "y": 0.1
       },
       "content": {
        "cell": "1dbb9346-179b-4835-b430-6369d88f1a1b",
        "part": "whole"
       },
       "id": "3fb9ce83-fbb2-4995-832a-f8f400734ad3"
      }
     }
    },
    "1519a4fa-1588-4644-98de-9c43bf0aceb5": {
     "id": "1519a4fa-1588-4644-98de-9c43bf0aceb5",
     "prev": "8a712017-49b7-449f-8264-43a032ace902",
     "regions": {
      "29546121-ed11-44b7-8144-0c44e874098f": {
       "attrs": {
        "height": 0.8,
        "width": 0.8,
        "x": 0.1,
        "y": 0.1
       },
       "content": {
        "cell": "365590a4-6963-4812-a1cf-688f7b6bb9ff",
        "part": "whole"
       },
       "id": "29546121-ed11-44b7-8144-0c44e874098f"
      }
     }
    },
    "176eaccb-15dd-455d-bf07-504213e7aa01": {
     "id": "176eaccb-15dd-455d-bf07-504213e7aa01",
     "prev": "de6b30f4-2463-4901-92ed-aabad78e5e0f",
     "regions": {
      "1542aa9e-dc55-4b90-adef-bf5181872b42": {
       "attrs": {
        "height": 0.8,
        "width": 0.8,
        "x": 0.1,
        "y": 0.1
       },
       "content": {
        "cell": "5c242050-c1f7-4b3b-8103-2ea9d71a40dc",
        "part": "whole"
       },
       "id": "1542aa9e-dc55-4b90-adef-bf5181872b42"
      }
     }
    },
    "19091b36-b0e7-49b1-b501-ec05937e0da9": {
     "id": "19091b36-b0e7-49b1-b501-ec05937e0da9",
     "prev": "1983c02e-fb99-4c05-a728-e0c0ad7c06d8",
     "regions": {
      "6529a31c-8d45-425c-b1d7-d0ac6fca6a32": {
       "attrs": {
        "height": 0.8,
        "width": 0.8,
        "x": 0.1,
        "y": 0.1
       },
       "content": {
        "cell": "e766909d-9421-4aaf-9fb1-bc90d27e49e3",
        "part": "whole"
       },
       "id": "6529a31c-8d45-425c-b1d7-d0ac6fca6a32"
      }
     }
    },
    "1983c02e-fb99-4c05-a728-e0c0ad7c06d8": {
     "id": "1983c02e-fb99-4c05-a728-e0c0ad7c06d8",
     "prev": "176eaccb-15dd-455d-bf07-504213e7aa01",
     "regions": {
      "1c4e605d-7f22-4f30-b3fb-74b2937e7a4a": {
       "attrs": {
        "height": 0.8,
        "width": 0.8,
        "x": 0.1,
        "y": 0.1
       },
       "content": {
        "cell": "4d217204-e5c0-4568-bd30-12c2e41b681d",
        "part": "whole"
       },
       "id": "1c4e605d-7f22-4f30-b3fb-74b2937e7a4a"
      }
     }
    },
    "212b111f-4527-459c-8297-1db5580ee5c9": {
     "id": "212b111f-4527-459c-8297-1db5580ee5c9",
     "prev": "76898529-e49e-4663-8d02-8261dfe1d94b",
     "regions": {
      "2e4bd280-3cd6-47d0-9c81-17737b24053b": {
       "attrs": {
        "height": 0.8,
        "width": 0.8,
        "x": 0.1,
        "y": 0.1
       },
       "content": {
        "cell": "0c316996-9933-4b3d-82ec-259518dc8bc9",
        "part": "whole"
       },
       "id": "2e4bd280-3cd6-47d0-9c81-17737b24053b"
      }
     }
    },
    "23a7337f-a0cf-4ed4-baa9-ec06bfdc0579": {
     "id": "23a7337f-a0cf-4ed4-baa9-ec06bfdc0579",
     "prev": "e76e9a02-54c1-4ec9-80fb-c611ed398122",
     "regions": {
      "b5721d20-d6f8-4ddb-a5aa-eb16f0cc8893": {
       "attrs": {
        "height": 0.8,
        "width": 0.8,
        "x": 0.1,
        "y": 0.1
       },
       "content": {
        "cell": "313015a2-b5a9-4136-a8ea-5d011e47d840",
        "part": "whole"
       },
       "id": "b5721d20-d6f8-4ddb-a5aa-eb16f0cc8893"
      }
     }
    },
    "732f1952-ee54-46fb-8067-099512824296": {
     "id": "732f1952-ee54-46fb-8067-099512824296",
     "prev": "0a2d4faf-9fb8-4cee-853b-ed68b90f3f8a",
     "regions": {
      "f31d4597-08ad-4c46-ad52-4bd2d775c624": {
       "attrs": {
        "height": 0.8,
        "width": 0.8,
        "x": 0.1,
        "y": 0.1
       },
       "content": {
        "cell": "aadfec52-27ca-4541-8920-fa9253d51827",
        "part": "whole"
       },
       "id": "f31d4597-08ad-4c46-ad52-4bd2d775c624"
      }
     }
    },
    "76898529-e49e-4663-8d02-8261dfe1d94b": {
     "id": "76898529-e49e-4663-8d02-8261dfe1d94b",
     "prev": "19091b36-b0e7-49b1-b501-ec05937e0da9",
     "regions": {
      "ec1746fc-aec9-4a7c-8225-9e9ac8d45889": {
       "attrs": {
        "height": 0.8,
        "width": 0.8,
        "x": 0.1,
        "y": 0.1
       },
       "content": {
        "cell": "b3e539be-84e2-49ce-a183-31cfc5c7ce7c",
        "part": "whole"
       },
       "id": "ec1746fc-aec9-4a7c-8225-9e9ac8d45889"
      }
     }
    },
    "8a712017-49b7-449f-8264-43a032ace902": {
     "id": "8a712017-49b7-449f-8264-43a032ace902",
     "prev": "bed9e696-630e-4747-be1c-bc3737ba992f",
     "regions": {
      "1faab517-cd16-4c63-bb01-a67246749d7a": {
       "attrs": {
        "height": 0.8,
        "width": 0.8,
        "x": 0.1,
        "y": 0.1
       },
       "content": {
        "cell": "3f14ddf0-4145-4687-9c33-712c3c32520f",
        "part": "whole"
       },
       "id": "1faab517-cd16-4c63-bb01-a67246749d7a"
      }
     }
    },
    "90af992d-eb6d-4496-b2d2-6aa9a95b6a61": {
     "id": "90af992d-eb6d-4496-b2d2-6aa9a95b6a61",
     "prev": "732f1952-ee54-46fb-8067-099512824296",
     "regions": {
      "4f448bec-5be9-4553-88ae-e35ed7612f25": {
       "attrs": {
        "height": 0.8,
        "width": 0.8,
        "x": 0.1,
        "y": 0.1
       },
       "content": {
        "cell": "c445fbfb-b8ab-4e9a-8d13-12231a1c588f",
        "part": "whole"
       },
       "id": "4f448bec-5be9-4553-88ae-e35ed7612f25"
      }
     }
    },
    "bed9e696-630e-4747-be1c-bc3737ba992f": {
     "id": "bed9e696-630e-4747-be1c-bc3737ba992f",
     "prev": "23a7337f-a0cf-4ed4-baa9-ec06bfdc0579",
     "regions": {
      "ac1513f0-404f-492b-8b42-0313e9a753b0": {
       "attrs": {
        "height": 0.8,
        "width": 0.8,
        "x": 0.1,
        "y": 0.1
       },
       "content": {
        "cell": "18dd2eee-8b6c-4a5e-9539-132d00a7c7e1",
        "part": "whole"
       },
       "id": "ac1513f0-404f-492b-8b42-0313e9a753b0"
      }
     }
    },
    "de6b30f4-2463-4901-92ed-aabad78e5e0f": {
     "id": "de6b30f4-2463-4901-92ed-aabad78e5e0f",
     "prev": "e36b4639-be8c-46f7-a8c9-bcfb134f9fd0",
     "regions": {
      "55ec36e0-362f-4fd3-8060-7cee056039aa": {
       "attrs": {
        "height": 0.8,
        "width": 0.8,
        "x": 0.1,
        "y": 0.1
       },
       "content": {
        "cell": "c3cf461e-4c9e-4dec-99d2-07bfa79cbe23",
        "part": "whole"
       },
       "id": "55ec36e0-362f-4fd3-8060-7cee056039aa"
      }
     }
    },
    "e36b4639-be8c-46f7-a8c9-bcfb134f9fd0": {
     "id": "e36b4639-be8c-46f7-a8c9-bcfb134f9fd0",
     "prev": "1519a4fa-1588-4644-98de-9c43bf0aceb5",
     "regions": {
      "4c1e9714-9ba0-45fd-8a2f-ef80a5c85c2e": {
       "attrs": {
        "height": 0.8,
        "width": 0.8,
        "x": 0.1,
        "y": 0.1
       },
       "content": {
        "cell": "6534d4dc-125f-47e6-a022-cf1e0d277174",
        "part": "whole"
       },
       "id": "4c1e9714-9ba0-45fd-8a2f-ef80a5c85c2e"
      }
     }
    },
    "e76e9a02-54c1-4ec9-80fb-c611ed398122": {
     "id": "e76e9a02-54c1-4ec9-80fb-c611ed398122",
     "prev": "90af992d-eb6d-4496-b2d2-6aa9a95b6a61",
     "regions": {
      "9491b84d-193b-40ff-9321-d21eb1ba88d4": {
       "attrs": {
        "height": 0.8,
        "width": 0.8,
        "x": 0.1,
        "y": 0.1
       },
       "content": {
        "cell": "b64ec10e-fa9d-4f3f-907f-6799611ed6b1",
        "part": "whole"
       },
       "id": "9491b84d-193b-40ff-9321-d21eb1ba88d4"
      }
     }
    }
   },
   "themes": {}
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
