{"cells":[{"metadata":{},"cell_type":"markdown","source":"<center><img src=\"https://i.imgur.com/hBPv3fh.png\" width=\"650\"></center>\n<h1><center>Kaggle LANL Earthquake Prediction Modeling</center></h1>\n\n**Nhiệm vụ**: Dự đoán thời gian sắp xảy ra động đất dựa vào dãy acoustic_data thu được trong mỗi file dữ liệu.\n\n**Model**: Project này sử dụng model CatBoostRegressor. Output của project là một continuous number -> Regression data.\n\n**CatBoost**: Là model được phát triển bởi Yandex dựa trên công thức Gradient Boosting thuộc họ Decision Tree. CatBoost có các ưu điểm:\n* Thể hiện tốt mà it cần chỉnh parameters.\n* Hỗ trợ các biến categorical không phải dạng số --> Không cần dummies.\n* Scale với GPU.\n* Độ chính xác cao, có thể giảm overfitting.\n* Tốc độ dự đoán nhanh.\n\n[Nguồn](https://catboost.ai/)"},{"metadata":{"trusted":true},"cell_type":"code","source":"!pip install catboost","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Model\nfrom catboost import CatBoostRegressor, Pool\n\nfrom sklearn.preprocessing import StandardScaler\nfrom sklearn.metrics import mean_absolute_error","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(os.listdir(\"../input\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train = pd.read_csv('../input/train.csv', dtype={'acoustic_data': np.int16,\n                                                 'time_to_failure': np.float64})\ntrain.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Để ý thấy cột **time_to_failure** chứa các con số giống nhau, tuy nhiên nhiều khả năng do số được làm tròn vì khác biệt nằm ở phần thập phân. Cần để pandas hiển thị phần thập phân nhiều hơn để xác nhận điều này."},{"metadata":{"trusted":true},"cell_type":"code","source":"pd.options.display.precision = 15 # Hiển thị 15 số thập phân\ntrain.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Mỗi file test chứa 150,000 dòng acoustic_data, nhiệm vụ của chúng ta là dự đoán time_to_failure tại dòng cuối cùng của mỗi file test.\n\n<center><b>seg_004cd2</b></center>\n\n|      |acoustic_data|time_to_failure|\n|------|-------------|---------------|\n|  0   |      6      |               |\n|  1   |     16      |               |\n| ...  |     ...     |      ...      |\n|149998|151          |               |\n|149999|77           |    **3.26**   |\n\n<br>\n\n<center><b>submission</b></center>\n\n|          |time_to_failure|\n|----------|---------------|\n|seg_004cd2|    **3.26**   |\n|    ...   |      ...      |\n|seg_123ef7|      ...      |"},{"metadata":{"trusted":true},"cell_type":"code","source":"train_chunk = pd.read_csv('../input/train.csv', chunksize=150_000, iterator=True, dtype={'acoustic_data': np.int16,\n                                                                                          'time_to_failure': np.float64})","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Do feature gốc chỉ có **acoustic_data**, ta cần sử dụng tới kỹ thuật Feature Engineering để tạo thêm các feature khác dựa trên feature gốc, từ đó tăng khả năng predict của model. Nói cách khác, ta có thêm nhiều dữ kiện hơn để thực hiện việc phỏng đoán thời gian sắp xảy ra động đất.\n\n**Ý tưởng:** Tạo ra function `feature_engineering`, function sẽ tạo ra một list gồm mean, std, min, max của cột acoustic_data (new_feat = \\[7.32, 0.16, -77, 109\\]). Sau đó biến list này thành pd.Series để append vào 1 pd.DataFrame, mỗi Series append vào DataFrame sẽ trở thành 1 dòng."},{"metadata":{"trusted":true},"cell_type":"code","source":"def feature_engineering(df):\n    new_feat = []\n    new_feat.append(df.mean())\n    new_feat.append(df.std())\n    new_feat.append(df.min())\n    new_feat.append(df.max())\n    \n    return pd.Series(new_feat)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Feature Engineering\nX_train = pd.DataFrame()\ny_train = pd.Series()\n\nfor df in train_chunk:\n    fe = feature_engineering(df['acoustic_data'])\n    X_train = X_train.append(fe, ignore_index=True)\n    y_train = y_train.append(pd.Series(df['time_to_failure'].values[-1])) # Lấy giá trị cuối cùng của mỗi chunk","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Đặt tên cho các cột\ncolumns = ['mean', 'std', 'min', 'max']\nX_train.columns = columns\n\nX_train.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"y_train.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Các feature được sử dụng là các số liên tiếp và có sự khác biệt lớn về giá trị của chúng. Ví dụ như giá trị của feature **mean** có thể trải từ -10 đến 10, trong khi đó giá trị của feature **max** có thể trải từ 50 đến 200. Do đó, để có thể sử dụng các feature này một cách hiệu quả, chúng ta cần sử dụng kỹ thuật scale để các giá trị của các feature chỉ nằm trong khoảng 0 đến 1 hoặc -1 đến 1 (tùy theo kỹ thuật scale)."},{"metadata":{"trusted":true},"cell_type":"code","source":"scaler = StandardScaler()\nscaler.fit(X_train)\nX_train_scaled = scaler.transform(X_train)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Tiếp theo, chọn model để train bằng feature đã scale. Ở đây sử dụng model CatBoostRegressor."},{"metadata":{"trusted":true},"cell_type":"code","source":"params = {'iterations': 10000,\n          'loss_function': 'MAE'}\n\ntrain_pool = Pool(X_train_scaled, y_train)\n\ncbr = CatBoostRegressor(**params)\ncbr.fit(X_train_scaled, y_train, eval_set=train_pool, silent=True)\n\ny_pred = cbr.predict(X_train_scaled)\nprint('Best score: ' + str((cbr.best_score_)))\nprint('MAE: {:.3f}'.format(mean_absolute_error(y_train.values, y_pred)))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# SUBMIT"},{"metadata":{"trusted":true},"cell_type":"code","source":"submission = pd.read_csv('../input/sample_submission.csv', index_col='seg_id') # Đọc file sample_submission để lấy form\n\nX_test = pd.DataFrame(columns=X_train.columns, dtype=np.float64, index=submission.index) # Tạo DF mới cho X_test để thực hiện Feature Engineering tương tự với train data","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_test.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Feature Engineering cho test data\nfor seg_id in X_test.index:\n    seg = pd.read_csv('../input/test/' + seg_id + '.csv')\n    \n    x = seg['acoustic_data'].values\n    \n    X_test.loc[seg_id, 'mean'] = x.mean()\n    X_test.loc[seg_id, 'std'] = x.std()\n    X_test.loc[seg_id, 'max'] = x.max()\n    X_test.loc[seg_id, 'min'] = x.min()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_test.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_test_scaled = scaler.transform(X_test) # Scale feature ở test data\n\nsubmission['time_to_failure'] = cbr.predict(X_test_scaled)\nsubmission.to_csv('submission.csv')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission.head()","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}