In [1]:
"""
*** README (assumes familiarity with Jupyter notebook) ***

1. To begin, create a dataset by calling prep(window), this pre-processes the collected accelerometer+gyroscope data
in /data in the following way:

  i. For all key position data, call combine_setState_createFeatures() 

2. To run tests, it is useful to create test data. This is done with prep_test(file_to_test) - this function omits
setting the state, but the name tells you what the expected outcome should be (see also state value mappings)

3. Next, we add the HMM for smoothing. Using domain specific knowledge, we setup an emission and transition
probability matrix, which captures the liklihood of all movement between the total number of states. 



Y. Optional, use the state_reconciler on data involving stand ups to readjust the predicted states. Particularly
aimed at fixing OCG / YMOUNT errors


def main(training_window=40):
    prepped_data = prep(training_window)



ALGORITHM STEPS:

1) The first (standing up detection) RF classifier prediction output sets the 'avg_stand' 
feature in the dataframe passed to (2)

2) The main (position state) RF classifier runs and outputs predicted states

3) The "reconcile function" looks through the predicted states and for OCG and YMOUNT looks for any stand up
motions detected in the vicinity. It corrects accordingly

4) The HMM smooths the results to create clean sequences


** In future, step 1 could be replicated with other isolated movements (e.g. bridge, shrimp, sit up)

TODO: is it possible to attempt to detect stand ups using a different time window?
"""


Out[1]:
'\n*** README (assumes familiarity with Jupyter notebook) ***\n\n1. To begin, create a dataset by calling prep(window), this pre-processes the collected accelerometer+gyroscope data\nin /data in the following way:\n\n  i. For all key position data, call combine_setState_createFeatures() \n\n2. To run certain tests, it is useful to create test data. This is done with prep_test(file_to_test)\n\n\ndef main(training_window=40):\n    prepped_data = prep(training_window)\n\n\n\nALGORITHM STEPS:\n\n1) The first (standing up detection) RF classifier prediction output sets the \'avg_stand\' \nfeature in the dataframe passed to (2)\n\n2) The main (position state) RF classifier runs and outputs predicted states\n\n3) The "reconcile function" looks through the predicted states and for OCG and YMOUNT looks for any stand up\nmotions detected in the vicinity. It corrects accordingly\n\n4) The HMM smooths the results to create clean sequences\n\n\n** In future, step 1 could be replicated with other isolated movements (e.g. bridge, shrimp, sit up)\n\nTODO: is it possible to attempt to detect stand ups using a different time window?\n'

In [2]:
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import math

from hmmlearn import hmm
from sklearn import cross_validation
from sklearn.cross_validation import KFold
from sklearn.ensemble import RandomForestClassifier
from sklearn.grid_search import GridSearchCV, RandomizedSearchCV
from sklearn.metrics import confusion_matrix, accuracy_score
from sklearn.preprocessing import PolynomialFeatures

from rolltec_features import create_features
from manage_state import set_state, set_stand_state, state_reconciler
from algorithm_tests import trial, trial_standup, test_model, test_model_stand
from utilities import (convert_to_words, print_full, get_position_stats, combine_csv, resolve_acc_gyro,
                       blank_filter, concat_data)

TIME_SEQUENCE_LENGTH = 50
polynomial_features = PolynomialFeatures(interaction_only=False, include_bias=True, degree=1)

In [4]:
def update_df(df, index, new_values, reach=8):
    
    #print new_values # This is the value at the index (i.e. the row when the stand_up event was 1)
    # need to take this list and lay it over the values in the df at that index
    # TODO: catch indexing error
    
    for x in range(0,reach):
        amount = reach - x
        i = index - (amount*20)
        df.loc[i, 'state'] = new_values[x]
    
    for y in range(0,reach):
        amount = reach - y
        i = index + (amount*20)
        df.loc[i, 'state'] = new_values[y+reach]
    
    return df

