# Notebook from ngachago/movie_recs
Path: turicreate_recs.ipynb

!pip install turicreateCollecting turicreate
  Downloading https://files.pythonhosted.org/packages/25/9f/a76acc465d873d217f05eac4846bd73d640b9db6d6f4a3c29ad92650fbbe/turicreate-6.4.1-cp37-cp37m-manylinux1_x86_64.whl (92.0MB)
     |████████████████████████████████| 92.0MB 103kB/s
Requirement already satisfied: scipy>=1.1.0 in /usr/local/lib/python3.7/dist-packages (from turicreate) (1.4.1)
Collecting prettytable==0.7.2
  Downloading https://files.pythonhosted.org/packages/ef/30/4b0746848746ed5941f052479e7c23d2b56d174b82f4fd34a25e389831f5/prettytable-0.7.2.tar.bz2
Collecting numba<0.51.0
  Downloading https://files.pythonhosted.org/packages/04/be/8c88cee3366de2a3a23a9ff1a8be34e79ad1eb1ceb0d0e33aca83655ac3c/numba-0.50.1-cp37-cp37m-manylinux2014_x86_64.whl (3.6MB)
     |████████████████████████████████| 3.6MB 33.3MB/s
Requirement already satisfied: numpy in /usr/local/lib/python3.7/dist-packages (from turicreate) (1.19.5)
Requirement already satisfied: requests>=2.9.1 in /usr/local/lib/python3.7/dist-packages (from turicreate) (2.23.0)
Collecting resampy==0.2.1
  Downloading https://files.pythonhosted.org/packages/14/b6/66a06d85474190b50aee1a6c09cdc95bb405ac47338b27e9b21409da1760/resampy-0.2.1.tar.gz (322kB)
     |████████████████████████████████| 327kB 55.2MB/s
Requirement already satisfied: decorator>=4.0.9 in /usr/local/lib/python3.7/dist-packages (from turicreate) (4.4.2)
Collecting coremltools==3.3
  Downloading https://files.pythonhosted.org/packages/1b/1d/b1a99beca7355b6a026ae61fd8d3d36136e5b36f13e92ec5f81aceffc7f1/coremltools-3.3-cp37-none-manylinux1_x86_64.whl (3.5MB)
     |████████████████████████████████| 3.5MB 25.7MB/s
Requirement already satisfied: pandas>=0.23.2 in /usr/local/lib/python3.7/dist-packages (from turicreate) (1.1.5)
Collecting tensorflow<2.1.0,>=2.0.0
  Downloading https://files.pythonhosted.org/packages/3c/b3/3eeae9bc44039ceadceac0c7ba1cc8b1482b172810b3d7624a1cad251437/tensorflow-2.0.4-cp37-cp37m-manylinux2010_x86_64.whl (86.4MB)
     |████████████████████████████████| 86.4MB 49kB/s
Requirement already satisfied: pillow>=5.2.0 in /usr/local/lib/python3.7/dist-packages (from turicreate) (7.1.2)
Requirement already satisfied: six>=1.10.0 in /usr/local/lib/python3.7/dist-packages (from turicreate) (1.15.0)
Collecting llvmlite<0.34,>=0.33.0.dev0
  Downloading https://files.pythonhosted.org/packages/0a/28/0a35b3c2685bf2ea327cef5577bdf91f387f0f4594417a2a05a1d42fb7c2/llvmlite-0.33.0-cp37-cp37m-manylinux1_x86_64.whl (18.3MB)
     |████████████████████████████████| 18.3MB 262kB/s
Requirement already satisfied: setuptools in /usr/local/lib/python3.7/dist-packages (from numba<0.51.0->turicreate) (56.1.0)
Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests>=2.9.1->turicreate) (3.0.4)
Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests>=2.9.1->turicreate) (1.24.3)
Requirement already satisfied: idna<3,>=2.5 in /usr/local/lib/python3.7/dist-packages (from requests>=2.9.1->turicreate) (2.10)
Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.7/dist-packages (from requests>=2.9.1->turicreate) (2020.12.5)
Requirement already satisfied: protobuf>=3.1.0 in /usr/local/lib/python3.7/dist-packages (from coremltools==3.3->turicreate) (3.12.4)
Requirement already satisfied: pytz>=2017.2 in /usr/local/lib/python3.7/dist-packages (from pandas>=0.23.2->turicreate) (2018.9)
Requirement already satisfied: python-dateutil>=2.7.3 in /usr/local/lib/python3.7/dist-packages (from pandas>=0.23.2->turicreate) (2.8.1)
Collecting tensorflow-estimator<2.1.0,>=2.0.0
  Downloading https://files.pythonhosted.org/packages/fc/08/8b927337b7019c374719145d1dceba21a8bb909b93b1ad6f8fb7d22c1ca1/tensorflow_estimator-2.0.1-py2.py3-none-any.whl (449kB)
     |████████████████████████████████| 450kB 34.9MB/s
Requirement already satisfied: google-pasta>=0.1.6 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.1.0,>=2.0.0->turicreate) (0.2.0)
Requirement already satisfied: termcolor>=1.1.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.1.0,>=2.0.0->turicreate) (1.1.0)
Requirement already satisfied: grpcio>=1.8.6 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.1.0,>=2.0.0->turicreate) (1.32.0)
Collecting tensorboard<2.1.0,>=2.0.0
  Downloading https://files.pythonhosted.org/packages/76/54/99b9d5d52d5cb732f099baaaf7740403e83fe6b0cedde940fabd2b13d75a/tensorboard-2.0.2-py3-none-any.whl (3.8MB)
     |████████████████████████████████| 3.8MB 29.0MB/s
Requirement already satisfied: absl-py>=0.7.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.1.0,>=2.0.0->turicreate) (0.12.0)
Collecting gast==0.2.2
  Downloading https://files.pythonhosted.org/packages/4e/35/11749bf99b2d4e3cceb4d55ca22590b0d7c2c62b9de38ac4a4a7f4687421/gast-0.2.2.tar.gz
Requirement already satisfied: h5py<=2.10.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.1.0,>=2.0.0->turicreate) (2.10.0)
Requirement already satisfied: wheel>=0.26; python_version >= "3" in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.1.0,>=2.0.0->turicreate) (0.36.2)
Requirement already satisfied: wrapt>=1.11.1 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.1.0,>=2.0.0->turicreate) (1.12.1)
Collecting keras-applications>=1.0.8
  Downloading https://files.pythonhosted.org/packages/71/e3/19762fdfc62877ae9102edf6342d71b28fbfd9dea3d2f96a882ce099b03f/Keras_Applications-1.0.8-py3-none-any.whl (50kB)
     |████████████████████████████████| 51kB 7.8MB/s
Requirement already satisfied: astor>=0.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.1.0,>=2.0.0->turicreate) (0.8.1)
Requirement already satisfied: keras-preprocessing>=1.0.5 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.1.0,>=2.0.0->turicreate) (1.1.2)
Requirement already satisfied: opt-einsum>=2.3.2 in /usr/local/lib/python3.7/dist-packages (from tensorflow<2.1.0,>=2.0.0->turicreate) (3.3.0)
Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.1.0,>=2.0.0->tensorflow<2.1.0,>=2.0.0->turicreate) (2.0.0)
Requirement already satisfied: google-auth<2,>=1.6.3 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.1.0,>=2.0.0->tensorflow<2.1.0,>=2.0.0->turicreate) (1.30.0)
Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.1.0,>=2.0.0->tensorflow<2.1.0,>=2.0.0->turicreate) (0.4.4)
Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.7/dist-packages (from tensorboard<2.1.0,>=2.0.0->tensorflow<2.1.0,>=2.0.0->turicreate) (3.3.4)
Requirement already satisfied: rsa<5,>=3.1.4; python_version >= "3.6" in /usr/local/lib/python3.7/dist-packages (from google-auth<2,>=1.6.3->tensorboard<2.1.0,>=2.0.0->tensorflow<2.1.0,>=2.0.0->turicreate) (4.7.2)
Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.7/dist-packages (from google-auth<2,>=1.6.3->tensorboard<2.1.0,>=2.0.0->tensorflow<2.1.0,>=2.0.0->turicreate) (0.2.8)
Requirement already satisfied: cachetools<5.0,>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from google-auth<2,>=1.6.3->tensorboard<2.1.0,>=2.0.0->tensorflow<2.1.0,>=2.0.0->turicreate) (4.2.2)
Requirement already satisfied: requests-oauthlib>=0.7.0 in /usr/local/lib/python3.7/dist-packages (from google-auth-oauthlib<0.5,>=0.4.1->tensorboard<2.1.0,>=2.0.0->tensorflow<2.1.0,>=2.0.0->turicreate) (1.3.0)
Requirement already satisfied: importlib-metadata; python_version < "3.8" in /usr/local/lib/python3.7/dist-packages (from markdown>=2.6.8->tensorboard<2.1.0,>=2.0.0->tensorflow<2.1.0,>=2.0.0->turicreate) (4.0.1)
Requirement already satisfied: pyasn1>=0.1.3 in /usr/local/lib/python3.7/dist-packages (from rsa<5,>=3.1.4; python_version >= "3.6"->google-auth<2,>=1.6.3->tensorboard<2.1.0,>=2.0.0->tensorflow<2.1.0,>=2.0.0->turicreate) (0.4.8)
Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.7/dist-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<0.5,>=0.4.1->tensorboard<2.1.0,>=2.0.0->tensorflow<2.1.0,>=2.0.0->turicreate) (3.1.0)
Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata; python_version < "3.8"->markdown>=2.6.8->tensorboard<2.1.0,>=2.0.0->tensorflow<2.1.0,>=2.0.0->turicreate) (3.4.1)
Requirement already satisfied: typing-extensions>=3.6.4; python_version < "3.8" in /usr/local/lib/python3.7/dist-packages (from importlib-metadata; python_version < "3.8"->markdown>=2.6.8->tensorboard<2.1.0,>=2.0.0->tensorflow<2.1.0,>=2.0.0->turicreate) (3.7.4.3)
Building wheels for collected packages: prettytable, resampy, gast
  Building wheel for prettytable (setup.py) ... done
  Created wheel for prettytable: filename=prettytable-0.7.2-cp37-none-any.whl size=13700 sha256=9d6902657d1f235bf5a5f05cd63aa2f0d9064252d36cab482c6e9b6b62ab5b90
  Stored in directory: /root/.cache/pip/wheels/80/34/1c/3967380d9676d162cb59513bd9dc862d0584e045a162095606
  Building wheel for resampy (setup.py) ... done
  Created wheel for resampy: filename=resampy-0.2.1-cp37-none-any.whl size=320845 sha256=158e45734f9929dc8b23409f5d2294ddd99dd25d1f065ae815613c5ffbdf9878
  Stored in directory: /root/.cache/pip/wheels/ff/4f/ed/2e6c676c23efe5394bb40ade50662e90eb46e29b48324c5f9b
  Building wheel for gast (setup.py) ... done
  Created wheel for gast: filename=gast-0.2.2-cp37-none-any.whl size=7540 sha256=0d2522c284d07b8382b1db0d42e3c580de21f52c5d12be58eee240d90f0f7d3d
  Stored in directory: /root/.cache/pip/wheels/5c/2e/7e/a1d4d4fcebe6c381f378ce7743a3ced3699feb89bcfbdadadd
