{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom scipy import stats\nfrom scipy import signal\nimport pywt\nimport numba\n\nfrom tqdm.auto import tqdm\nfrom joblib import Parallel, delayed\nimport gc","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"# Data yielding"},{"metadata":{"trusted":true},"cell_type":"code","source":"@numba.jit(parallel=True)\ndef wavelet_coeffs(x, wavelet='db9', level=9):\n    coeffs = pywt.wavedec(x, wavelet=wavelet, level=level)\n    return coeffs\n\nclass FeatureGenerator(object):\n    def __init__(self, dtype, n_jobs=1, chunk_size=None, fs=4e6, wavelet='db9', level=9):\n        self.chunk_size = chunk_size\n        self.dtype = dtype\n        self.filename = None\n        self.n_jobs = n_jobs\n        self.fs = fs\n        self.wavelet = wavelet\n        self.level = level\n        self.test_files = []\n        if self.dtype == 'train':\n            self.filename = '../input/train.csv'\n            self.total_data = int(629145481 / self.chunk_size)\n        else:\n            submission = pd.read_csv('../input/sample_submission.csv')\n            for seg_id in submission.seg_id.values:\n                self.test_files.append((seg_id, '../input/test/' + seg_id + '.csv'))\n            self.total_data = int(len(submission))\n\n    def read_chunks(self):\n        if self.dtype == 'train':\n            iter_df = pd.read_csv(self.filename, iterator=True, chunksize=self.chunk_size,\n                                  dtype={'acoustic_data': np.float64, 'time_to_failure': np.float64})\n            for counter, df in enumerate(iter_df):\n                if df.time_to_failure.values[0] > df.time_to_failure.values[-1]:\n                    x = df.acoustic_data.values\n                    y = df.time_to_failure.values[-1]\n                    seg_id = 'train_' + str(counter)\n                    yield seg_id, x, y\n        else:\n            for seg_id, f in self.test_files:\n                df = pd.read_csv(f, dtype={'acoustic_data': np.float64})\n                x = df.acoustic_data.values\n                yield seg_id, x, -999\n                \n    @numba.jit(parallel=True)\n    def features(self, x, y, seg_id, fs=4e6):\n        feature_dict = dict()\n        feature_dict['target'] = y\n        feature_dict['seg_id'] = seg_id\n        coeffs = wavelet_coeffs(x, wavelet=self.wavelet, level=self.level)\n        coeffs_diff = wavelet_coeffs(np.diff(x), wavelet=self.wavelet, level=self.level)\n        percentiles_ranges = [99, 98, 97, 96, 95, 94, 93, 92, 91, 90, 80, 75, \n                              50, 25, 20, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]\n        \n        signals_list = {\n            'regular': coeffs, \n            'diff': coeffs_diff,\n        }\n        for signal_name, signal_i in signals_list.items():\n            for i, x_i in enumerate(signal_i):\n                if i == 0:\n                    name = '{}_cA'.format(signal_name)\n                else:\n                    name = '{}_cD{}'.format(signal_name, self.level - (i - 1))\n                # statistics and centered moments\n                feature_dict['rms_{}'.format(name)] = np.sqrt(np.mean(np.sum(x_i ** 2)))\n                feature_dict['mean_{}'.format(name)] = np.mean(x_i)\n                feature_dict['median_{}'.format(name)] = np.median(x_i)\n                feature_dict['var{}'.format(name)] = np.var(x_i)\n                feature_dict['skewnes_{}'.format(name)] = stats.skew(x_i)\n                feature_dict['kurtosis_{}'.format(name)] = stats.kurtosis(x_i)\n                # non-centered moments\n                for m in range(2, 5):\n                    feature_dict['moment_{}_{}'.format(m, name)] = np.mean(np.sum(x_i ** m))\n                # percentile ranges\n                for pct in percentiles_ranges:\n                    feature_dict['percentile{}_{}'.format(str(pct), name)] = np.percentile(x_i, pct)\n                # sum of energy of coefficients within bands\n                chunks = 20\n                step = len(x_i) // chunks\n                for chunk_no, band in enumerate(range(0, len(x_i), step)):\n                    feature_dict['energy_chunk{}_{}'.format(chunk_no, name)] = np.sum(x_i[band:band+step] ** 2)\n                    feature_dict['energy_chunk_rms{}_{}'.format(chunk_no, name)] = np.sqrt(\n                        np.mean(\n                            np.sum(\n                                feature_dict['energy_chunk{}_{}'.format(chunk_no, name)] ** 2)\n                        )\n                    )\n                \n        return feature_dict\n\n    def generate(self):\n        feature_list = []\n        res = Parallel(n_jobs=self.n_jobs)(delayed(self.features)(x, y, s, fs=self.fs)\n                                            for s, x, y in tqdm(self.read_chunks(), total=self.total_data))\n        for r in res:\n            feature_list.append(r)\n        return pd.DataFrame(feature_list)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Parse data and preprocess"},{"metadata":{"trusted":true},"cell_type":"code","source":"wavelet = 'db4'\nlevel = 9\ntraining_fg = FeatureGenerator(dtype='train', n_jobs=1, chunk_size=150000, wavelet=wavelet, level=level)\ntraining_data = training_fg.generate()\n\ntest_fg = FeatureGenerator(dtype='test', n_jobs=1, chunk_size=None, wavelet=wavelet, level=level)\ntest_data = test_fg.generate()\n\ntraining_data.to_csv(\"train_features.csv\", index=False)\ntest_data.to_csv(\"test_features.csv\", index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"training_data.sample(5)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"training_data.dropna(axis=1, inplace=True)\ntest_data.dropna(axis=1, inplace=True)\nprint(training_data.shape, test_data.shape)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Modeling"},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn.model_selection import KFold, TimeSeriesSplit\nfrom sklearn.metrics import mean_absolute_error, make_scorer\nfrom sklearn.ensemble import RandomForestRegressor\nfrom xgboost import XGBRegressor","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"features_cols = [c for c in training_data.columns if (('target' not in c) and ('seg_id' not in c))]\n\nX = training_data[features_cols].values\ny = training_data['target'].values\nX_test = test_data[features_cols].values","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from skopt import BayesSearchCV\nfrom skopt.space import Real, Categorical, Integer","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"xgb = XGBRegressor(random_state=11)\nsearch_space = {\n    'n_estimators': Integer(100, 1000),\n    'learning_rate': Real(1e-6, 3e-1, 'log-uniform'),\n    'min_child_weight': Integer(4, 10),\n    'reg_alpha': Real(1e-6, 0.5, 'log-uniform'),\n    'reg_lambda': Real(1e-6, 1.0, 'log-uniform'),\n    'colsample_bytree': Real(0.2, 0.8, 'log-uniform'),\n}","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#folds = KFold(n_splits=3, random_state=11)\n#cv = folds.split(X, y)\n\n# weird error using KFold or TimeSeriesSplit\n\nopt = BayesSearchCV(\n    xgb,\n    search_space,\n    scoring=make_scorer(mean_absolute_error, greater_is_better=False),\n    n_iter=32,\n    cv=5,\n    n_jobs=-1,\n    random_state=11,\n    refit=True,\n)\n\nopt.fit(X, y)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('val. score: {:.3f}'.format(opt.best_score_))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(opt.best_params_)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Submitting"},{"metadata":{"trusted":true},"cell_type":"code","source":"y_pred = opt.predict(X_test)\n\n# submission\nsub = pd.read_csv('../input/sample_submission.csv')\nsub['time_to_failure'] = y_pred\nsub.to_csv('submission.csv', index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"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.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}