In [5]:
def combine_setState_createFeatures(directory, state, window=40, stand=0):
    """
    convenience method to combine three steps in one function:
    (1) combine multiple csv files, (2) set their movement state for training,
    (3) detect any instances of standing up, (4) add features
    """
    
    combined_data = combine_csv(directory)
    combined_data_updated = set_state(combined_data, state)
    combined_data_updated2 = set_stand_state(combined_data_updated, stand)
    feature_training_data = create_features(combined_data_updated2, window)
    ready_training_data = set_state(feature_training_data, state)
    
    return ready_training_data

In [6]:
def prep(window=40):
    """prepare the raw sensor data
    
    the argument window determines the size of the sliding selection window
    for the time series. Given that data has been collected at a frequency of 
    25Hz, a sliding window of 40 will give you combined data windows 
    of 1.6 seconds.
    """

    #1 Your mount
    ymount_td = combine_setState_createFeatures('your_mount_raw_data', 'your_mount', window, 0)
    #2 Your side control
    ysc_td = combine_setState_createFeatures('your_side_control_raw_data', 'your_side_control', window, 0)
    #3 Your closed guard
    ycg_td = combine_setState_createFeatures('your_closed_guard_raw_data', 'your_closed_guard', window, 0)
    #4 Your back control
    ybc_td = combine_setState_createFeatures('your_back_control_raw_data', 'your_back_control', window, 0)
    #5 Opponent mount or opponent side control
    omountsc_td = combine_setState_createFeatures('opponent_mount_and_opponent_side_control_raw_data', 'opponent_mount_or_sc', window, 0)
    #6 Opponent closed guard
    ocg_td = combine_setState_createFeatures('opponent_closed_guard_raw_data', 'opponent_closed_guard', window, 0)
    #7 Opponent back control
    obc_td = combine_setState_createFeatures('opponent_back_control_raw_data', 'opponent_back_control', window, 0)
    #8 "Non jiu-jitsu" motion
    nonjj_td = combine_setState_createFeatures('non_jj_raw_data', 'non_jj', window, 0)
    #9 "stand up" motion
    stand_up_td = combine_setState_createFeatures('standing_up_raw_data', 'opponent_closed_guard', window, 1)

    training_data = concat_data([ymount_td, ysc_td, ycg_td, ybc_td, omountsc_td, ocg_td, obc_td, nonjj_td, stand_up_td])
    # remove NaN
    training_data = blank_filter(training_data)
    return training_data

In [7]:
def prep_test(test_file):
    el_file = 'data/test_cases/' + test_file
    df = pd.DataFrame()
    df = pd.read_csv(el_file, index_col=None, header=0)
    df = resolve_acc_gyro(df)
    df = create_features(df, _window=40, test=True)
    test_data = blank_filter(df)

    return test_data

In [8]:
training_data40 = prep(40)


/Users/christophersamiullah/repos/sensor_readings/venv/lib/python2.7/site-packages/pandas/core/common.py:516: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison
  mask = arr == x
0       NaN
1       NaN
2       NaN
3       NaN
4       NaN
5       NaN
6       NaN
7       NaN
8       NaN
9       NaN
10      NaN
11      NaN
12      NaN
13      NaN
14      NaN
15      NaN
16      NaN
17      NaN
18      NaN
19        0
20        0
21        0
22        0
23        0
24        0
25        0
26        0
27        0
28        0
29        0
         ..