Successfully built prettytable resampy gast
ERROR: tensorflow 2.0.4 has requirement numpy<1.19.0,>=1.16.0, but you'll have numpy 1.19.5 which is incompatible.
ERROR: tensorflow-probability 0.12.1 has requirement gast>=0.3.2, but you'll have gast 0.2.2 which is incompatible.
ERROR: librosa 0.8.0 has requirement resampy>=0.2.2, but you'll have resampy 0.2.1 which is incompatible.
Installing collected packages: prettytable, llvmlite, numba, resampy, coremltools, tensorflow-estimator, tensorboard, gast, keras-applications, tensorflow, turicreate
  Found existing installation: prettytable 2.1.0
    Uninstalling prettytable-2.1.0:
      Successfully uninstalled prettytable-2.1.0
  Found existing installation: llvmlite 0.34.0
    Uninstalling llvmlite-0.34.0:
      Successfully uninstalled llvmlite-0.34.0
  Found existing installation: numba 0.51.2
    Uninstalling numba-0.51.2:
      Successfully uninstalled numba-0.51.2
  Found existing installation: resampy 0.2.2
    Uninstalling resampy-0.2.2:
      Successfully uninstalled resampy-0.2.2
  Found existing installation: tensorflow-estimator 2.4.0
    Uninstalling tensorflow-estimator-2.4.0:
      Successfully uninstalled tensorflow-estimator-2.4.0
  Found existing installation: tensorboard 2.4.1
    Uninstalling tensorboard-2.4.1:
      Successfully uninstalled tensorboard-2.4.1
  Found existing installation: gast 0.3.3
    Uninstalling gast-0.3.3:
      Successfully uninstalled gast-0.3.3
  Found existing installation: tensorflow 2.4.1
    Uninstalling tensorflow-2.4.1:
      Successfully uninstalled tensorflow-2.4.1
Successfully installed coremltools-3.3 gast-0.2.2 keras-applications-1.0.8 llvmlite-0.33.0 numba-0.50.1 prettytable-0.7.2 resampy-0.2.1 tensorboard-2.0.2 tensorflow-2.0.4 tensorflow-estimator-2.0.1 turicreate-6.4.1
import turicreate as tc_____no_output_____data = tc.SFrame.read_csv('clean_ratings.csv')_____no_output_____data.head(3)_____no_output_____train, test = tc.recommender.util.random_split_by_user(data, 'userId', 'title')
model = tc.recommender.create(train, 'userId', 'title', target='rating')

