{"cells":[{"metadata":{"trusted":true,"_uuid":"5e3cc32d3d80609faff3b75cc59d2f61758744c9","scrolled":true},"cell_type":"code","source":"# for hyper parameter search\n!pip install optuna","execution_count":null,"outputs":[]},{"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)\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":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"import pyarrow.parquet as pq","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"01594fd1d337c617a1a6ee8e3a6294827765a814"},"cell_type":"code","source":"from pathlib import Path","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8aa52ec3fb464bdb8d7707a0eca1599509c808b2"},"cell_type":"code","source":"class DataPaths(object):\n    TRAIN_PARQUET_PATH = Path('../input/train.parquet')\n    TRAIN_METADATA_PATH = Path('../input/metadata_train.csv')\n    TEST_PARQUET_PATH = Path('../input/test.parquet')\n    TEST_MATADATA_PATH = Path('../input/metadata_test.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2cce94cb8c0e7b132b5cbb949fdb8c7176b99a93"},"cell_type":"code","source":"train_meta_df = pd.read_csv('../input/metadata_train.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"fba17be63cbd6629762d97506e679b87f669a9b4"},"cell_type":"code","source":"train_meta_df[:10]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"0f95bb722af928fa33302e932a09e804bce1ad5b"},"cell_type":"code","source":"# for debug\n# train_meta_df = train_meta_df.iloc[:600]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"2c444b89032ba1111f8b3c804050d00affc43348"},"cell_type":"code","source":"train_meta_df.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9fb51602e3d410d06449be8da53cd679ead5f0d9"},"cell_type":"code","source":"train_meta_df.describe()","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"231506ab85eb2b5a6e90e724b972388122c32b83"},"cell_type":"markdown","source":""},{"metadata":{"_uuid":"2119ffe6eb9430281b8a70f5dd96268ad9d28682"},"cell_type":"markdown","source":"# feature extraction"},{"metadata":{"trusted":true,"_uuid":"06fe4a5d936b1b40791331e79efc7f412b98dce3"},"cell_type":"code","source":"from scipy import signal","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"99d70a58d66fdae947874e23d432cccdee92c248"},"cell_type":"code","source":"import pywt","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"151e6c21d6b79c017c5f6953094bc8e6b27ca4ea"},"cell_type":"code","source":"WAVELET_WIDTH = 30","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3ed6eb6a60900355cc35dc55b25b693d3021e018"},"cell_type":"code","source":"from sklearn.preprocessing import FunctionTransformer","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"ee0b6d2310486fdf80a1a9fcd29839b2b8c04cc3"},"cell_type":"code","source":"subset_train = pq","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9792deb1eb2c9e585dab31738e712f9d16968872"},"cell_type":"code","source":"class SummaryTransformer(FunctionTransformer):\n    def __init__(self, \n                 kw_args=None, inv_kw_args=None):\n        validate = False\n        inverse_func = None\n        accept_sparse = False\n        pass_y = 'deprecated'\n        super().__init__(self.f, inverse_func, validate, accept_sparse, pass_y, kw_args, inv_kw_args)\n    \n    def f(self, X):\n        avgs = np.mean(X)\n        stds = np.std(X)\n        maxs = np.max(X)\n        mins = np.min(X)\n        medians = np.median(X)\n        return np.array([avgs, stds, maxs, mins, medians])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"13ed45fade3f2ea4472829898870bd3ae24c1254"},"cell_type":"code","source":"class WaevletSummaryTransformer(FunctionTransformer):\n    def __init__(self, wavelet_width,\n                 kw_args=None, inv_kw_args=None):\n        validate = False\n        inverse_func = None\n        accept_sparse = False\n        pass_y = 'deprecated'\n        self.wavelet_width = wavelet_width\n        super().__init__(self.f, inverse_func, validate, accept_sparse, pass_y, kw_args, inv_kw_args)\n    \n    def f(self, X):\n#         wavelets = signal.cwt(X, signal.ricker, np.arange(1, self.wavelet_width + 1))\n        wavelets, _ = pywt.cwt(X, np.arange(1, self.wavelet_width + 1), 'mexh')\n        avgs = np.mean(wavelets, axis=1)\n        stds = np.std(wavelets, axis=1)\n        maxs = np.max(wavelets, axis=1)\n        mins = np.min(wavelets, axis=1)\n        medians = np.median(wavelets, axis=1)\n        return np.concatenate([avgs, stds, maxs, mins, medians])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"30fe4552db1b0b005983d7763d3289b76ae56e11"},"cell_type":"code","source":"class SpectrogramSummaryTransformer(FunctionTransformer):\n    def __init__(self, sample_rate, fft_length, stride_length,\n                 kw_args=None, inv_kw_args=None):\n        validate = False\n        inverse_func = None\n        accept_sparse = False\n        pass_y = 'deprecated'\n        self.sample_rate = sample_rate\n        self.fft_length = fft_length\n        self.stride_length = stride_length\n        super().__init__(self.f, inverse_func, validate, accept_sparse, pass_y, kw_args, inv_kw_args)\n    \n    def f(self, X):\n        X = self.to_spectrogram(X)\n        avgs = np.mean(X, axis=1)\n        stds = np.std(X, axis=1)\n        maxs = np.max(X, axis=1)\n        mins = np.min(X, axis=1)\n        medians = np.median(X, axis=1)\n        return np.concatenate([avgs, stds, maxs, mins, medians])\n\n    def to_spectrogram(self, series):\n        f, t, Sxx = signal.spectrogram(series, fs=self.sample_rate, nperseg=self.fft_length,\n                                   noverlap=self.fft_length - self.stride_length, window=\"hanning\", axis=0,\n                                   return_onesided=True, mode=\"magnitude\", scaling=\"density\")\n        return Sxx","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"052e7c5b7177447a400fc878782d97ca39040668"},"cell_type":"code","source":"from typing import List","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"f0e243fff59c7a8b04e7188a1257d84d800ada10"},"cell_type":"code","source":"from sklearn.base import TransformerMixin","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"586f3c2c94ddec87fc9199560a84406c113faedd"},"cell_type":"code","source":"train_meta_df.columns","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1d0af4299e447ec80a8c6a0fd6b98423836f3f83"},"cell_type":"code","source":"def read_column(parquet_path, column_id):\n    return pq.read_pandas(parquet_path, columns=[str(column_id)]).to_pandas()[str(column_id)]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"bed388f2029b0d09a8676d3915bd841a50eb1954"},"cell_type":"code","source":"import itertools","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9baf299c4a811f637314a07c3f15abfcd8a48597"},"cell_type":"code","source":"from tqdm import tqdm_notebook","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1982f42171235a8de916a06d797a18d004d338aa"},"cell_type":"code","source":"from multiprocessing.pool import Pool","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"92b1203056d8d4e45fe56337b6a1e6a41fc52dc2"},"cell_type":"code","source":"class FeatureExtractor(object):\n    def __init__(self, transformers):\n        self.transformers: List[TransformerMixin] = transformers\n        self._parquet_path = None\n        self._meta_df = None\n    \n    def fit(self, parquet_path, meta_df):\n        pass\n    \n    def from_signal(self, parquet_path, signal_id):\n        return [ transformer.transform(read_column(parquet_path, signal_id).values)  \n                                          for transformer in self.transformers]\n    \n    def from_measurement(self, measure_id):\n        temp = np.concatenate(\n            list(itertools.chain.from_iterable(\n                [ self.from_signal(self._parquet_path, signal_id) for signal_id \n                 in self._meta_df[self._meta_df[\"id_measurement\"] == measure_id].signal_id\n                ]\n            ))\n        )\n        return temp\n    \n    def transform(self, parquet_path, meta_df, n_jobs=2):\n        self._parquet_path = parquet_path\n        self._meta_df = meta_df\n        with Pool(n_jobs) as pool:\n            rows = pool.map(self.from_measurement, self._meta_df.id_measurement.unique())\n        return np.vstack(rows)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"9e0f819cde207b2eb8ec64dff9ee9e6bfef68e52"},"cell_type":"code","source":"N_MEASUREMENTS = 800000","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"12a050d96451e185775c0f0edca9856832c5c6b8"},"cell_type":"code","source":"TOTAL_DURATION = 20e-3","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"51e12982874cb33211d164f2c7b3d6799058f0bf"},"cell_type":"code","source":"sample_rate = N_MEASUREMENTS / TOTAL_DURATION","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e3cb26ddeb1bb451f594d1094e40f43feebe99a9"},"cell_type":"code","source":"# wavelet transform takes too much time\n# extractor = FeatureExtractor([SummaryTransformer(), WaevletSummaryTransformer(WAVELET_WIDTH), SpectrogramSummaryTransformer(\n#     sample_rate= sample_rate, fft_length=200, stride_length=100)])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e3cb26ddeb1bb451f594d1094e40f43feebe99a9"},"cell_type":"code","source":"extractor = FeatureExtractor([SummaryTransformer(), SpectrogramSummaryTransformer(\n    sample_rate= sample_rate, fft_length=200, stride_length=100)])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"468a96e4346ff3a47e6266d31be441b8a9d1769a"},"cell_type":"code","source":"X = extractor.transform(DataPaths.TRAIN_PARQUET_PATH, train_meta_df, n_jobs=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"dc8d6ee353958834989a09d38529df7d834ac1e8"},"cell_type":"code","source":"X.shape","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"7070196513c1f246aaae9a3472c5cb59977c4400"},"cell_type":"markdown","source":"## train model"},{"metadata":{"trusted":true,"_uuid":"a02e8546d3c8455f35db457f73e6440826302096"},"cell_type":"code","source":"from sklearn.metrics import matthews_corrcoef","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"14459d4c689d8f832f5436ccae75ec531d2c8a60"},"cell_type":"code","source":"from lightgbm import LGBMClassifier","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7bd4b2ddb627bfb200f448cd243177b12f16589d"},"cell_type":"code","source":"import optuna","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6a76fa78d04cd50dcc8e8dd8368b9687bbc5e5a4"},"cell_type":"code","source":"y = train_meta_df.target[list(range(train_meta_df.signal_id.values[0], \n                                        train_meta_df.signal_id.values[-1], 3))]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"e0b76738f16f71722e8941248df8966b0b30ac41"},"cell_type":"code","source":"RANDOM_STATE=10","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a77b06f5153a9f652ca275c5bd2c00ccc73a7fbf"},"cell_type":"code","source":"from sklearn.model_selection import cross_validate\nfrom sklearn.metrics import make_scorer","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"1ffcbab92775d27aa40269ffb959599e86888cba"},"cell_type":"code","source":"def objective(trial:optuna.trial.Trial):\n    boosting_type = trial.suggest_categorical(\"boosting_type\", ['gbdt', 'dart'])\n    num_leaves = trial.suggest_int('num_leaves', 30, 80)\n    min_data_in_leaf = trial.suggest_int('min_data_in_leaf', 10, 100)\n#     max_depth = trial.suggest_int('max_depth', )\n    lambda_l1 = trial.suggest_loguniform('lambda_l1', 1e-5, 1e-2)\n    lambda_l2 = trial.suggest_loguniform('lambda_l2', 1e-5, 1e-2)\n#     num_iterations = trial.suggest_int(\"num_iterations\", 100, 500)\n    learning_rate = trial.suggest_loguniform('learning_rate', 1e-4, 1e-1)\n    \n    clf = LGBMClassifier(boosting_type=boosting_type, num_leaves=num_leaves, \n                        learning_rate=learning_rate, reg_alpha=lambda_l1, \n                        min_child_samples=min_data_in_leaf,\n                         reg_lambda=lambda_l2, random_state=RANDOM_STATE)\n#     fit_params = {\"early_stopping_rounds\":20, \n#                  \"eval_metric\": matthews_corrcoef}\n    scores = cross_validate(clf, X, y, verbose=1,  \n                  n_jobs=-1, scoring=make_scorer(matthews_corrcoef), cv=5)\n    return - scores[\"test_score\"].mean()\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cf1d69515bd4d60a6d72d028ab28fecc63aab4ad"},"cell_type":"code","source":"study = optuna.create_study()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"648760d94cff75c5a35626733363cb4930382451"},"cell_type":"code","source":"study.optimize(objective, n_trials=10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"cd1d2d548656be0ae1ef72187ef5de394d524452"},"cell_type":"code","source":"study.best_params","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"70d55d5682330dcc7a435ca35d83a799705ac859"},"cell_type":"code","source":"study.best_value","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3ae3512bb3ac659f7fbdf0d6e997c96566fca5db"},"cell_type":"code","source":"best_params = study.best_params","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3dc147c74606ae0cc08204b2c37682bba0a9c9ef"},"cell_type":"code","source":"best_params[\"random_state\"] = RANDOM_STATE","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"36715af0c0d5a7f3e6ebfb7e8a9d513b4f9aa47c"},"cell_type":"code","source":"clf = LGBMClassifier(**best_params)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"c346848b4064bf8145d04e110c2c72ec5e3c5837"},"cell_type":"code","source":"clf.fit(X, y, eval_metric=matthews_corrcoef, \n       verbose=1)","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"2beeeb3d8c96585d4decd9e95b195adcb4fb8f16"},"cell_type":"markdown","source":"## predict"},{"metadata":{"trusted":true,"_uuid":"3a3686e84d0c33d0502235b8c32f6006ac2ceaa3"},"cell_type":"code","source":"test_meta_df = pd.read_csv(DataPaths.TEST_MATADATA_PATH)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"171adbe9d43e1410ef3002ee352639792cdab76b"},"cell_type":"code","source":"# test_meta_df = test_meta_df.iloc[:15]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"277bee4ec20e11bd4a9411ab8aa3686eef302977"},"cell_type":"code","source":"test_meta_df.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"019da115e2a1eab3d54e75d52331cb3fa313a7dc"},"cell_type":"code","source":"X = extractor.transform(DataPaths.TEST_PARQUET_PATH, test_meta_df, n_jobs=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a69b6ac38258497fe509c92845681ab1a98d2cbc"},"cell_type":"code","source":"predictions = clf.predict(X)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"7b52e3bb9eeb8146b15c7bd1703e6c8cf906d17f"},"cell_type":"code","source":"submit_df = pd.DataFrame()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"a3faec0532f2963b4a4518a6bc46d6d6071bdf68"},"cell_type":"code","source":"submit_df[\"signal_id\"] = test_meta_df.signal_id","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"8f6824253cef7adbcf92ae1c14b1604e20cf70bb"},"cell_type":"code","source":"submit_df[\"target\"] = np.repeat(predictions, 3)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"6ee404366c747370ba4eae7ffa91662d8d1c32aa"},"cell_type":"code","source":"submit_df[:10]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"3216f5da363645a25c1bfe1a4636082625b1c676"},"cell_type":"code","source":"submit_df.to_csv(\"submission.csv\", index=None)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true,"_uuid":"10745f32ef707181eb76cfb97cc61b719b1c7b7c"},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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}