16210     0
16211     0
16212     0
16213     0
16214     0
16215     0
16216     0
16217     0
16218     0
16219     0
16220     0
16221     0
16222   NaN
16223   NaN
16224   NaN
16225   NaN
16226   NaN
16227   NaN
16228   NaN
16229   NaN
16230   NaN
16231   NaN
16232   NaN
16233   NaN
16234   NaN
16235   NaN
16236   NaN
16237   NaN
16238   NaN
16239   NaN
Name: avg_stand, dtype: float64
rolltec_features.py:137: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  new_df['max_min_x'] = df2.apply(lambda x: max_min_diff(x['rolling_max_x'], x['rolling_min_x']), axis=1)
rolltec_features.py:138: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  new_df['max_min_y'] = df2.apply(lambda x: max_min_diff(x['rolling_max_y'], x['rolling_min_y']), axis=1)
rolltec_features.py:139: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  new_df['max_min_z'] = df2.apply(lambda x: max_min_diff(x['rolling_max_z'], x['rolling_min_z']), axis=1)
rolltec_features.py:140: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  new_df['max_min_gx'] = df2.apply(lambda x: max_min_diff(x['rolling_max_gx'], x['rolling_min_gx']), axis=1)
rolltec_features.py:141: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  new_df['max_min_gy'] = df2.apply(lambda x: max_min_diff(x['rolling_max_gy'], x['rolling_min_gy']), axis=1)
rolltec_features.py:142: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  new_df['max_min_gz'] = df2.apply(lambda x: max_min_diff(x['rolling_max_gz'], x['rolling_min_gz']), axis=1)
rolltec_features.py:144: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  new_df['acc_rss'] = df2.apply(lambda x: root_sum_square(x['ACCEL_X'], x['ACCEL_Y'], x['ACCEL_Z']), axis=1)
rolltec_features.py:145: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  new_df['gyro_rss'] = df2.apply(lambda x: root_sum_square(x['GYRO_X'], x['GYRO_Y'], x['GYRO_Z']), axis=1)
rolltec_features.py:147: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  new_df['acc_rms'] = df2.apply(lambda x: root_mean_square(x['ACCEL_X'], x['ACCEL_Y'], x['ACCEL_Z']), axis=1)
rolltec_features.py:148: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  new_df['gyro_rms'] = df2.apply(lambda x: root_mean_square(x['GYRO_X'], x['GYRO_Y'], x['GYRO_Z']), axis=1)
rolltec_features.py:150: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  new_df['acc_magnitude'] = df2.apply(lambda x: magnitude(x['ACCEL_X'], x['ACCEL_Y'], x['ACCEL_Z']), axis=1)
rolltec_features.py:151: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
  new_df['gyro_magnitude'] = df2.apply(lambda x: magnitude(x['GYRO_X'], x['GYRO_Y'], x['GYRO_Z']), axis=1)
0      NaN
1      NaN
2      NaN
3      NaN
4      NaN
5      NaN
6      NaN
7      NaN
8      NaN
9      NaN
10     NaN
11     NaN
12     NaN
13     NaN
14     NaN
15     NaN
16     NaN
17     NaN
18     NaN
19       0
20       0
21       0
22       0
23       0
24       0
25       0
26       0
27       0
28       0
29       0
        ..
9322     0
9323     0
9324     0
9325     0
9326     0
9327     0
9328     0
9329     0
9330     0
9331     0
9332     0
9333     0
9334   NaN
9335   NaN
9336   NaN
9337   NaN
9338   NaN
9339   NaN
9340   NaN
9341   NaN
9342   NaN
9343   NaN
9344   NaN
9345   NaN
9346   NaN
9347   NaN
9348   NaN
9349   NaN
9350   NaN
9351   NaN
Name: avg_stand, dtype: float64
0       NaN
1       NaN
2       NaN
3       NaN
4       NaN
5       NaN
6       NaN
7       NaN
8       NaN
9       NaN
10      NaN
11      NaN
12      NaN
13      NaN
14      NaN
15      NaN
16      NaN
17      NaN
18      NaN
19        0
20        0
21        0
22        0
23        0
24        0
25        0
26        0
27        0
28        0
29        0
         ..