# Recommendations for all users
results = model.recommend()_____no_output_____results_____no_output_____# Recommendations for specific users
recommendations = model.recommend(users=[1, 30, 138491])
recommendations_____no_output_____recommendations.print_rows(num_rows=30, num_columns=4)+--------+-------------------------------+--------------------+------+
| userId |             title             |       score        | rank |
+--------+-------------------------------+--------------------+------+
|   1    | Eternal Sunshine of the Sp... | 4.840323238915466  |  1   |
|   1    |    Dark Knight, The (2008)    | 4.567221700495742  |  2   |
|   1    |        Sin City (2005)        |  4.55818572575476  |  3   |
|   1    |      Forrest Gump (1994)      | 4.488435178345703  |  4   |
|   1    |   Princess Bride, The (1987)  | 4.486539482420944  |  5   |
|   1    | City of God (Cidade de Deu... | 4.464555352276824  |  6   |
|   1    |      Batman Begins (2005)     | 4.457778125351928  |  7   |
|   1    | Fear and Loathing in Las V... | 4.440626829213165  |  8   |
|   1    | Star Wars: Episode II - At... | 4.401259689873718  |  9   |
|   1    |          Fargo (1996)         | 4.398957132643722  |  10  |
|   30   | Harry Potter and the Priso... | 4.779675125426315  |  1   |
|   30   | Eternal Sunshine of the Sp... | 4.765040903634094  |  2   |
|   30   |      Forrest Gump (1994)      | 4.566802679842971  |  3   |
|   30   |      Batman Begins (2005)     | 4.530001431054138  |  4   |
|   30   |        Sin City (2005)        | 4.485710709637664  |  5   |
|   30   |      Pulp Fiction (1994)      | 4.478504448479675  |  6   |
|   30   |      Spider-Man 2 (2004)      |  4.45189893180754  |  7   |
|   30   |          Fargo (1996)         | 4.411792903489135  |  8   |
|   30   | Fear and Loathing in Las V... | 4.392617254799865  |  9   |
|   30   |    Dark Knight, The (2008)    | 4.3924503915968165 |  10  |
| 138491 | Harry Potter and the Priso... |  4.75369805032637  |  1   |
| 138491 | Eternal Sunshine of the Sp... | 4.455697118586563  |  2   |
| 138491 | Silence of the Lambs, The ... |  4.45560097629454  |  3   |
| 138491 | Twelve Monkeys (a.k.a. 12 ... | 4.448785662001632  |  4   |
| 138491 |      Spider-Man 2 (2004)      | 4.325804113692306  |  5   |
| 138491 |      Groundhog Day (1993)     | 4.321624576396011  |  6   |
| 138491 |      Trainspotting (1996)     | 4.289129137343429  |  7   |
| 138491 | Terminator 2: Judgment Day... | 4.247376798934005  |  8   |
| 138491 | Wallace & Gromit: The Wron... | 4.228273271864913  |  9   |
| 138491 |    Dark Knight, The (2008)    |  4.22316974336531  |  10  |
+--------+-------------------------------+--------------------+------+
[30 rows x 4 columns]

# Recommendations for new users
new_user = model.recommend([139000])
new_user_____no_output_____# New user and limiting number of recommendations
lim_3 = model.recommend(users=[139000], k=3)
lim_3_____no_output_____# Include items seen during training
with_seen = model.recommend(users=[1], exclude_known=False)
with_seen_____no_output_____# Save model
model.save('movie_recs.model')

# Reload model
model = tc.load_model('movie_recs.model')_____no_output_____

## Choosing a model

_____no_output_____

# Predict the rating a user would give an item

f_model = tc.factorization_recommender.create(train, user_id='userId', item_id='title', target='rating')
f_results = f_model.recommend(users=[1, 30, 138491], k=3)
f_results_____no_output_____# Predict how likely it is that a user would rate the movie highly
# Absolute values of predicted scores may not match actual ratings

s_model = tc.item_similarity_recommender.create(train, 'userId', 'title', target='rating')_____no_output_____s_results = s_model.recommend(users=[1, 30, 138491], k=3)
s_results_____no_output_____# Predict how likely it is that a user would rate the movie highly
# Ranking factorization recommends based on items that are similar AND are highly rated

rf_model = tc.ranking_factorization_recommender.create(train, 'userId', 'title', target='rating')_____no_output_____rf_results = rf_model.recommend(users=[1, 30, 138491], k=3)
rf_results
_____no_output_____

_____no_output_____## Compare Models_____no_output_____

models = [f_model, s_model, rf_model]
model_names = ['Factorization', 'Item similarity', 'Ranking factorization']
tc.recommender.util.compare_models(test, models, model_names=model_names, metric='rmse', target='rating')
PROGRESS: Evaluate model Factorization

Overall RMSE: 0.9700989715182593

Per User RMSE (best)
+--------+----------------------+-------+
| userId |         rmse         | count |
+--------+----------------------+-------+
|  615   | 0.056858196212827505 |   2   |
+--------+----------------------+-------+
[1 rows x 3 columns]

Per User RMSE (worst)
+--------+--------------------+-------+
| userId |        rmse        | count |
+--------+--------------------+-------+
|  1215  | 2.5347860746322723 |   7   |
+--------+--------------------+-------+
[1 rows x 3 columns]

Per Item RMSE (best)
+------------------------------+-----------------------+-------+
|            title             |          rmse         | count |
+------------------------------+-----------------------+-------+
| Go Figure (Va savoir) (2001) | 0.0005060088864556889 |   1   |
+------------------------------+-----------------------+-------+
[1 rows x 3 columns]

Per Item RMSE (worst)
+------------------------------+-------------------+-------+
|            title             |        rmse       | count |
+------------------------------+-------------------+-------+
| Big Bang Theory, The (2007-) | 7.046441687090898 |   1   |
+------------------------------+-------------------+-------+
[1 rows x 3 columns]

PROGRESS: Evaluate model Item similarity

Overall RMSE: 3.6174904919357718

Per User RMSE (best)
+--------+-------------------+-------+
| userId |        rmse       | count |
+--------+-------------------+-------+
|  708   | 0.967671789990328 |   2   |
+--------+-------------------+-------+
[1 rows x 3 columns]

Per User RMSE (worst)
+--------+-------------------+-------+
| userId |        rmse       | count |
+--------+-------------------+-------+
|  914   | 4.976789468489428 |   7   |
+--------+-------------------+-------+
[1 rows x 3 columns]

Per Item RMSE (best)
+-------------------------------+--------------------+-------+
|             title             |        rmse        | count |
+-------------------------------+--------------------+-------+
| Cirque du Freak: The Vampi... | 0.4733333325386047 |   1   |
+-------------------------------+--------------------+-------+
[1 rows x 3 columns]

Per Item RMSE (worst)
+-------------------------------+------+-------+
|             title             | rmse | count |
+-------------------------------+------+-------+
| Fantastic Planet, The (Pla... | 5.0  |   1   |
+-------------------------------+------+-------+
[1 rows x 3 columns]

PROGRESS: Evaluate model Ranking factorization

Overall RMSE: 0.996348239525505

Per User RMSE (best)
+--------+---------------------+-------+
| userId |         rmse        | count |
+--------+---------------------+-------+
|  181   | 0.15216736110929277 |   2   |
+--------+---------------------+-------+
[1 rows x 3 columns]

Per User RMSE (worst)
+--------+--------------------+-------+
| userId |        rmse        | count |
+--------+--------------------+-------+
|  809   | 3.0419390720964645 |   14  |
+--------+--------------------+-------+
[1 rows x 3 columns]

Per Item RMSE (best)
+-------------------+-----------------------+-------+
|       title       |          rmse         | count |
+-------------------+-----------------------+-------+
| Guard, The (2011) | 0.0001331569762346163 |   1   |
+-------------------+-----------------------+-------+
[1 rows x 3 columns]

Per Item RMSE (worst)
+----------------------------+-------------------+-------+
|           title            |        rmse       | count |
+----------------------------+-------------------+-------+
| The Spectacular Now (2013) | 4.621904922179791 |   1   |
+----------------------------+-------------------+-------+
[1 rows x 3 columns]

_____no_output_____


# Notebook from jonfroehlich/CSE590Sp2018
Path: Assignments/A02-GestureRecognizer/Code/A02-PythonGestureRecognizer/.ipynb_checkpoints/A2 Gesture Recognizer-checkpoint.ipynb

# Notes
This Jupyter Notebook provides you with some basic scaffolding to get you started on the [A2: Gesture Recognizer assignment](https://canvas.uw.edu/courses/1199409/assignments/4176980). In particular, I wrote some parser code and some initial data structures to parse and load the gesture logs recorded with the [A2: Gesture Logger](https://github.com/jonfroehlich/CSE590Sp2018/tree/master/A02-GestureLogger).

## Getting Started
1. The first thing you need to do is to change the logPath variable to point to the directory with your gesture logs. Scroll down to the "Load the Data" cell
2. Then, you should be able to select Cell->Run All in the File Menu above and the data should be read in.
3. Hopefully, in class, we will have time to visualize and analyze these signals a bit

## Dynamic Time Warping
If you choose to explore Dynamic Time Warping (DTW), I recommend fastdtw. You can install this by typing the following in cell:
```
import sys
!{sys.executable} -m pip install fastdtw
```
See https://jakevdp.github.io/blog/2017/12/05/installing-python-packages-from-jupyter/ for more details_____no_output_____

# This cell includes the major classes used in our classification analyses
import matplotlib.pyplot as plt # needed for plotting
import numpy as np # numpy is primary library for numeric array (and matrix) handling
from scipy import signal

# Each accelerometer and gyroscope log file gets parsed and made into a SensorData object
class SensorData:

    # Constructors in Python look like this (strangely enough)
    # All arguments are numpy arrays except sensorType, which is a str
    def __init__(self, sensorType, currentTimeMs, sensorTimestampNano, x, y, z):
        self.sensorType = sensorType

        # On my mac, I could cast as straight-up int but on Windows, this failed
        # This is because on Windows, a long is 32 bit but on Unix, a long is 64bit
        # So, forcing to int64 to be safe. See: https://stackoverflow.com/q/38314118
        self.currentTimeMs = currentTimeMs.astype(np.int64)
        self.sensorTimestampNano = sensorTimestampNano.astype(np.int64)

        self.x = x.astype(float)
        self.y = y.astype(float)
        self.z = z.astype(float)

        # xSquared = np.multiply(self.x , self.x)
        # ySquared = np.multiply(self.y, self.y)
        # zSquared = np.multiply(self.z, self.z)
        # self.mag = np.sqrt(np.add(xSquared, ySquared, zSquared))
        # Fixed April 26, 2018 based on class comment by Krzysztof D.
        self.mag = np.sqrt(self.x**2 + self.y**2 + self.z**2)

    # Returns a dict of numpy arrays
    def get_data(self):
        return {"x":self.x, "y":self.y, "z":self.z, "mag":self.mag}

    # Pads the end of each data array with zeroes. Throws exception
    # if newArrayLength smaller than the current data array (and thus nothing to pad)
    def pad_with_zeros(self, newArrayLength):
        self.signalLengthBeforePadding = len(self.x)
        arrayLengthDiff = newArrayLength - len(self.x)
        if arrayLengthDiff < 0:
            raise ValueError("New array length '{}' must be larger than current array length '{}".
                             format(newArrayLength, len(self.x)))

        # np.pad allows us to pad either the left side, right side, or both sides of an array
        # in this case, we are padding only the right side. See: https://docs.scipy.org/doc/numpy/reference/generated/numpy.pad.html
        self.x = np.pad(self.x, (0, arrayLengthDiff), 'constant', constant_values=0)
        self.y = np.pad(self.y, (0, arrayLengthDiff), 'constant', constant_values=0)
        self.z = np.pad(self.z, (0, arrayLengthDiff), 'constant', constant_values=0)
        self.mag = np.pad(self.mag, (0, arrayLengthDiff), 'constant', constant_values=0)

# A trial is one gesture recording and includes an accel SensorData object and a gyro SensorData object
class Trial:

    # We actually parse the sensor log files in the constructor--this is probably bad practice
    # But offers a relatively clean solution
    def __init__(self, gestureName, endTimeMs, trialNum, accelLogFilenameWithPath, gyroLogFilenameWithPath):
        self.gestureName = gestureName
        self.trialNum = trialNum
        self.endTimeMs = endTimeMs
        self.accelLogFilenameWithPath = accelLogFilenameWithPath
        self.gyroLogFilenameWithPath = gyroLogFilenameWithPath

        # unpack=True puts each column in its own array, see https://stackoverflow.com/a/20245874
        # I had to force all types to strings because auto-type inferencing failed
        parsedAccelLogData = np.genfromtxt(accelLogFilenameWithPath, delimiter=',',
                              dtype=str, encoding=None, skip_header=1, unpack=True)

        # The asterisk is really cool in Python. It allows us to "unpack" this variable
        # into arguments needed for the SensorData constructor. Google for "tuple unpacking"
        self.accel = SensorData("Accelerometer", *parsedAccelLogData[1:])

        parsedGyroLogData = np.genfromtxt(gyroLogFilenameWithPath, delimiter=',',
                              dtype=str, encoding=None, skip_header=1, unpack=True)

        self.gyro = SensorData("Gyroscope", *parsedGyroLogData[1:])

    # Utility function that returns the end time as a nice string
    def getEndTimeMsAsString(self):
        return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(self.endTimeMs / 1000))_____no_output_____# This cell contains our file handling and parsing related functions
from os import listdir
import ntpath
import os

# Returns all csv filenames in the given directory
def find_csv_filenames( path_to_dir, suffix=".csv" ):
    filenames = listdir(path_to_dir)
    return [ filename for filename in filenames if filename.endswith( suffix ) ]

# Parses and creates Trial objects for all csv files in the given dir
# Returns a dict() mapping (str: gestureName) to (list: Trial objects)
def parse_and_create_gesture_trials( path_to_dir ):
    csvFilenames = find_csv_filenames(path_to_dir)

    print("Found {} csv files in {}".format(len(csvFilenames), path_to_dir))

    mapGestureNameToTrialList = dict()
    mapGestureNameToMapEndTimeMsToMapSensorToFile = dict()
    for csvFilename in csvFilenames:
        # parse filename into meaningful parts
        filenameNoExt = os.path.splitext(csvFilename)[0];
        filenameParts = filenameNoExt.split("_")
        gestureName = filenameParts[0]
        sensorName = filenameParts[1]
        timeMs = int(filenameParts[2])

        # print("gestureName={} sensorName={} timeMs={}".format(gestureName, sensorName, timeMs))

        if gestureName not in mapGestureNameToMapEndTimeMsToMapSensorToFile:
            mapGestureNameToMapEndTimeMsToMapSensorToFile[gestureName] = dict()

        if timeMs not in mapGestureNameToMapEndTimeMsToMapSensorToFile[gestureName]:
            mapGestureNameToMapEndTimeMsToMapSensorToFile[gestureName][timeMs] = dict()

        mapGestureNameToMapEndTimeMsToMapSensorToFile[gestureName][timeMs][sensorName] = csvFilename
        # print (mapGestureNameToMapEndTimeMsToMapSensorToFile)

    print("Found {} gestures".format(len(mapGestureNameToMapEndTimeMsToMapSensorToFile)))

    # track the longest array so we can resize accordingly (by padding with zeros currently)
    maxArrayLength = -1
    trialWithMostSensorEvents = None

    # Now we need to loop through the data and sort each gesture set by timems values
    # (so that we have trial 1, 2, 3, etc.)
    for gestureName, mapEndTimeMsToMapSensorToFile in mapGestureNameToMapEndTimeMsToMapSensorToFile.items():
        gestureTrialNum = 0
        mapGestureNameToTrialList[gestureName] = list()
        for endTimeMs in sorted(mapEndTimeMsToMapSensorToFile.keys()):
            mapSensorToFile = mapEndTimeMsToMapSensorToFile[endTimeMs]

            accelFilenameWithPath = os.path.join(logPath, mapSensorToFile["Accelerometer"])
            gyroFilenameWithPath = os.path.join(logPath, mapSensorToFile["Gyroscope"])

            gestureTrial = Trial(gestureName, endTimeMs, gestureTrialNum, accelFilenameWithPath, gyroFilenameWithPath)
            mapGestureNameToTrialList[gestureName].append(gestureTrial)

            if maxArrayLength < len(gestureTrial.accel.x):
                maxArrayLength = len(gestureTrial.accel.x)
                trialWithMostSensorEvents = gestureTrial

            gestureTrialNum = gestureTrialNum + 1

        print("Found {} trials for '{}'".format(len(mapGestureNameToTrialList[gestureName]), gestureName))

    # Some basic preprocessing
    # Resize arrays so everything is same length (necessary for shape matching)
    print("Max trial length across all gesture is '{}' Trial {} with {} sensor events. Resizing all arrays to match".
          format(trialWithMostSensorEvents.gestureName, trialWithMostSensorEvents.trialNum, maxArrayLength))
    for gestureName, trialList in mapGestureNameToTrialList.items():
        for trial in trialList:
            trial.accel.pad_with_zeros(maxArrayLength)
            trial.gyro.pad_with_zeros(maxArrayLength)

    return mapGestureNameToTrialList

# Returns the leafs in a path
# From: https://stackoverflow.com/a/8384788
def path_leaf(path):
    head, tail = ntpath.split(path)
    return tail or ntpath.basename(head)

# Utility function to extract gesture name from filename
def extract_gesture_name( filename ):
    # leaf = path_leaf(filename)
    tokenSplitPos = filename.index('_')
    gestureName = filename[:tokenSplitPos]
    return gestureName

# Returns the minimum number of trials across all gestures (just in case we accidentally recorded a
# different number. We should have 5 or 10 each for the A2 assignment)
def get_min_num_of_trials( mapGestureToTrials ):
    minNumTrials = -1
    for gestureName, trialSet in mapGestureToTrials.items():
        if minNumTrials == -1 or minNumTrials > len(trialSet):
            minNumTrials = len(trialSet)
    return minNumTrials

# returns the total number of trials
def get_total_num_of_trials (mapGestureToTrials):
    numTrials = 0
    for gestureName, trialSet in mapGestureToTrials.items():
        numTrials = numTrials + len(trialSet)
    return numTrials_____no_output_____# Load the data

# You should change the path to the location of the log files on your system
# logPath = '/Users/jonf/Dropbox/CSE590_UbiComp/Git/CSE590Sp2018p/A02-GestureRecognizer/JupyterAnalysis/GestureLogs'
# logPath = "D:\Dropbox\CSE590_UbiComp\Git\CSE590Sp2018\A02-GestureRecognizer\JonGestureLogs"

logPath = './JonGestureLogs'

mapGestureToTrials = parse_and_create_gesture_trials(logPath)Found 100 csv files in ./JonGestureLogs
Found 10 gestures
Found 5 trials for 'At Rest'
Found 5 trials for 'Backhand Tennis'
Found 5 trials for 'Baseball Throw'
Found 5 trials for 'Forehand Tennis'
Found 5 trials for 'Midair Clockwise O'
Found 5 trials for 'Midair Counter Clockwise O'
Found 5 trials for 'Midair S'
Found 5 trials for 'Midair Zorro Z'
Found 5 trials for 'Shake'
Found 5 trials for 'Underhand Bowling'
Max trial length across all gesture is 'At Rest' Trial 3 with 323 sensor events. Resizing all arrays to match
# Now, we need to plot and explore the data. Come up with a shape matching approach
# and a trained model approach (e.g., decision tree, SVM) to classify the gestures

# For example, here's how you would plot one of the signals
from random import randint
gestureNamesSorted = sorted(mapGestureToTrials.keys())
randomGestureName = gestureNamesSorted[randint(0, len(gestureNamesSorted) - 1)]

# This is where we actually make the plot.
# subplots allows us to make a nice grid of plots. For example, if you want to
# make a 2,2 grid of plots, change the 1 below to 2,2
fig, axes = plt.subplots(1, figsize=(10, 5)) #figsize is width, height
gestureTrials = mapGestureToTrials[randomGestureName]
trialNum = 0
for trial in gestureTrials:
    axes.plot(trial.accel.mag, alpha=0.7, label="Trial {}".format(trialNum))
    trialNum = trialNum + 1

# set the title and show the legend
axes.set_title(randomGestureName + " (Accel Mag)")
axes.legend()
_____no_output_____# Now let's plot all of the accel signals! :)

# We are going to make a grid of line graphs with a row for each gesture, so len(mapGestureToTrials) rows
# and a column for each signal type, so 4 columns (one for x, y, z, and mag)
fig, axes = plt.subplots(len(mapGestureToTrials), 4, figsize=(20, 3 * len(mapGestureToTrials)))
fig.subplots_adjust(hspace=0.5)

index = 0
gestureNamesSorted = sorted(mapGestureToTrials.keys())
for gestureName in gestureNamesSorted:
    gestureTrials = mapGestureToTrials[gestureName]

    trialNum = 1
    for trial in gestureTrials:
        axes[index][0].plot(trial.accel.x, alpha=0.7, label="Trial {}".format(trialNum))
        axes[index][1].plot(trial.accel.y, alpha=0.7, label="Trial {}".format(trialNum))
        axes[index][2].plot(trial.accel.z, alpha=0.7, label="Trial {}".format(trialNum))
        axes[index][3].plot(trial.accel.mag, alpha=0.7, label="Trial {}".format(trialNum))
        trialNum = trialNum + 1

    axes[index][0].set_title(gestureName + " (Accel X)")
    axes[index][0].legend()

    axes[index][1].set_title(gestureName + " (Accel Y)")
    axes[index][1].legend()

    axes[index][2].set_title(gestureName + " (Accel Z)")
    axes[index][2].legend()

    axes[index][3].set_title(gestureName + " (Accel Mag)")
    axes[index][3].legend()
    index = index + 1
_____no_output_____# In class on Thursday, April 12, I'd like you to start analyzing and comparing these gesture signals.
# Think about:
#  - What kind of filtering might be useful?
#  - What kind of signal transforms? (e.g., ffts)
#  - Is there value in exploring both the accel data AND the gyro data?
#  - What is the simplest way we can compare two signals? (scroll down and look for distance.euclidean)?
#  - What classes might you want to create to help you keep things organized? (e.g., your k-fold experiments and results)_____no_output_____

# Model-Based ML Exercises
Here is some code for the in-class exercises on Thurs, April 19_____no_output_____

# Given the online discussion about k-fold implementations, I thought I would provide my own. Note that sci-kit learn also
# has built-in functionality for this (I've never used it but worth checking out):
# http://scikit-learn.org/stable/modules/cross_validation.html
from random import randint

# Returns a list of folds where each list item is a dict() with key=gesture name and value=selected trial for that fold
# if createNewKFold is True, returns a new random fold, otherwise returns same fold setup as before
# (this is to better enable repeat experimentation). WARNING: if you are trying to use multiple gesture datasets
# make sure you set createNewKFold=True
fixedFoldsToMapGestureToTrial = None
def generate_kfolds(mapGestureToTrials, numFolds=5, createNewKFold=False):
    global fixedFoldsToMapGestureToTrial

    if createNewKFold is False and fixedFoldsToMapGestureToTrial is not None:
        return fixedFoldsToMapGestureToTrial

    # Quick check to make sure that there are numFolds of gesture trials for each gesture
    for gestureName, trials in mapGestureToTrials.items():
        if numFolds != len(trials):
            raise ValueError("For the purposes of this assignment, the number of folds={} must equal the number of trials for each gesture. Gesture '{}' has {} trials"
                             .format(numFolds, gestureName, len(trials)))

    numGestures = len(mapGestureToTrials)
    tmpMapGestureToTrials = dict()
    for gestureName, trials in mapGestureToTrials.items():
        tmpMapGestureToTrials[gestureName] = list(trials)

    gestureNames = list(mapGestureToTrials.keys())

    # create folds
    foldToMapGestureToTrial = list()
    for i in range(0, numFolds):
        curFoldMapGestureToTrial = dict()
        foldToMapGestureToTrial.append(curFoldMapGestureToTrial)

        for j in range(0, numGestures):
            curGestureName = gestureNames[j]
            trialList = tmpMapGestureToTrials[curGestureName]
            randTrialIndex = 0
            if (len(trialList) > 0):
                randTrialIndex = randint(0, len(trialList) - 1)

            randTrial = trialList[randTrialIndex]
            curFoldMapGestureToTrial[curGestureName] = randTrial
            del trialList[randTrialIndex]

    if fixedFoldsToMapGestureToTrial is None:
        fixedFoldsToMapGestureToTrial = foldToMapGestureToTrial

    return foldToMapGestureToTrial_____no_output_____# Print out the folds
numFolds = 5
foldToMapGestureToTrial = generate_kfolds(mapGestureToTrials, numFolds)

# debug check folds
foldIndex = 0
print("DEBUG: PRINTING OUT FOLDS")
for fold in foldToMapGestureToTrial:
    print("Fold: ", foldIndex)
    for gestureName, trial in fold.items():
        print("\t Gesture: {} Trial: {}".format(gestureName, trial.trialNum))
    foldIndex = foldIndex + 1DEBUG: PRINTING OUT FOLDS
Fold:  0
	 Gesture: At Rest Trial: 1
	 Gesture: Backhand Tennis Trial: 0
	 Gesture: Baseball Throw Trial: 1
	 Gesture: Forehand Tennis Trial: 1
	 Gesture: Midair Clockwise O Trial: 3
	 Gesture: Midair Counter Clockwise O Trial: 4
	 Gesture: Midair S Trial: 2
	 Gesture: Midair Zorro Z Trial: 3
	 Gesture: Shake Trial: 3
	 Gesture: Underhand Bowling Trial: 2
Fold:  1
	 Gesture: At Rest Trial: 4
	 Gesture: Backhand Tennis Trial: 3
	 Gesture: Baseball Throw Trial: 4
	 Gesture: Forehand Tennis Trial: 2
	 Gesture: Midair Clockwise O Trial: 0
	 Gesture: Midair Counter Clockwise O Trial: 3
	 Gesture: Midair S Trial: 1
	 Gesture: Midair Zorro Z Trial: 4
	 Gesture: Shake Trial: 2
	 Gesture: Underhand Bowling Trial: 0
Fold:  2
	 Gesture: At Rest Trial: 2
	 Gesture: Backhand Tennis Trial: 1
	 Gesture: Baseball Throw Trial: 3
	 Gesture: Forehand Tennis Trial: 4
	 Gesture: Midair Clockwise O Trial: 4
	 Gesture: Midair Counter Clockwise O Trial: 2
	 Gesture: Midair S Trial: 3
	 Gesture: Midair Zorro Z Trial: 2
	 Gesture: Shake Trial: 0
	 Gesture: Underhand Bowling Trial: 4
Fold:  3
	 Gesture: At Rest Trial: 0
	 Gesture: Backhand Tennis Trial: 4
	 Gesture: Baseball Throw Trial: 2
	 Gesture: Forehand Tennis Trial: 3
	 Gesture: Midair Clockwise O Trial: 1
	 Gesture: Midair Counter Clockwise O Trial: 1
	 Gesture: Midair S Trial: 0
	 Gesture: Midair Zorro Z Trial: 1
	 Gesture: Shake Trial: 1
	 Gesture: Underhand Bowling Trial: 3
Fold:  4
	 Gesture: At Rest Trial: 3
	 Gesture: Backhand Tennis Trial: 2
	 Gesture: Baseball Throw Trial: 0
	 Gesture: Forehand Tennis Trial: 0
	 Gesture: Midair Clockwise O Trial: 2
	 Gesture: Midair Counter Clockwise O Trial: 0
	 Gesture: Midair S Trial: 4
	 Gesture: Midair Zorro Z Trial: 0
	 Gesture: Shake Trial: 4
	 Gesture: Underhand Bowling Trial: 1
# Playing around with 1D Explorations of data
# TODO: brainstorm and experiment with at least five features that you think might be highly differentiable in the
# gesture dataset. I've started by plotting two simple features: the maximum magnitude and the length of the trial

import itertools

mapMarkerToDesc = {
    ".":"point",
    ",":"pixel",
    "o":"circle",
    "v":"triangle_down",
    "^":"triangle_up",
    "<":"triangle_left",
    ">":"triangle_right",
    "1":"tri_down",
    "2":"tri_up",
    "3":"tri_left",
    "4":"tri_right",
    "8":"octagon",
    "s":"square",
    "p":"pentagon",
    "*":"star",
    "h":"hexagon1",
    "H":"hexagon2",
    "+":"plus",
    "D":"diamond",
    "d":"thin_diamond",
    "|":"vline",
    "_":"hline"
}

# Plots the maximum magnitude of each trial's acceleration signal
markers = list(mapMarkerToDesc.keys())
marker = itertools.cycle(markers)
plt.figure(figsize=(12, 6))
for gestureName, trials in mapGestureToTrials.items():
    x = list(trial.accel.mag.max() for trial in trials)
    y = np.random.rand(len(x))
    s = [200] * len(x)
    plt.scatter(x, y, alpha=0.75, marker=next(marker), s=s, label=gestureName)

plt.ylim((0,10))
plt.legend(loc='upper left', bbox_to_anchor=(1,1))
plt.title("1D Plot of Max Accel Mag")
plt.show()

# Plots the length of each gesture trial
markers = list(mapMarkerToDesc.keys())
marker = itertools.cycle(markers)
plt.figure(figsize=(12, 6))
for gestureName, trials in mapGestureToTrials.items():
    x = list(trial.accel.signalLengthBeforePadding for trial in trials)
    y = np.random.rand(len(x))
    s = [200] * len(x)
    plt.scatter(x, y, alpha=0.75, marker=next(marker), s=s, label=gestureName)

plt.ylim((0,10))
plt.legend(loc='upper left', bbox_to_anchor=(1,1))
plt.title("1D Plot of Signal Length Before Padding")
plt.show()

# Add your own down here!
_____no_output_____# Now explore the discriminability of 2 dimensions!
# For this exercise, you're going to explore these features in 2D by combining them. Please wait
# to complete this exercise until we get to it in class
# I purposefully did not give you skeleton code here. Please copy/paste a section from the above cell
# and adapt it to plot two features at a time in a scatter plot_____no_output_____# Now, let's try to build an SVM using some of the features you brainstormed.
# We're going to start with the simplest possible SVM using only one feature
#
# Some nice resources:
#  - Official sci-kit learn (Start here!): http://scikit-learn.org/stable/modules/svm.html
#  - A simple classification example using scikit: https://dbaumgartel.wordpress.com/2014/03/10/a-scikit-learn-example-in-10-lines/
#  - A nice video overview of SVM: https://youtu.be/N1vOgolbjSc
#
#
from sklearn import svm

numFolds = get_min_num_of_trials(mapGestureToTrials)
numGestures = len(mapGestureToTrials)
numTrials = get_total_num_of_trials(mapGestureToTrials)
foldToMapGestureToTrial = generate_kfolds(mapGestureToTrials)

gestureNames = list(mapGestureToTrials.keys())

# now build an SVM
# Currently training on folds 1-4 and testing on fold 0 (just for now)
foldIndex = 0
mapGestureNameToCorrectMatchCnt = dict()
mapGestureNameToPredictionResultList = dict()
trainingData = np.array([])
classLabels = np.array([])
for i in range(1, numFolds):
    # print("\tFold: ", i)
    fold = foldToMapGestureToTrial[i]
    for gestureName, trial in fold.items():
        trainingData = np.append(trainingData, trial.accel.mag.max())
        classLabels = np.append(classLabels, trial.gestureName)

# for row in range(0,len(classLabels)):
#     print("gestureName={} values={}".format(classLabels[row], trainingData[row]))

# Setup SVM
trainingData = trainingData.reshape(-1, 1) # for 1D input feature vectors, we have to reshape like this

# Traing our SVM
#print(trainingData)
clf = svm.SVC()
clf.fit(trainingData, classLabels)

# Test our SVM
# fold 0 will be our test fold
testFold = foldToMapGestureToTrial[0]
for gestureName, trial in testFold.items():
    print("Attempting to predict: {}".format(gestureName))
    svmPrediction = clf.predict(trial.accel.mag.max())
    print("SVM prediction: {}".format(svmPrediction[0]))Attempting to predict: At Rest
SVM prediction: At Rest
Attempting to predict: Backhand Tennis
SVM prediction: Shake
Attempting to predict: Baseball Throw
SVM prediction: Baseball Throw
Attempting to predict: Forehand Tennis
SVM prediction: Underhand Bowling
Attempting to predict: Midair Clockwise O
SVM prediction: Midair Counter Clockwise O
Attempting to predict: Midair Counter Clockwise O
SVM prediction: Midair Counter Clockwise O
Attempting to predict: Midair S
SVM prediction: Backhand Tennis
Attempting to predict: Midair Zorro Z
SVM prediction: Midair Zorro Z
Attempting to predict: Shake
SVM prediction: Backhand Tennis
Attempting to predict: Underhand Bowling
SVM prediction: Backhand Tennis
# Here's some sample code for building up a multi-dimensional feature vector
# Feel free to use this approach (or not) in your homework

# Example create_feature_vector function that returns a 3D feature vector for the given trial
def create_simple_feature_vector(trial):
    return [trial.accel.mag.max(), trial.accel.signalLengthBeforePadding, trial.gyro.mag.max()]

# takes in the current testFold, the trainingFolds, and a create_feature_vector function
# the create_feature_vector function creates feature vectors given a Trial object
# I suggest creating multiple different create_feature_vector functions that you pass
# in here and test (this will allow you to easily compare different feature vectors)
def get_svm_input(testFold, trainingFolds, create_feature_vector):

    # calculate the number of training trials
    numOfTrainingTrials = 0
    for trainingFold in trainingFolds:
        numOfTrainingTrials = numOfTrainingTrials + len(trainingFold)

    # Now figure out the number of features from the create_feature_vector call
    # This is just a dummy call to figure out the number of features in order to
    # properly initialize our trainingData matrix
    tmpTrainingTrial = random.choice(list(trainingFolds[0].values()))
    numFeatures = len(create_feature_vector(tmpTrainingTrial))
    print("The feature vector size is: {}".format(numFeatures))

    # now we can setup our training data structures
    # each row in our trainingData matrix corresponds to a trial
    # and each column corresponds to a feature
    trainingData = np.zeros([numOfTrainingTrials, numFeatures])
    trainingTrials = list()
    trainingLabels = np.array([])

    # Build up the training data and also keep track of the class labels (in trainingLabels)
    row = 0
    for trainingFold in trainingFolds:
        for trainingGestureName, trainingTrial in trainingFold.items():
            trainingData[row] = create_feature_vector(trainingTrial)
            trainingLabels = np.append(trainingLabels, trainingTrial.gestureName)
            trainingTrials.append(trainingTrial)
            row = row + 1

    # Now setup the testData data structure
    testData = np.zeros([len(testFold), numFeatures])
    testRow = 0
    groundtruthLabels = list()
    testTrials = list()
    for testGestureName, testTrial in testFold.items():
        testTrials.append(testTrial)
        testData[testRow] = create_feature_vector(testTrial)
        groundtruthLabels.append(testGestureName)
        testRow = testRow + 1

# This is an example of how you would call the get_svm_input method
# You'll have to figre out how to appropriately put this in a for loop and use it...
svmInput = get_svm_input(testFold, trainingFolds, create_feature_vector)

# Unpack the tuple into more semantic variable names
trainingData, trainingLabels, trainingTrials, testData, groundtruthLabels, testTrials = svmInput
        _____no_output_____

# Sandbox
Everything below here is a Sandbox for you to play. You could do this in another Jupyter Notebook but I often have some cells at the bottom of my notebook that let's me experiment with and play with Python and the numpy, scipy, etc. libraries. I've added some example playground cells that I used when making the assignment.

Feel free to delete all of these cells but I thought they might be informative for you._____no_output_____

import numpy as np
x = np.array([1,2,3])
y = np.array([1,2,3])
z = np.array([1,2,3])

sum1 = np.add(x, y, z)
print(sum1)

x = np.array([1,2,3])
y = np.array([1,2,3])
z = np.array([1,2,3])

sum2 = x + y + z
print(sum2)[2 4 6]
[3 6 9]
# Testing to see if the numpy 'where' method supports string matching
a = np.array(['apple', 'orange', 'apple', 'banana'])

indicesWhereThereAreApples = np.where(a == 'apple')

print (indicesWhereThereAreApples)
print (a[indicesWhereThereAreApples])(array([0, 2]),)
['apple' 'apple']
# Playing around with classes in Python 3. Notice how just like in Javascript, you can add a new member variable
# just by starting to use it!

class DummyClass:
    def __init__(self, variable):
        self.testVar = variable

dummy = DummyClass(5)
print(dummy.testVar)
dummy.newVar = 7 # added a new member variable called newVar here. Cool!
print(dummy.newVar)
vars(dummy) # prints out the member variables of the class5
7
<__main__.DummyClass object at 0x0000021DE06F1EB8>
# Experimenting with how folding and unfolding tuples work
testTuple = (1,2,3,4,5,6,7,8,9,10)
print(testTuple)
print(*testTuple)
print(*testTuple[5:])(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
1 2 3 4 5 6 7 8 9 10
2 3 4 5 6 7 8 9 10
# Experimenting with how we delete things out of lists
import random
testDict = {"a":1, "c":3, "d":4}
a = list(testDict.keys())
print(a)
random.shuffle(a)
print(a)
del a[1]
print(a)['a', 'c', 'd']
['c', 'd', 'a']
['c', 'a']
# Playing around with how we can split up and combine lists in Python
testList = [1, 2, 3, 4, 5]
index = 4
print(testList[0:index] + testList[index + 1:5])

index = 3
print(testList[0:index] + testList[index + 1:5])

print(testList[index:])
print(testList[:index])[1, 2, 3, 4]
[1, 2, 3, 5]
[4, 5]
[1, 2, 3]
# playing around with numpy subtraction. In order for these operations to work
# the arrays must be of the same size
np1 = np.array([1, 2, 3, 4, 5])
np2 = np.array([1, 2, 4, 5, 5])
np2 - np1

np3 = [1, 2, 3]

# the (0,2) value tells pad to pad 0 times in the front of array
# and three times to the end of array. See: https://docs.scipy.org/doc/numpy/reference/generated/numpy.pad.html
np3_resized = np.pad(np3, (0, 2), 'constant', constant_values=0)
np3_resized - np2_____no_output_____# Find Euclidean distance between two numpy vector arrays
np1 = np.array([1, 2, 3, 4, 5])
np2 = np.array([5, 4, 3, 2, 1])

# First, we'll try numpy's way of determining Euclidean distance
# See: https://stackoverflow.com/a/1401828
npDist = np.linalg.norm(np2 - np1)
print(npDist)

# Next, we'll try scipy's way
# See: https://stackoverflow.com/a/21986532
from scipy.spatial import distance

scipyDist = distance.euclidean(np2,np1)
print(scipyDist)6.324555320336759
6.324555320336759
# detrend playground
from scipy import signal
a = np.random.rand(50) * 50
print(a)
b = np.array(range(0,50))
c = a + b

fig, axes = plt.subplots()
# axes.plot(a)
# axes.plot(b)
axes.plot(c, label="c (avg={:0.1f})".format(np.mean(c)))
c_detrended = signal.detrend(c)
axes.plot(c_detrended, label="c_detrended (avg={:0.1f})".format(np.mean(c_detrended)))
axes.legend()
[20.71252011  8.78988347 16.82944846 36.72949846  4.09536247 10.98916896
 20.49924781 42.04752804 23.52361472 32.81979501 25.1537431  32.63775625
 29.47310173 14.74481111 27.99181801 28.05595037  6.37351857 11.21620453
 20.05507375 27.48057611 46.0554874  30.19780715 16.81600967 46.04017909
 14.17316122 23.77002629 13.8218774  13.39551535 25.46883984 39.0992263
 39.73306045 35.93992952 36.23930638  5.25965328 11.25497228 23.57120135
 24.90890586 47.67212009 43.49724776 48.92544858 24.99838416 32.17393488
 47.28216752 18.5817449   0.83783202 33.38589305 48.89446442 15.0173838
 29.30864342 13.89376934]
# Playing around with plotting confusion matrices
# From: http://scikit-learn.org/stable/auto_examples/model_selection/plot_confusion_matrix.html#sphx-glr-auto-examples-model-selection-plot-confusion-matrix-py
import itertools
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix

def plot_confusion_matrix(cm, classes,
                          normalize=False,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):
    """
    This function prints and plots the confusion matrix.
    Normalization can be applied by setting `normalize=True`.
    """
    if normalize:
        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]
        print("Normalized confusion matrix")
    else:
        print('Confusion matrix, without normalization')

    print(cm)

    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=90)
    plt.yticks(tick_marks, classes)

    fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt),
                 horizontalalignment="center",
                 color="white" if cm[i, j] > thresh else "black")

    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')

