{"cells":[{"metadata":{"_uuid":"39816cf96d3b424db5e82be7c1b66116b63ac1ea"},"cell_type":"markdown","source":"An experiment to test KNN-DTWs against Grasp-and-Lift EEGs"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nfrom scipy.spatial.distance import euclidean\nfrom sklearn.base import BaseEstimator,ClassifierMixin\nfrom sklearn.model_selection import train_test_split\nimport fastdtw # linear-complexity dtw\nimport seaborn as sns\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7da6c4a3070ae8b439ba87f43bc3ae64d6150954"},"cell_type":"markdown","source":"Use the lovely KnnDtwClassifier from github.com/llvll "},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"# from https://github.com/llvll/motionml/blob/master/ip%5By%5D/motionml.ipynb\nclass KnnDtwClassifier(BaseEstimator, ClassifierMixin):\n    \"\"\"Custom classifier implementation for Scikit-Learn using Dynamic Time Warping (DTW)\n       and KNN (K-Nearest Neighbors) algorithms.\n       This classifier can be used for labeling the varying-length sequences, like time series\n       or motion data.\n       FastDTW library is used for faster DTW calculations - linear instead of quadratic complexity.\n    \"\"\"\n    def __init__(self, n_neighbors=1):\n        self.n_neighbors = n_neighbors\n        self.features = []\n        self.labels = []\n\n    def get_distance(self, x, y):\n        return fastdtw(x, y)[0]\n\n    def fit(self, X, y=None):\n        for index, l in enumerate(y):\n            self.features.append(X[index])\n            self.labels.append(l)\n        return self\n\n    def predict(self, X):\n        dist = np.array([self.get_distance(X, seq) for seq in self.features])\n        indices = dist.argsort()[:self.n_neighbors]\n        return np.array(self.labels)[indices]\n\n    def predict_ext(self, X):\n        dist = np.array([self.get_distance(X, seq) for seq in self.features])\n        indices = dist.argsort()[:self.n_neighbors]\n        return (dist[indices],\n                indices)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"9874f8178ef2399bf5e0b395f2252bf3a1fa94da"},"cell_type":"markdown","source":"1. Load the training data"},{"metadata":{"trusted":true,"_uuid":"66eb42078482ec010d8dd539c08e144991554c9f"},"cell_type":"code","source":"def loadDataSets(data_dir):\n    datasets = {}\n    for d in os.listdir(data_dir)[0:3]:\n        name_parts = d.split(\"_\")\n        short_name = f\"{name_parts[0]}_{name_parts[1]}\"\n        if not short_name in datasets:\n            datasets[short_name] = {\n                'events': pd.read_csv(os.path.join(data_dir, f\"{short_name}_events.csv\")),\n                'data': pd.read_csv(os.path.join(data_dir, f\"{short_name}_data.csv\")),\n            }\n    return datasets\ndatasets = loadDataSets(\"../input/train/train\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":true,"_uuid":"762c29dcc35b859d6781b2884904aafad44ce3dc"},"cell_type":"code","source":"# data = X\nfirst_key = list(datasets.keys())[0]\nprint(\"rows: \", len(datasets[first_key]['data']))\ndatasets[first_key]['data'].head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"d04a0f9be34a5352c5d11447f019e287414cfefd"},"cell_type":"code","source":"# events table = Y\nprint(\"rows: \", len(datasets[first_key]['events']))\ndatasets[first_key]['events'].head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"scrolled":false,"_uuid":"9706b840a436cedb293b3f74ba0a5114c10dba4b"},"cell_type":"code","source":"# X_all from data, drop id\n# sets = [datasets[d]['data'].drop(['id'],axis=1) for d in datasets.keys()]\nlens = [len(datasets[d]['data']) for d in datasets.keys()]\nprint(lens)\n# X_all = np.stack(sets)\n# print(X_all.shape)\n# X_all.head()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"e1ee671a22395ce0e18aabf166c90c96f6faead2"},"cell_type":"markdown","source":"I don't think it makes sense to try and KNN the samples as whole items, since they are not active the entire duration. Instead, the data should be sliced so that training samples map to a singular static output for the entire duration. Samples should be the same duration, as DTW doesn't handle the sample length itself stretching."}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.6","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}