12790     0
12791     0
12792     0
12793     0
12794     0
12795     0
12796     0
12797     0
12798     0
12799     0
12800     0
12801     0
12802   NaN
12803   NaN
12804   NaN
12805   NaN
12806   NaN
12807   NaN
12808   NaN
12809   NaN
12810   NaN
12811   NaN
12812   NaN
12813   NaN
12814   NaN
12815   NaN
12816   NaN
12817   NaN
12818   NaN
12819   NaN
Name: avg_stand, dtype: float64
0      NaN
1      NaN
2      NaN
3      NaN
4      NaN
5      NaN
6      NaN
7      NaN
8      NaN
9      NaN
10     NaN
11     NaN
12     NaN
13     NaN
14     NaN
15     NaN
16     NaN
17     NaN
18     NaN
19       0
20       0
21       0
22       0
23       0
24       0
25       0
26       0
27       0
28       0
29       0
        ..
5893     0
5894     0
5895     0
5896     0
5897     0
5898     0
5899     0
5900     0
5901     0
5902     0
5903     0
5904     0
5905   NaN
5906   NaN
5907   NaN
5908   NaN
5909   NaN
5910   NaN
5911   NaN
5912   NaN
5913   NaN
5914   NaN
5915   NaN
5916   NaN
5917   NaN
5918   NaN
5919   NaN
5920   NaN
5921   NaN
5922   NaN
Name: avg_stand, dtype: float64
0       NaN
1       NaN
2       NaN
3       NaN
4       NaN
5       NaN
6       NaN
7       NaN
8       NaN
9       NaN
10      NaN
11      NaN
12      NaN
13      NaN
14      NaN
15      NaN
16      NaN
17      NaN
18      NaN
19        0
20        0
21        0
22        0
23        0
24        0
25        0
26        0
27        0
28        0
29        0
         ..
18552     0
18553     0
18554     0
18555     0
18556     0
18557     0
18558     0
18559     0
18560     0
18561     0
18562     0
18563     0
18564   NaN
18565   NaN
18566   NaN
18567   NaN
18568   NaN
18569   NaN
18570   NaN
18571   NaN
18572   NaN
18573   NaN
18574   NaN
18575   NaN
18576   NaN
18577   NaN
18578   NaN
18579   NaN
18580   NaN
18581   NaN
Name: avg_stand, dtype: float64
0       NaN
1       NaN
2       NaN
3       NaN
4       NaN
5       NaN
6       NaN
7       NaN
8       NaN
9       NaN
10      NaN
11      NaN
12      NaN
13      NaN
14      NaN
15      NaN
16      NaN
17      NaN
18      NaN
19        0
20        0
21        0
22        0
23        0
24        0
25        0
26        0
27        0
28        0
29        0
         ..
16730     0
16731     0
16732     0
16733     0
16734     0
16735     0
16736     0
16737     0
16738     0
16739     0
16740     0
16741     0
16742   NaN
16743   NaN
16744   NaN
16745   NaN
16746   NaN
16747   NaN
16748   NaN
16749   NaN
16750   NaN
16751   NaN
16752   NaN
16753   NaN
16754   NaN
16755   NaN
16756   NaN
16757   NaN
16758   NaN
16759   NaN
Name: avg_stand, dtype: float64
0      NaN
1      NaN
2      NaN
3      NaN
4      NaN
5      NaN
6      NaN
7      NaN
8      NaN
9      NaN
10     NaN
11     NaN
12     NaN
13     NaN
14     NaN
15     NaN
16     NaN
17     NaN
18     NaN
19       0
20       0
21       0
22       0
23       0
24       0
25       0
26       0
27       0
28       0
29       0
        ..