y_true = ["cat", "ant", "cat", "cat", "ant", "bird", "bird"]
y_pred = ["ant", "ant", "cat", "cat", "ant", "cat", "bird"]
labels=["ant", "bird", "cat"]
cm = confusion_matrix(y_true, y_pred, labels)
plt.figure()
plot_confusion_matrix(cm, classes=labels,
                      title='Confusion matrix (without normalization)')

plt.figure()
plot_confusion_matrix(cm, classes=labels, normalize=True,
                      title='Confusion matrix (with normalization)')
plt.show()Confusion matrix, without normalization
[[2 0 0]
 [0 1 1]
 [1 0 2]]
Normalized confusion matrix
[[1.         0.         0.        ]
 [0.         0.5        0.5       ]
 [0.33333333 0.         0.66666667]]


# Notebook from ML-Algorithms/Iris-Flowers-Classification
Path: Machine_Learning_with_Iris_Dataset.ipynb

_____no_output_____

import numpy as np
import pandas as pd
from pandas import Series, DataFrame

import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline_____no_output_____iris = pd.read_csv("Iris.csv")_____no_output_____iris.head()_____no_output_____iris.info()<class 'pandas.core.frame.DataFrame'>
RangeIndex: 150 entries, 0 to 149
Data columns (total 6 columns):
 #   Column         Non-Null Count  Dtype
---  ------         --------------  -----
 0   Id             150 non-null    int64
 1   SepalLengthCm  150 non-null    float64
 2   SepalWidthCm   150 non-null    float64
 3   PetalLengthCm  150 non-null    float64
 4   PetalWidthCm   150 non-null    float64
 5   Species        150 non-null    object
dtypes: float64(4), int64(1), object(1)
memory usage: 7.2+ KB

### removing unneeded column_____no_output_____

iris.drop("Id", axis=1, inplace = True)_____no_output_____

### Some EDA with Iris_____no_output_____

fig = iris[iris.Species == 'Iris-setosa'].plot(kind='scatter', x='SepalLengthCm', y='SepalWidthCm', color='orange', label='Setosa')
iris[iris.Species == 'Iris-versicolor'].plot(kind='scatter', x='SepalLengthCm', y='SepalWidthCm', color='blue', label='Versicolor', ax=fig)
iris[iris.Species == 'Iris-virginica'].plot(kind='scatter', x='SepalLengthCm', y='SepalWidthCm', color='green', label='Virginica', ax=fig)

fig.set_xlabel('Sepal Length')
fig.set_ylabel('Sepal Width')
fig.set_title('Sepal Length Vs Width')

fig=plt.gcf()
fig.set_size_inches(10, 7)
plt.show()_____no_output_____sns.FacetGrid(iris, hue='Species', height=5)\
   .map(plt.scatter, 'SepalLengthCm', 'SepalWidthCm')\
   .add_legend()_____no_output_____fig = iris[iris.Species == 'Iris-setosa'].plot(kind='scatter', x='PetalLengthCm', y='PetalWidthCm', color='orange', label='Setosa')