8690     0
8691     0
8692     0
8693     0
8694     0
8695     0
8696     0
8697     0
8698     0
8699     0
8700     0
8701     0
8702   NaN
8703   NaN
8704   NaN
8705   NaN
8706   NaN
8707   NaN
8708   NaN
8709   NaN
8710   NaN
8711   NaN
8712   NaN
8713   NaN
8714   NaN
8715   NaN
8716   NaN
8717   NaN
8718   NaN
8719   NaN
Name: avg_stand, dtype: float64
0       NaN
1       NaN
2       NaN
3       NaN
4       NaN
5       NaN
6       NaN
7       NaN
8       NaN
9       NaN
10      NaN
11      NaN
12      NaN
13      NaN
14      NaN
15      NaN
16      NaN
17      NaN
18      NaN
19        0
20        0
21        0
22        0
23        0
24        0
25        0
26        0
27        0
28        0
29        0
         ..
48810     0
48811     0
48812     0
48813     0
48814     0
48815     0
48816     0
48817     0
48818     0
48819     0
48820     0
48821     0
48822   NaN
48823   NaN
48824   NaN
48825   NaN
48826   NaN
48827   NaN
48828   NaN
48829   NaN
48830   NaN
48831   NaN
48832   NaN
48833   NaN
48834   NaN
48835   NaN
48836   NaN
48837   NaN
48838   NaN
48839   NaN
Name: avg_stand, dtype: float64
0       NaN
1       NaN
2       NaN
3       NaN
4       NaN
5       NaN
6       NaN
7       NaN
8       NaN
9       NaN
10      NaN
11      NaN
12      NaN
13      NaN
14      NaN
15      NaN
16      NaN
17      NaN
18      NaN
19        1
20        1
21        1
22        1
23        1
24        1
25        1
26        1
27        1
28        1
29        1
         ..
20850     1
20851     1
20852     1
20853     1
20854     1
20855     1
20856     1
20857     1
20858     1
20859     1
20860     1
20861     1
20862   NaN
20863   NaN
20864   NaN
20865   NaN
20866   NaN
20867   NaN
20868   NaN
20869   NaN
20870   NaN
20871   NaN
20872   NaN
20873   NaN
20874   NaN
20875   NaN
20876   NaN
20877   NaN
20878   NaN
20879   NaN
Name: avg_stand, dtype: float64
Removed 612 NaN rows

In [9]:
test_data1 = prep_test('test1_ymount_ycg.csv')
test_data4 = prep_test('GL_TEST1_CS.csv')
test_data5 = prep_test('GL_TEST2_CS.csv')
test_data6 = prep_test('GL_TEST3_CS_very_still.csv')
test_data7 = prep_test('GL_TEST1_UrsWearing.csv')
test_data8 = prep_test('DIO_YCG_YMOUNT_YSC.csv')
test_data9 = prep_test('DIO_OCG_YCG_YMOUNT_YBC.csv')


Removed 2 NaN rows
Removed 2 NaN rows
Removed 1 NaN rows
Removed 4 NaN rows
Removed 1 NaN rows
Removed 0 NaN rows
Removed 1 NaN rows

In [12]:
"""
This is for testing the effectiveness of the 
standing motion detection. The datasets below with STAND in the
name refer to sequences involving a stand up.

This is effectively a tangent to the main algorithm, but one which could
be very useful and widely applicable.
"""

test_data100 = prep_test('CS_OCG_STAND_OCG.csv')
#test_data101 = prep_test('URS_OCG_STAND_OCG1.csv')

# TODO: DEBUG If I move the test data creation out of this cell it causes an error

foo = trial_standup(training_data40, test_data100)

# HAVE TO BE CAREFUL WITH CREATING COPIES OF DF vs. actually changing the original - is creating bugs
step2 = trial(training_data40, foo)
print step2[['state', 'avg_stand']]

# step 3

fixed = state_reconciler(step2)

test_data1000 = prep_test('URS_OCG_STAND_OCG3.csv')
baz = trial_standup(training_data40, test_data1000)
step2again = trial(training_data40, baz)
pre_pre_smooth = step2again['state'].values
pre_pre_smooth_words = convert_to_words(pre_pre_smooth)

pre_smooth = fixed['state'].values
pre_smooth_words = convert_to_words(pre_smooth)