iris[iris.Species == 'Iris-versicolor'].plot(kind='scatter', x='PetalLengthCm', y='PetalWidthCm', color='blue', label='Versicolor', ax=fig)
iris[iris.Species == 'Iris-virginica'].plot(kind='scatter', x='PetalLengthCm', y='PetalWidthCm', color='green', label='Virginica', ax=fig)

fig.set_xlabel('Petal Length')
fig.set_ylabel('Petal Width')
fig.set_title('Petal Length Vs Width')

fig=plt.gcf()
fig.set_size_inches(10, 7)
plt.show()_____no_output_____iris.hist(edgecolor='black', linewidth=1.2)
fig = plt.gcf()
fig.set_size_inches(12,6)
plt.show()_____no_output_____plt.figure(figsize=(15,10))
plt.subplot(2,2,1)
sns.violinplot(x='Species', y = 'SepalLengthCm', data=iris)
plt.subplot(2,2,2)
sns.violinplot(x='Species', y = 'SepalWidthCm', data=iris)

plt.subplot(2,2,3)
sns.violinplot(x='Species', y = 'PetalLengthCm', data=iris)
plt.subplot(2,2,4)
sns.violinplot(x='Species', y = 'PetalWidthCm', data=iris)_____no_output_____

## Now the given problem is a classification problem.. Thus we will be using the classification algorithms to build a model.

### Classification: Samples belong to two or more classes and we want to learn from already labeled data how to predict the class of unlabeled data

### Regression: If the desired output consists of one or more continuous variables, then the task is called regression. An example of a regression problem would be the prediction of the length of a salmon as a function of its age and weight.

#### Before we start, we need to clear some ML notations.
#### attributes-->An attribute is a property of an instance that may be used to determine its classification. In the following dataset, the attributes are the petal and sepal length and width. It is also known as Features.
#### Target variable, in the machine learning context is the variable that is or should be the output. Here the target variables are the 3 flower species._____no_output_____

# importing alll the necessary packages to use the various classification algorithms
from sklearn.linear_model import LogisticRegression # for Logistic Regression Algorithm
from sklearn.model_selection import train_test_split # to split the dataset for training and testing
from sklearn.neighbors import KNeighborsClassifier # KNN classifier
from sklearn import svm # for suport vector machine algorithm
from sklearn import metrics # for checking the model accuracy
from sklearn.tree import DecisionTreeClassifier # for using DTA_____no_output_____iris.shape_____no_output_____

Now, when we train any algorithm, the number of features and their correlation plays an important role. If there are features and many of the features are highly correlated, then training an algorithm with all the featues will reduce the accuracy. Thus features selection should be done carefully. This dataset has less featues but still we will see the correlation.
_____no_output_____

plt.figure(figsize=(8,4))
sns.heatmap(iris.corr(), annot=True, cmap='cubehelix_r') # draws heatmap with input as correlation matrix calculated by iris.corr()
plt.show()_____no_output_____

Observation--->
The Sepal Width and Length are not correlated The Petal Width and Length are highly correlated
We will use all the features for training the algorithm and check the accuracy.

Then we will use 1 Petal Feature and 1 Sepal Feature to check the accuracy of the algorithm as we are using only 2 features that are not correlated. Thus we can have a variance in the dataset which may help in better accuracy. We will check it later.

Steps To Be followed When Applying an Algorithm

Split the dataset into training and testing dataset. The testing dataset is generally smaller than training one as it will help in training the model better.

Select any algorithm based on the problem (classification or regression) whatever you feel may be good.
Then pass the training dataset to the algorithm to train it. We use the .fit() method
Then pass the testing data to the trained algorithm to predict the outcome. We use the .predict() method.
We then check the accuracy by passing the predicted outcome and the actual output to the model._____no_output_____## Splitting The Data into Training And Testing Dataset_____no_output_____

train, test = train_test_split(iris, test_size=0.3) # our main data split into train and test
# the attribute test_size=0.3 splits the data into 70% and 30% ratio. train=70% and test=30%
print(train.shape)
print(test.shape)(105, 5)
(45, 5)
train_X = train[['SepalLengthCm','SepalWidthCm','PetalLengthCm','PetalWidthCm']] # taking the training data features
train_y = train.Species # output of the training data

test_X = test[['SepalLengthCm','SepalWidthCm','PetalLengthCm','PetalWidthCm']] # taking test data feature
test_y = test.Species # output value of the test data_____no_output_____train_X.head()_____no_output_____test_X.head()_____no_output_____train_y.head()_____no_output_____

## Support Vector Machine SVM_____no_output_____

model = svm.SVC() # select the svm algorithm

# we train the algorithm with training data and training output
model.fit(train_X, train_y)

# we pass the testing data to the stored algorithm to predict the outcome
prediction = model.predict(test_X)
print('The accuracy of the SVM is: ', metrics.accuracy_score(prediction, test_y)) # we check the accuracy of the algorithm
#we pass the predicted output by the model and the actual outputThe accuracy of the SVM is:  0.8888888888888888

SVM is giving very good accuracy . We will continue to check the accuracy for different models.

Now we will follow the same steps as above for training various machine learning algorithms._____no_output_____### Logistic Regression _____no_output_____

model = LogisticRegression()
model.fit(train_X, train_y)
prediction = model.predict(test_X)
print('The accuracy of Logistic Regression is: ', metrics.accuracy_score(prediction, test_y))The accuracy of Logistic Regression is:  0.8888888888888888

### Decision Tree_____no_output_____

model = DecisionTreeClassifier()
model.fit(train_X, train_y)
prediction = model.predict(test_X)
print('The accuracy of Decision Tree is: ', metrics.accuracy_score(prediction, test_y))The accuracy of Decision Tree is:  0.8888888888888888

### K-Nearest Neighbors_____no_output_____

model = KNeighborsClassifier(n_neighbors=3) # this examines 3 neighbors for putting the data into class
model.fit(train_X, train_y)
prediction = model.predict(test_X)
print('The accuracy of KNN is: ', metrics.accuracy_score(prediction, test_y))The accuracy of KNN is:  0.8666666666666667

### Let's check the accuracy for various values of n for K-Nearest nerighbours
_____no_output_____

a_index = list(range(1,11))
a = pd.Series()
for i in list(range(1,11)):
    model = KNeighborsClassifier(n_neighbors=i)
    model.fit(train_X, train_y)
    prediction = model.predict(test_X)
    a = a.append(pd.Series(metrics.accuracy_score(prediction, test_y)))
plt.plot(a_index, a)
x = [1,2,3,4,5,6,7,8,9,10]
plt.xticks(x)<ipython-input-48-0380e3d3c479>:2: DeprecationWarning: The default dtype for empty Series will be 'object' instead of 'float64' in a future version. Specify a dtype explicitly to silence this warning.
  a = pd.Series()

Above is the graph showing the accuracy for the KNN models using different values of n._____no_output_____### We used all the features of iris in above models. Now we will use Petals and Sepals Seperately_____no_output_____### Creating Petals And Sepals Training Data_____no_output_____

petal = iris[['PetalLengthCm','PetalWidthCm','Species']]
sepal = iris[['SepalLengthCm','SepalWidthCm','Species']]_____no_output_____

### For Iris Petal_____no_output_____

train_p,test_p = train_test_split(petal, test_size=0.3, random_state=0) #petals
train_x_p = train_p[['PetalWidthCm','PetalLengthCm']]
train_y_p = train_p.Species

test_x_p = test_p[['PetalWidthCm','PetalLengthCm']]
test_y_p = test_p.Species_____no_output_____

### For Iris Sepal_____no_output_____

train_s,test_s = train_test_split(sepal, test_size=0.3, random_state=0) #sepals
train_x_s = train_s[['SepalWidthCm','SepalLengthCm']]
train_y_s = train_s.Species

test_x_s = test_s[['SepalWidthCm','SepalLengthCm']]
test_y_s = test_s.Species_____no_output_____

## SVM Algorithm_____no_output_____

model=svm.SVC()
model.fit(train_x_p,train_y_p)
prediction=model.predict(test_x_p)
print('The accuracy of the SVM using Petals is:',metrics.accuracy_score(prediction,test_y_p))

model=svm.SVC()
model.fit(train_x_s,train_y_s)
prediction=model.predict(test_x_s)
print('The accuracy of the SVM using Sepals is:',metrics.accuracy_score(prediction,test_y_s))The accuracy of the SVM using Petals is: 0.9777777777777777
The accuracy of the SVM using Sepals is: 0.8

## Logistic Regression_____no_output_____

model = LogisticRegression()
model.fit(train_x_p,train_y_p)
prediction=model.predict(test_x_p)
print('The accuracy of the Logistic Regression using Petals is:',metrics.accuracy_score(prediction,test_y_p))

model.fit(train_x_s,train_y_s)
prediction=model.predict(test_x_s)
print('The accuracy of the Logistic Regression using Sepals is:',metrics.accuracy_score(prediction,test_y_s))The accuracy of the Logistic Regression using Petals is: 0.9777777777777777
The accuracy of the Logistic Regression using Sepals is: 0.8222222222222222

## Decision Tree_____no_output_____

model=DecisionTreeClassifier()
model.fit(train_x_p,train_y_p)
prediction=model.predict(test_x_p)
print('The accuracy of the Decision Tree using Petals is:',metrics.accuracy_score(prediction,test_y_p))

model.fit(train_x_s,train_y_s)
prediction=model.predict(test_x_s)
print('The accuracy of the Decision Tree using Sepals is:',metrics.accuracy_score(prediction,test_y_s))The accuracy of the Decision Tree using Petals is: 0.9555555555555556
The accuracy of the Decision Tree using Sepals is: 0.6444444444444445

## K-Nearest Neighbors_____no_output_____

model=KNeighborsClassifier(n_neighbors=3)
model.fit(train_x_p,train_y_p)
prediction=model.predict(test_x_p)
print('The accuracy of the KNN using Petals is:',metrics.accuracy_score(prediction,test_y_p))

model.fit(train_x_s,train_y_s)
prediction=model.predict(test_x_s)
print('The accuracy of the KNN using Sepals is:',metrics.accuracy_score(prediction,test_y_s))The accuracy of the KNN using Petals is: 0.9777777777777777
The accuracy of the KNN using Sepals is: 0.7333333333333333

### Observations:

- Using Petals over Sepal for training the data gives a much better accuracy.
- This was expected as we saw in the heatmap above that the correlation between the Sepal Width and Length was very low whereas     the correlation between Petal Width and Length was very high._____no_output_____


# Notebook from Arnoldsynchron/2016-ml-contest
Path: geoLEARN/Submission_4_XGBoost2.ipynb

## Facies classification using ExtraTrees, OneVsRest and Feature imputation

### Contest entry by :[geoLEARN](http://geolearn.ca/)

##### [Martin Blouin](https://github.com/mablou), [Lorenzo Perozzi](https://github.com/lperozzi), [Antoine Caté](https://github.com/Antoine-Cate)

in collaboration with  [Erwan Gloaguen](http://ete.inrs.ca/erwan-gloaguen)

####  [Original contest notebook](../Facies_classification.ipynb) by Brendon Hall, [Enthought](https://www.enthought.com/)

In this notebook we will train a machine learning algorithm to predict facies from well log data.  The dataset comes from a class exercise from The University of Kansas on [Neural Networks and Fuzzy Systems](http://www.people.ku.edu/~gbohling/EECS833/).  This exercise is based on a consortium project to use machine learning techniques to create a reservoir model of the largest gas fields in North America, the Hugoton and Panoma Fields. For more info on the origin of the data, see [Bohling and Dubois (2003)](http://www.kgs.ku.edu/PRS/publication/2003/ofr2003-50.pdf) and [Dubois et al. (2007)](http://dx.doi.org/10.1016/j.cageo.2006.08.011).

The dataset consists of log data from nine wells that have been labeled with a facies type based on observation of core. We will use this log data to train a Random Forest model to classify facies types. _____no_output_____## Exploring the dataset

First, we import and examine the dataset used to train the classifier._____no_output_____

###### Importing all used packages
%matplotlib inline

import warnings
warnings.filterwarnings('ignore')

import pandas as pd
import numpy as np

from pandas import set_option
pd.options.mode.chained_assignment = None

###### Import packages needed for the make_vars functions
import Feature_Engineering as FE
import xgboost as xgb
##### import stuff from scikit learn
from sklearn.ensemble import ExtraTreesClassifier, RandomForestRegressor
from sklearn.multiclass import OneVsRestClassifier
from sklearn.model_selection import LeaveOneGroupOut, cross_val_predict

filename = 'facies_vectors.csv'
df = pd.read_csv(filename)
df.head()/usr/local/anaconda3/lib/python3.5/site-packages/sklearn/cross_validation.py:44: DeprecationWarning: This module was deprecated in version 0.18 in favor of the model_selection module into which all the refactored classes and functions are moved. Also note that the interface of the new CV iterators are different from that of this module. This module will be removed in 0.20.
  "This module will be removed in 0.20.", DeprecationWarning)
####### create X_train and y_train
X_train = df[['GR', 'ILD_log10', 'DeltaPHI', 'PHIND', 'NM_M', 'RELPOS']][df.PE.notnull()]
y_train = df['PE'][df.PE.notnull()]
groups_train = df['Well Name'][df.PE.notnull()]

X_fit = df[['GR', 'ILD_log10', 'DeltaPHI', 'PHIND', 'NM_M', 'RELPOS']][df.PE.isnull()]_____no_output_____Cl = RandomForestRegressor(n_estimators=100)
Cl.fit(X_train, y_train)
y_predict = Cl.predict(X_fit)
df['PE'][df.PE.isnull()] = y_predict
training_data = df_____no_output_____

## Feature engineering
As stated in our [previous submission](Submission_increased_variance.ipynb), we believe that feature engineering has a high potential for increasing classification success. A strategy for building new variables is explained below.

The dataset is distributed along a series of drillholes intersecting a stratigraphic sequence. Sedimentary facies tend to be deposited in sequences that reflect the evolution of the paleo-environment (variations in water depth, water temperature, biological activity, currents strenght, detrital input, ...). Each facies represents a specific depositional environment and is in contact with facies that represent a progressive transition to an other environment.
Thus, there is a relationship between neighbouring samples, and the distribution of the data along drillholes can be as important as data values for predicting facies.

A series of new variables (features) are calculated and tested below to help represent the relationship of neighbouring samples and the overall texture of the data along drillholes. These variables are:

- detail and approximation coeficients at various levels of two [wavelet transforms](https://en.wikipedia.org/wiki/Discrete_wavelet_transform) (using two types of [Daubechies](https://en.wikipedia.org/wiki/Daubechies_wavelet) wavelets);
- measures of the local entropy with variable observation windows;
- measures of the local gradient with variable observation windows;
- rolling statistical calculations (i.e., mean, standard deviation, min and max) with variable observation windows;
- ratios between marine and non-marine lithofacies with different observation windows;
- distances from the nearest marine or non-marine occurence uphole and downhole.

Functions used to build these variables are located in the [Feature Engineering](Feature_Engineering.py) python script.

All the data exploration work related to the conception and study of these variables is not presented here._____no_output_____

##### cD From wavelet db1
dwt_db1_cD_df = FE.make_dwt_vars_cD(wells_df=training_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                       levels=[1, 2, 3, 4], wavelet='db1')

##### cA From wavelet db1
dwt_db1_cA_df = FE.make_dwt_vars_cA(wells_df=training_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                       levels=[1, 2, 3, 4], wavelet='db1')

##### cD From wavelet db3
dwt_db3_cD_df = FE.make_dwt_vars_cD(wells_df=training_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                       levels=[1, 2, 3, 4], wavelet='db3')

##### cA From wavelet db3
dwt_db3_cA_df = FE.make_dwt_vars_cA(wells_df=training_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                       levels=[1, 2, 3, 4], wavelet='db3')

##### From entropy
entropy_df = FE.make_entropy_vars(wells_df=training_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                               l_foots=[2, 3, 4, 5, 7, 10])

###### From gradient
gradient_df = FE.make_gradient_vars(wells_df=training_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                                 dx_list=[2, 3, 4, 5, 6, 10, 20])

##### From rolling average
moving_av_df = FE.make_moving_av_vars(wells_df=training_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                                   windows=[1, 2, 5, 10, 20])

##### From rolling standard deviation
moving_std_df = FE.make_moving_std_vars(wells_df=training_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                                     windows=[3 , 4, 5, 7, 10, 15, 20])

##### From rolling max
moving_max_df = FE.make_moving_max_vars(wells_df=training_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                                     windows=[3, 4, 5, 7, 10, 15, 20])

##### From rolling min
moving_min_df = FE.make_moving_min_vars(wells_df=training_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                                     windows=[3 , 4, 5, 7, 10, 15, 20])

###### From rolling NM/M ratio
rolling_marine_ratio_df = FE.make_rolling_marine_ratio_vars(wells_df=training_data, windows=[5, 10, 15, 20, 30, 50, 75, 100, 200])

###### From distance to NM and M, up and down
dist_M_up_df = FE.make_distance_to_M_up_vars(wells_df=training_data)
dist_M_down_df = FE.make_distance_to_M_down_vars(wells_df=training_data)
dist_NM_up_df = FE.make_distance_to_NM_up_vars(wells_df=training_data)
dist_NM_down_df = FE.make_distance_to_NM_down_vars(wells_df=training_data)_____no_output_____list_df_var = [dwt_db1_cD_df, dwt_db1_cA_df, dwt_db3_cD_df, dwt_db3_cA_df,
               entropy_df, gradient_df, moving_av_df, moving_std_df, moving_max_df, moving_min_df,
              rolling_marine_ratio_df, dist_M_up_df, dist_M_down_df, dist_NM_up_df, dist_NM_down_df]
combined_df = training_data
for var_df in list_df_var:
    temp_df = var_df
    combined_df = pd.concat([combined_df,temp_df],axis=1)
combined_df.replace(to_replace=np.nan, value='-1', inplace=True)
print (combined_df.shape)
combined_df.head(5)(4149, 299)

## Building a prediction model from these variables_____no_output_____

X = combined_df.iloc[:, 4:]
y = combined_df['Facies']
groups = combined_df['Well Name']
XGBoost = xgb.XGBClassifier(n_estimators=200, max_depth=5, min_child_weight = 2, learning_rate=0.12, subsample=0.7, colsample_bytree=0.9, seed=i)
Cl = OneVsRestClassifier(XGBoost, n_jobs=-1)_____no_output_____

## Applying the classification model to test data_____no_output_____

filename = 'validation_data_nofacies.csv'
test_data = pd.read_csv(filename)
test_data.head(5)_____no_output_____##### cD From wavelet db1
dwt_db1_cD_df = FE.make_dwt_vars_cD(wells_df=test_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                                    levels=[1, 2, 3, 4], wavelet='db1')

##### cA From wavelet db1
dwt_db1_cA_df = FE.make_dwt_vars_cA(wells_df=test_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                       levels=[1, 2, 3, 4], wavelet='db1')

##### cD From wavelet db3
dwt_db3_cD_df = FE.make_dwt_vars_cD(wells_df=test_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                       levels=[1, 2, 3, 4], wavelet='db3')

##### cA From wavelet db3
dwt_db3_cA_df = FE.make_dwt_vars_cA(wells_df=test_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                       levels=[1, 2, 3, 4], wavelet='db3')

##### From entropy
entropy_df = FE.make_entropy_vars(wells_df=test_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                               l_foots=[2, 3, 4, 5, 7, 10])

###### From gradient
gradient_df = FE.make_gradient_vars(wells_df=test_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                                 dx_list=[2, 3, 4, 5, 6, 10, 20])

##### From rolling average
moving_av_df = FE.make_moving_av_vars(wells_df=test_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                                   windows=[1, 2, 5, 10, 20])

##### From rolling standard deviation
moving_std_df = FE.make_moving_std_vars(wells_df=test_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                                     windows=[3 , 4, 5, 7, 10, 15, 20])

##### From rolling max
moving_max_df = FE.make_moving_max_vars(wells_df=test_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                                     windows=[3, 4, 5, 7, 10, 15, 20])

##### From rolling min
moving_min_df = FE.make_moving_min_vars(wells_df=test_data, logs=['GR', 'ILD_log10', 'DeltaPHI', 'PE', 'PHIND'],
                                     windows=[3 , 4, 5, 7, 10, 15, 20])

###### From rolling NM/M ratio
rolling_marine_ratio_df = FE.make_rolling_marine_ratio_vars(wells_df=test_data, windows=[5, 10, 15, 20, 30, 50, 75, 100, 200])

###### From distance to NM and M, up and down
dist_M_up_df = FE.make_distance_to_M_up_vars(wells_df=test_data)
dist_M_down_df = FE.make_distance_to_M_down_vars(wells_df=test_data)
dist_NM_up_df = FE.make_distance_to_NM_up_vars(wells_df=test_data)
dist_NM_down_df = FE.make_distance_to_NM_down_vars(wells_df=test_data)_____no_output_____combined_test_df = test_data
list_df_var = [dwt_db1_cD_df, dwt_db1_cA_df, dwt_db3_cD_df, dwt_db3_cA_df,
               entropy_df, gradient_df, moving_av_df, moving_std_df, moving_max_df, moving_min_df,
              rolling_marine_ratio_df, dist_M_up_df, dist_M_down_df, dist_NM_up_df, dist_NM_down_df]
for var_df in list_df_var:
    temp_df = var_df
    combined_test_df = pd.concat([combined_test_df,temp_df],axis=1)
combined_test_df.replace(to_replace=np.nan, value='-99999', inplace=True)

X_test = combined_test_df.iloc[:, 3:]_____no_output_____test_pred_df = combined_test_df[['Well Name', 'Depth']]
for i in range(20):
    XGBoost = xgb.XGBClassifier(n_estimators=200, max_depth=5, min_child_weight = 2, learning_rate=0.12, subsample=0.7, colsample_bytree=0.9, seed=i)
    Cl = OneVsRestClassifier(XGBoost, n_jobs=-1)
    Cl.fit(X.values, y.values)
    y_test = Cl.predict(X_test.values)
    y_test = pd.DataFrame(y_test, columns=['Predicted Facies #' + str(i)])
    test_pred_df = pd.concat([test_pred_df, y_test], axis=1)
print (test_pred_df.shape)
test_pred_df.head()(830, 22)

## Exporting results_____no_output_____

test_pred_df.to_pickle('Prediction_submission4_XGBoost2.pkl')_____no_output_____