print pre_pre_smooth_words
print pre_smooth_words


Removed 1 NaN rows
[ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
  0.  0.  0.  0.  1.  0.  1.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
  0.  0.]
['your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_side_control', 'your_mount', 'your_side_control', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'your_mount']
Your Mount: 0.947368421053
Your Side Control: 0.0526315789474
Your Closed Guard: 0.0
Your Back Control: 0.0
Opponent Mount or Opponent Side Control: 0.0
Opponent Closed Guard: 0.0
Opponent Back Control: 0.0
OTHER: 0.0

[7 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 7 7 5 5 5 5 5 5 5 5 5 7 7 0 0 0 0 5 5 5 5
 5]
['OTHER', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'OTHER', 'OTHER', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'OTHER', 'OTHER', 'your_mount', 'your_mount', 'your_mount', 'your_mount', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard']
Your Mount: 0.105263157895
Your Side Control: 0.0
Your Closed Guard: 0.0
Your Back Control: 0.0
Opponent Mount or Opponent Side Control: 0.0
Opponent Closed Guard: 0.763157894737
Opponent Back Control: 0.0
OTHER: 0.131578947368

     state  avg_stand
19       7          0
39       5          0
59       5          0
79       5          0
99       5          0
119      5          0
139      5          0
159      5          0
179      5          0
199      5          0
219      5          0
239      5          0
259      5          0
279      5          0
299      5          0
319      5          0
339      7          0
359      7          0
379      5          0
399      5          0
419      5          0
439      5          0
459      5          1
479      5          0
499      5          1
519      5          0
539      5          0
559      7          0
579      7          0
599      0          0
619      0          0
639      0          0
659      0          0
679      5          0
699      5          0
719      5          0
739      5          0
759      5          0

In [14]:
n_components = 8 # ('ybc', 'ymount', 'ysc', 'ycg', 'ocg', 'osc_mount', 'obc', 'other')
startprob = np.array([0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.65,]) # assume users will turn on sensor whist standing

In [15]:
"""
probability of these positions given current state:

your_mount' if v == 0 
else 'your_side_control' if v == 1
else 'your_closed_guard' if v == 2
else 'your_back_control' if v == 3
else 'opponent_mount_or_sc' if v == 4
else 'opponent_closed_guard' if v == 5
else 'opponent_back_control' if v == 6
else 'OTHER' if v == 7

transition_probability = {
        'ymt' : {'ymount': 0.800, 'ysc': 0.050, 'ycg': 0.010, 'ybc': 0.050, 'osc_mount': 0.001, 'ocg': 0.050, 'obc': 0.001, 'other': 0.038},
        'ysc' : {'ymount': 0.100, 'ysc': 0.800, 'ycg': 0.010, 'ybc': 0.010, 'osc_mount': 0.001, 'ocg': 0.050, 'obc': 0.001, 'other': 0.028},
        'ycg' : {'ymount': 0.010, 'ysc': 0.050, 'ycg': 0.800, 'ybc': 0.010, 'osc_mount': 0.050, 'ocg': 0.001, 'obc': 0.001, 'other': 0.078},
        'ybc' : {'ymount': 0.050, 'ysc': 0.010, 'ycg': 0.050, 'ybc': 0.800, 'osc_mount': 0.001, 'ocg': 0.010, 'obc': 0.001, 'other': 0.078},
        'omt' : {'ymount': 0.001, 'ysc': 0.050, 'ycg': 0.010, 'ybc': 0.001, 'osc_mount': 0.800, 'ocg': 0.050, 'obc': 0.050, 'other': 0.038},
        'ocg' : {'ymount': 0.100, 'ysc': 0.050, 'ycg': 0.010, 'ybc': 0.010, 'osc_mount': 0.001, 'ocg': 0.800, 'obc': 0.001, 'other': 0.028},
        'obc' : {'ymount': 0.010, 'ysc': 0.050, 'ycg': 0.001, 'ybc': 0.010, 'osc_mount': 0.050, 'ocg': 0.001, 'obc': 0.800, 'other': 0.078},
        'oth' : {'ymount': 0.050, 'ysc': 0.010, 'ycg': 0.050, 'ybc': 0.078, 'osc_mount': 0.001, 'ocg': 0.010, 'obc': 0.001, 'other': 0.800}
     }
"""

transmat = np.array([
                    [0.800, 0.050, 0.010, 0.050, 0.001, 0.050, 0.001, 0.038], 
                    [0.100, 0.800, 0.010, 0.010, 0.001, 0.050, 0.001, 0.028], 
                    [0.010, 0.050, 0.800, 0.010, 0.050, 0.001, 0.001, 0.078], 
                    [0.050, 0.010, 0.050, 0.800, 0.001, 0.010, 0.001, 0.078],
                    [0.001, 0.050, 0.010, 0.001, 0.800, 0.050, 0.050, 0.038],
                    [0.100, 0.050, 0.010, 0.010, 0.001, 0.800, 0.001, 0.028],
                    [0.010, 0.050, 0.001, 0.010, 0.050, 0.001, 0.800, 0.078],
                    [0.050, 0.010, 0.050, 0.078, 0.001, 0.010, 0.001, 0.800],
                    ])

In [40]:
"""

probability of these positions given current state:

your_mount' if v == 0 
else 'your_side_control' if v == 1
else 'your_closed_guard' if v == 2
else 'your_back_control' if v == 3
else 'opponent_mount_or_sc' if v == 4
else 'opponent_closed_guard' if v == 5
else 'opponent_back_control' if v == 6
else 'OTHER' if v == 7

emission_probability = {
        'ymt' : {'ymount': 0.500, 'ysc': 0.050, 'ycg': 0.010, 'ybc': 0.050, 'osc_mount': 0.001, 'ocg': 0.350, 'obc': 0.001, 'other': 0.038},
        'ysc' : {'ymount': 0.100, 'ysc': 0.800, 'ycg': 0.010, 'ybc': 0.010, 'osc_mount': 0.001, 'ocg': 0.050, 'obc': 0.001, 'other': 0.028},
        'ycg' : {'ymount': 0.010, 'ysc': 0.050, 'ycg': 0.400, 'ybc': 0.010, 'osc_mount': 0.500, 'ocg': 0.001, 'obc': 0.001, 'other': 0.078},
        'ybc' : {'ymount': 0.050, 'ysc': 0.010, 'ycg': 0.050, 'ybc': 0.600, 'osc_mount': 0.001, 'ocg': 0.010, 'obc': 0.201, 'other': 0.078},
        'omt' : {'ymount': 0.001, 'ysc': 0.050, 'ycg': 0.210, 'ybc': 0.050, 'osc_mount': 0.600, 'ocg': 0.050, 'obc': 0.001, 'other': 0.038},
        'ocg' : {'ymount': 0.400, 'ysc': 0.050, 'ycg': 0.010, 'ybc': 0.010, 'osc_mount': 0.001, 'ocg': 0.400, 'obc': 0.001, 'other': 0.028},
        'obc' : {'ymount': 0.010, 'ysc': 0.050, 'ycg': 0.001, 'ybc': 0.110, 'osc_mount': 0.050, 'ocg': 0.001, 'obc': 0.700, 'other': 0.078},
        'oth' : {'ymount': 0.050, 'ysc': 0.010, 'ycg': 0.050, 'ybc': 0.078, 'osc_mount': 0.001, 'ocg': 0.010, 'obc': 0.001, 'other': 0.800}
     }
"""

emissionprob = np.array([
                        [0.500, 0.050, 0.010, 0.050, 0.001, 0.350, 0.001, 0.038], 
                        [0.100, 0.800, 0.010, 0.010, 0.001, 0.050, 0.001, 0.028], 
                        [0.010, 0.050, 0.350, 0.010, 0.500, 0.001, 0.001, 0.078], 
                        [0.050, 0.010, 0.050, 0.700, 0.001, 0.010, 0.101, 0.078],
                        [0.001, 0.050, 0.210, 0.050, 0.600, 0.050, 0.001, 0.038],
                        [0.400, 0.050, 0.010, 0.010, 0.001, 0.400, 0.001, 0.028],
                        [0.010, 0.050, 0.001, 0.110, 0.050, 0.001, 0.700, 0.078],
                        [0.050, 0.010, 0.050, 0.078, 0.001, 0.010, 0.001, 0.800],
                        ])

In [41]:
# Hidden Markov Model with multinomial (discrete) emissions
model = hmm.MultinomialHMM(n_components=n_components,
                           n_iter=10,
                           verbose=False)

model.startprob_ = startprob
model.transmat_ = transmat
model.emissionprob_ = emissionprob
# model.n_features = 8

In [42]:
observations = np.array(pre_smooth)

n_samples = len(observations)
data = observations.reshape((n_samples, -1))
print data


[[5]
 [5]
 [5]
 [5]
 [5]
 [5]
 [5]
 [5]
 [5]
 [7]
 [5]
 [5]
 [5]
 [5]
 [5]
 [5]
 [5]
 [5]
 [5]
 [0]
 [0]
 [5]
 [5]
 [7]
 [7]
 [7]]

In [43]:
print 'TEST 1'

result = model.decode(data, algorithm='viterbi')
print 'pre smooth: {}'.format(pre_pre_smooth)
print 'result accuracy {}%'.format(result[0])
print 'final result: {}'.format(result[1])

result_words = convert_to_words(result[1])
print '====================='
print 'pre pre smooth words: {}'.format(pre_pre_smooth_words)
print '====================='
print 'result words: {}'.format(result_words)


print '\n'
print "pre pre smooth stats (before stand up detection)"
print get_position_stats(pre_pre_smooth_words)


print '\n'
print "pre smooth stats (before HMM)"
print get_position_stats(pre_smooth_words)

print '\n'

print 'result stats'
print get_position_stats(result_words)

print '******************'


TEST 1
pre smooth: [5 5 5 0 0 5 5 5 5 5 5 7 5 5 5 5 5 0 5 0 0 5 5 7 7 7]
result accuracy -36.3301057979%
final result: [5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 7 7 7]
=====================
pre pre smooth words: ['opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'your_mount', 'your_mount', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'OTHER', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'your_mount', 'opponent_closed_guard', 'your_mount', 'your_mount', 'opponent_closed_guard', 'opponent_closed_guard', 'OTHER', 'OTHER', 'OTHER']
=====================
result words: ['opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'opponent_closed_guard', 'OTHER', 'OTHER', 'OTHER']


pre pre smooth stats (before stand up detection)
Your Mount: 0.192307692308
Your Side Control: 0.0
Your Closed Guard: 0.0
Your Back Control: 0.0
Opponent Mount or Opponent Side Control: 0.0
Opponent Closed Guard: 0.653846153846
Opponent Back Control: 0.0
OTHER: 0.153846153846

None


pre smooth stats (before HMM)
Your Mount: 0.0769230769231
Your Side Control: 0.0
Your Closed Guard: 0.0
Your Back Control: 0.0
Opponent Mount or Opponent Side Control: 0.0
Opponent Closed Guard: 0.769230769231
Opponent Back Control: 0.0
OTHER: 0.153846153846

None


result stats
Your Mount: 0.0
Your Side Control: 0.0
Your Closed Guard: 0.0
Your Back Control: 0.0
Opponent Mount or Opponent Side Control: 0.0
Opponent Closed Guard: 0.884615384615
Opponent Back Control: 0.0
OTHER: 0.115384615385

None
******************

In [ ]: