{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"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.","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm import tqdm_notebook as tqdm","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Định nghĩa trước\n\n- total - Tổng số dòng có trong file dữ liệu chưa chuẩn hóa.\n- chunksize - Số lượng dữ liệu được sử dụng để tính mỗi dòng trong file đã chuẩn hóa.\n- segments - Số lượng lượng dữ liệu trong file đã chuẩn hóa.","metadata":{}},{"cell_type":"code","source":"%%time\n# Tổng số dòng dữ liệu\ntotal = 629145481 \nchunksize = 150_000\n\nc = 1\n\nsegments = total // chunksize\n# Debug\n# segments = 10","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Hiển thị đến độ chính xác 15 chữ số sau dấu phẩy.\npd.options.display.precision = 15","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training","metadata":{}},{"cell_type":"markdown","source":"#### Kiểm tra phiên bản của sklearn\nCode bên dưới để kiểm tra sklearn có sử dụng được các thuật toán từ bản 0.23 trở lên hay không. Một số thuật toán không xuất hiện trong các version từ 0.22 trở xuống, như VotingRegressor.","metadata":{}},{"cell_type":"code","source":"import sklearn\n\nprint('The scikit-learn version is {}.'.format(sklearn.__version__))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Import các thư viện cần thiết cho quá trình nạp dữ liệu","metadata":{}},{"cell_type":"code","source":"%%time\n# Thuật toán KMean từ sklearn để phân cụm dữ liệu.\nfrom sklearn.cluster import KMeans\n\n# thư viện các thao tác với mảng số.\nimport numpy as np\n\n# thư viện trực quan hóa.\nimport matplotlib.pyplot as plt \nimport seaborn as sns\n\n# thư viện quản lý các Warning (thông báo cảnh cáo).\nimport warnings\n\n# Bỏ qua các warning.\nwarnings.filterwarnings('ignore')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Nạp các đầu vào cho huấn luyện\nSử dụng đầu vào là các file đã được xử lý ở [notebook](https://www.kaggle.com/ngodang/int3405e-20-lanl-linear-boosting), tiến hành nạp các đầu vào bằng pandas.","metadata":{}},{"cell_type":"code","source":"X = pd.read_csv('../input/lanl-u-vo-chun-ha/X_train.csv')\ny = pd.read_csv('../input/lanl-u-vo-chun-ha/y_train.csv')\nlen(X.columns)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Trực quan một số giá trị \n\nTrực quan các giá trị của time_to_failure theo thời gian.","metadata":{}},{"cell_type":"code","source":"plt.plot(range(len(y)), y)\nplt.title(\"Giá trị của time_to_failure theo thời gian\")\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.histplot(data=y, x=\"time_to_failure\")\nplt.title(\"Phân bố nhãn y trong tập kiểm thử\")\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Biểu đồ các giá trị của TTF theo thời gian. Ta thấy rằng do số mẫu rất nhỏ so với tổng số mẫu, nên tính liên tục của y không bị ảnh hưởng quá nhiều (dữ liệu vẫn có cách hình răng cưa).\n\nBiểu đồ phân bố nhãn y trong tập kiểm thử, ta thấy có sự mất cân bằng lớn khi những điểm dữ liệu có nhãn càng lớn thì càng ít dữ liệu.","metadata":{}},{"cell_type":"markdown","source":"#### Nạp các đầu vào cho bộ test.","metadata":{}},{"cell_type":"code","source":"# Nạp dữ liệu từ file bản nộp mẫu, để thuận tiện cho việc xuất ra file kết quả.\nsubmission = pd.read_csv('../input/LANL-Earthquake-Prediction/sample_submission.csv', index_col='seg_id')\n\nX_test = pd.read_csv('../input/lanl-u-vo-chun-ha/X_test.csv')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Chuẩn hóa dữ liệu\n\nSử dụng Standard Scaler, dữ liệu sẽ được chuẩn hóa về dạng có mean bằng 0 và std bằng 1.","metadata":{}},{"cell_type":"code","source":"from sklearn.preprocessing import StandardScaler\n\nscaler = StandardScaler()\nX_scaled = scaler.fit_transform(X)\n\nX_test_scaled = scaler.transform(X_test)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Định nghĩa hàm mất mát.\n\nTrong đề bài yêu cầu sử dụng hàm đánh giá là MAE hay Mean Absolute Error, được tính bằng trung bình trị tuyệt đối sự khác nhau giữa dữ liệu nhãn dự đoán và dữ liệu nhãn được cho.\n\nDữ liệu được tính ở đây là time_to_failure.\n\nNạp hàm tính MAE từ sklearn:","metadata":{}},{"cell_type":"code","source":"from sklearn.metrics import mean_absolute_error as MAE","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training\n\n## Chia dữ liệu thành tập huấn luyện và thẩm định.\nChia bộ dữ liệu để huấn luyện thành 2 tập: Huấn luyện (training) và thẩm định (validation) sử dụng hàm train_test_split từ sklearn.model_selection. \n\nTỉ lệ dữ liệu dùng để huấn luyện sẽ là 50%. Do số file test là 2624 file, số dòng trong file training là 4194. Việc chia một nửa sẽ làm số lượng file cho validation gần với số lượng file trong test. \n\nDữ liệu được sử dụng là 2 loại:\n- \\<X>_no_shuffle_scaled: Là dữ liệu có phần valid là liên tục, sử dụng để trực quan khả năng dự đoán của mô hình. Được gọi là tập không tráo.\n- Loại còn lại được tráo và chia ngay từ đầu, sử dụng để tìm ra mô hình tốt nhất. Được gọi là tập có tráo.","metadata":{}},{"cell_type":"code","source":"train_size = .5","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import GridSearchCV, KFold\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.utils import shuffle\n\nX_train_no_shuffle_scaled, X_valid_no_shuffle_scaled, y_train_no_shuffle, y_valid_no_shuffle = train_test_split(X_scaled, y.values, train_size=train_size, shuffle=False)\nX_train_no_shuffle_scaled, y_train_no_shuffle = shuffle(X_train_no_shuffle_scaled, y_train_no_shuffle, random_state=42)\n\nX_train_scaled, X_valid_scaled, y_train, y_valid = train_test_split(X_scaled, y.values, train_size=train_size, shuffle=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Định nghĩa một hàm trực quan phục vụ thẩm định mô hình.","metadata":{}},{"cell_type":"code","source":"def plot_valid(y_valid, y_predict):\n    plt.subplots(figsize=(13, 3))\n    plt.plot(range(len(y_valid)), y_valid, label=\"valid\")\n    plt.plot(range(len(y_predict)), y_predict, label=\"predict\")\n    plt.legend()\n    plt.show()\n    \nplot_valid(y_valid_no_shuffle, y_valid_no_shuffle)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Import các mô hình sẽ sử dụng.","metadata":{}},{"cell_type":"code","source":"## Nhóm các mô hình tuyến tính.\nfrom sklearn.linear_model import LinearRegression\nfrom sklearn.linear_model import Ridge\nfrom sklearn.linear_model import Lasso\nfrom sklearn.svm import SVR\nfrom sklearn.svm import NuSVR\nfrom sklearn.neural_network import MLPRegressor\n\n## Nhóm mô hình cây.\nfrom sklearn.tree import DecisionTreeRegressor\n\n## Nhóm mô hình Bagging.\nfrom sklearn.ensemble import RandomForestRegressor\n\n## Nhóm mô hình phân cụm.\nfrom sklearn.neighbors import KNeighborsRegressor\n\n## Nhóm mô hình Boosting.\nfrom sklearn.ensemble import GradientBoostingRegressor\nfrom sklearn.ensemble import AdaBoostRegressor\nfrom xgboost import XGBRegressor\n\n## Nhóm mô hinh Ensemble khác.\nfrom sklearn.ensemble import VotingRegressor\nfrom sklearn.ensemble import StackingRegressor\n\n## Nhóm các thuật toán boosting hiệu quả với các cuộc thi của kaggle khác.\nimport xgboost as xg\nimport catboost as cb\nimport lightgbm as lgb","metadata":{"scrolled":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Phương pháp Cross Validation\n\nChia tập dữ liệu thành nhiều phần bằng nhau. Ứng với khi xét mỗi phần, thực hiện các bước:\n1. Tạo và huấn luyện mô hình trên các phần dữ liệu ngoài phần đang xét.\n2. Tính các số liệu về khả năng dự đoán của mô hình trên phần đang xét.\n3. Tính trung bình các số liệu.\n\nMô hình nào có điểm trung bình các số liệu cao hơn sẽ được chọn.\n\n## Cross Validation trong lựa chọn tham số cho mô hình\n\nHàm sử dụng: GridSearchCV từ sklearn.\n\nCác tham số của lớp:\n- estimator: Là mô hình dự đoán đang cần tìm siêu tham số phù hợp\n- param_grid: Là một đối tượng từ điển, chứa thông tin về tên siêu tham số và các giá trị có thể được chọn.\n- refit: Thực hiện huấn luyện mô hình tốt nhất trên toàn bộ bộ dữ liệu.\n- verbose: Quyết định mức độ của việc in ra các log.\n- cv: Số phần chia ra cho Cross Validation.\n- scoring: metric dùng để đánh giá độ tốt của mô hình.\n- n_jobs: Số quy trình có thể chạy song song.\n\nChức năng: Mỗi tổ hợp các giá trị trong các trường của param_grid sẽ đánh giá độ tốt dùng Cross Validation. Lớp trả về tổ hợp tham số tốt nhất.","metadata":{}},{"cell_type":"markdown","source":"## Xây dựng chiến lược đánh giá Out Of Fold (OOF)\n\nOut of Folds là chiến lược sẽ chia bộ dữ liệu ra thành n_folds phần bằng nhau. Ứng với mỗi phần, thuật toán sẽ thực hiện các bước sau:\n1. Đặt phần đang xét làm tập valid hiện tại. \n2. Huấn luyện mô hình trên các tập còn lại.\n3. Sử dụng mô hình để dự đoán tập valid. Giá trị dự đoán sẽ được ghi vào một mảng $valid$, tại vị trí tương ứng được lấy mẫu làm tập valid. \n5. Nếu vẫn còn tập valid chưa xét, tiếp tục xét và trở về bước 1.\n6. Tính hàm đánh giá trên mảng $valid$ để đánh giá so với giá trị nhãn đầu vào.\n\nCó 2 phiên bản cho hàm OOF:\n- oof là phiên bản không sử dụng giá trị tốt nhất để đánh giá, hoàn toàn huấn luyện dựa vào dữ liệu training.\n- oof_with_evalset là phiên bản sử dụng tập valid để tìm giá đánh giá mô hình.\n\n### oof: \nHàm dự đoán không sử dụng tập eval set để đánh giá và dừng sớm trong quá trình huấn luyện","metadata":{}},{"cell_type":"code","source":"%%time\nfrom sklearn.model_selection import KFold\n\ndef oof(params, model_class, X, y, n_folds):\n    \n    # Lớp KFold để chia dữ liệu thành các Fold.\n    kfold = KFold(n_splits = n_folds, shuffle=True, random_state=42)\n    # Mảng Valid để lưu lại các giá trị dự đoán.\n    oof_pred = np.zeros((len(y), ))\n    \n    # Duyệt qua các tập được chia bởi KFold.\n    for i, (train_index, valid_index) in enumerate(kfold.split(X)):\n        X_train, X_valid = X[train_index], X[valid_index] \n        y_train, y_valid = y[train_index], y[valid_index]\n        \n        # Xây dựng mô hình.\n        model = model_class(**params)\n        \n        # Hàm lọc bỏ các Warning bắt buộc từ sklearn. \n        # Các hàm Warning của sklearn có khả năng miễn nhiễm với lệnh ignore được khai báo bên trên.\n        with warnings.catch_warnings():\n            warnings.filterwarnings(\"ignore\")\n            \n            # Huấn luyện mô hình.\n            model.fit(X_train, y_train.ravel())\n        \n        # Dự đoán cho cho tập X_valid.\n        predict_valid = model.predict(X_valid).ravel()\n        \n        # Gán giá trị cho vị trí lấy mẫu valid tương ứng trong mảng Valid.\n        oof_pred[valid_index] = predict_valid\n        \n    print(\"Avg MAE: \", MAE(oof_pred, y))","metadata":{"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### oof_with_evalset: \nHàm dự đoán sử dụng tập eval set để đánh giá và dừng sớm trong quá trình huấn luyện. Sử dụng đối với các mô hình cho phép early stopping (Dừng sớm nếu kết quả không cải thiện).","metadata":{}},{"cell_type":"code","source":"%%time\nfrom sklearn.model_selection import KFold\n\ndef oof_with_evalset(params, model_class, X, y, n_folds):\n    \n    # Lớp KFold để chia dữ liệu thành các Fold.\n    kfold = KFold(n_splits = n_folds, shuffle=True, random_state=42)\n    # Mảng Valid để lưu lại các giá trị dự đoán.\n    oof_pred = np.zeros((len(y), ))\n    \n    # Duyệt qua các tập được chia bởi KFold.\n    for i, (train_index, valid_index) in enumerate(kfold.split(X)):\n        X_train, X_valid = X[train_index], X[valid_index] \n        y_train, y_valid = y[train_index], y[valid_index]\n        \n        # Xây dựng mô hình.\n        model = model_class(**params)\n        \n        # Hàm lọc bỏ các Warning bắt buộc từ sklearn. \n        # Các hàm Warning của sklearn có khả năng miễn nhiễm với lệnh ignore được khai báo bên trên.\n        with warnings.catch_warnings():\n            warnings.filterwarnings(\"ignore\")\n            \n            # Huấn luyện mô hình.\n            model.fit(X_train, y_train.ravel(), eval_set=[(X_train, y_train), (X_valid, y_valid)], verbose=False)\n        \n        # Dự đoán cho cho tập X_valid.\n        predict_valid = model.predict(X_valid).ravel()\n        \n        # Gán giá trị cho vị trí lấy mẫu valid tương ứng trong mảng Valid.\n        oof_pred[valid_index] = predict_valid\n        \n    print(\"Avg MAE: \", MAE(oof_pred, y))","metadata":{"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Kiểm tra sử dụng 2 mã bên dưới:","metadata":{}},{"cell_type":"code","source":"%%time\nparams = {}\n\noof(\n    params, LinearRegression, \n    X_train_no_shuffle_scaled, \n    y_train_no_shuffle, \n    5\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nparams = {'colsample_bytree': 0.4, 'learning_rate': 0.01, 'max_depth': 12, 'n_estimators': 100, 'num_leaves': 127, 'objective': 'regression_l1', 'reg_lambda': 3, 'subsample': 0.4}\n\noof_with_evalset(\n    params, lgb.LGBMRegressor,\n    X_train_no_shuffle_scaled, \n    y_train_no_shuffle, \n    5\n)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Hàm trực quan đánh giá\n\nChạy dữ liệu trên tập không tráo và trực quan kết quả","metadata":{}},{"cell_type":"code","source":"def visualize(params, model_class):\n    model = model_class(**params)\n    model.fit(X_train_no_shuffle_scaled, y_train_no_shuffle)\n    \n    pred = model.predict(X_valid_no_shuffle_scaled)\n    plot_valid(y_valid_no_shuffle, pred)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Chiến lược tìm kiếm mô hình tốt nhất\n\nChiến lượng sử dụng là sử dụng Grid Search để tìm ra tổ hợp các tham số hợp lệ đạt điểm Cross Validation cao nhất.","metadata":{}},{"cell_type":"code","source":"from warnings import simplefilter\n\nsimplefilter(action='ignore', category=FutureWarning)\n\ndef training(param_grid, model_class):\n    grid = GridSearchCV(model_class(), param_grid, verbose=1, cv=3, scoring='neg_mean_absolute_error', n_jobs=4)\n    \n    with warnings.catch_warnings():\n        warnings.filterwarnings(\"ignore\")\n        \n        grid.fit(X_scaled, y.values.ravel()) \n\n    print(grid.best_estimator_) \n    print(-grid.best_score_)\n    return grid","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Chiến lược đánh giá và xuất ra file csv","metadata":{}},{"cell_type":"code","source":"from warnings import simplefilter\n\nsimplefilter(action='ignore', category=FutureWarning)\n\ndef eval_and_export(params, model_class, model_name):\n\n    model = model_class(**params)\n    \n    with warnings.catch_warnings():\n        warnings.filterwarnings(\"ignore\")\n        model.fit(X_scaled, y.values.ravel())\n\n    pred_test = model.predict(X_test_scaled)\n    \n    # Do số time_to_failure luôn dương, nên báo cáo lấy max với 0\n    submission['time_to_failure'] = np.maximum(pred_test, 0)\n    submission.to_csv('submission_{}.csv'.format(model_name))\n    \n    print(\"Export to submission_{}.csv complete!\".format(model_name))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Linear Regressor","metadata":{}},{"cell_type":"markdown","source":"### Mô tả\n\nHồi quy tuyến tính là phương pháp mô hình hóa quan hệ giữa các thuộc tính bằng cách tìm ra một phương trình đường thẳng trên tập dữ liêu, với tham số là: $W, b$, trong đó, $W$ là một vector cùng số chiều với dữ liệu, và $b$ là bias, là một giá trị vô hướng.\n\nPhườn trình đường thẳng mà hàm hồi quy tuyến tính tìm kiếm có dạng: $Y = W^T X + b$ trong đó, $X$ là các đặc trưng đầu vào, $Y$ là giá trị dữ đoán. Nhiệm vụ của Hồi quy tuyến tính là tìm xác định $W$ và $b$ sao cho k\n\nHàm sẽ tập trung tối thiểu hóa lỗi $L$, được định nghĩa là mức độ sai số dự đoán của mô hình. Phương pháp xuống đồi bằng đạo hàm và lan truyền ngược có thể được sử dụng để tối thiểu hóa lỗi $L$.\n\nHàm hồi quy tuyến tính của thư viện sklearn không có tham số liên quan đến huấn luyện.","metadata":{}},{"cell_type":"code","source":"%%time\nfrom sklearn.linear_model import LinearRegression\n\nparams = {}","metadata":{"execution":{"iopub.status.busy":"2022-01-07T16:36:28.860213Z","iopub.execute_input":"2022-01-07T16:36:28.861187Z","iopub.status.idle":"2022-01-07T16:36:28.867138Z","shell.execute_reply.started":"2022-01-07T16:36:28.861107Z","shell.execute_reply":"2022-01-07T16:36:28.866559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time \n\noof(params, LinearRegression, X_scaled, y.values, 3)\nvisualize(params, LinearRegression)\neval_and_export(params, LinearRegression, \"LinearRegression\")","metadata":{"execution":{"iopub.status.busy":"2022-01-07T16:36:30.023733Z","iopub.execute_input":"2022-01-07T16:36:30.024161Z","iopub.status.idle":"2022-01-07T16:36:30.402796Z","shell.execute_reply.started":"2022-01-07T16:36:30.024106Z","shell.execute_reply":"2022-01-07T16:36:30.401771Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Ridge Regressor - L2 Norm\n","metadata":{}},{"cell_type":"markdown","source":"### Mô tả:\n\nRidge.\n\nThuật toán được định nghĩa và huấn luyện giống với Hồi quy tuyến tính. Điểm khác nhau duy nhất là trong hàm $L$ của Ridge cộng thêm thành phần $\\alpha ||W||^2_2$ (Chuẩn L2). Thành phần này còn gọi là Regularization.\n\nViệc thêm regularization có thể giúp giảm các giá trị của một số hệ số, thậm chí làm biến mất (đưa về $0$), từ đó, chọn các đặc trưng một cách tự động, trong vài trường hợp có thể tránh được overfitting.\n\nTrong lớp Ridge của sklearn, các tham số là:\n- alpha: Quyết định ảnh hưởng của Regularization là nhiều hay ít.\n\nViệc sử dụng chuẩn L2 là sẽ tốt hơn nếu các outlier là quan trọng, vì sử dụng L2 sẽ tăng tỉ trọng của các outlier.","metadata":{}},{"cell_type":"code","source":"%%time\nfrom sklearn.linear_model import Ridge\n\nparameters = {'alpha': [0.01, 0.1, 0.3, 0.6, 1, 2]}\n\ngrid = training(parameters, Ridge)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:29:54.732829Z","iopub.execute_input":"2022-01-07T15:29:54.733294Z","iopub.status.idle":"2022-01-07T15:29:54.914812Z","shell.execute_reply.started":"2022-01-07T15:29:54.733254Z","shell.execute_reply":"2022-01-07T15:29:54.914049Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Siêu tham số dự đoán được là giống nhau.","metadata":{}},{"cell_type":"code","source":"%%time\nfrom sklearn.linear_model import Ridge\n\nparams = grid.best_params_\noof(params, Ridge, X_scaled, y.values, 3)\nvisualize(params, Ridge)\neval_and_export(params, Ridge, \"Ridge\")","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:29:54.915974Z","iopub.execute_input":"2022-01-07T15:29:54.916408Z","iopub.status.idle":"2022-01-07T15:29:55.170496Z","shell.execute_reply.started":"2022-01-07T15:29:54.916367Z","shell.execute_reply":"2022-01-07T15:29:55.169612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Lasso Regressor - L1 Norm\n\n### Mô tả:\n\nLasso là viết tắt của Least Absolute Shrinkage and Selection Operator. \n\nThuật toán được định nghĩa và huấn luyện giống với Hồi quy tuyến tính. Điểm khác nhau duy nhất là trong hàm $L$ của Lasso cộng thêm thành phần $\\alpha ||W||$ (Chuẩn L1). Thành phần này còn gọi là Regularization.\n\nViệc thêm regularization có thể giúp giảm các giá trị của một số hệ số, thậm chí làm biến mất (đưa về $0$), từ đó, chọn các đặc trưng một cách tự động, trong vài trường hợp có thể tránh được overfitting.\n\nTrong lớp Lasso của sklearn, các tham số là:\n- alpha: Quyết định ảnh hưởng của Regularization là nhiều hay ít.\n\nViệc sử dụng chuẩn L1 là sẽ tốt hơn nếu muốn khử các outlier. Do L1 sẽ làm giảm giá trị hệ số tương ứng với đặc trưng outlier đến chính xác $0$.","metadata":{}},{"cell_type":"code","source":"%%time\nfrom sklearn.linear_model import Lasso\n\nparameters = {'alpha': [0.01, 0.1, 0.3, 0.6, 1, 2]}\n\ngrid = training(parameters, Lasso)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:29:55.179164Z","iopub.execute_input":"2022-01-07T15:29:55.17964Z","iopub.status.idle":"2022-01-07T15:29:57.812139Z","shell.execute_reply.started":"2022-01-07T15:29:55.179602Z","shell.execute_reply":"2022-01-07T15:29:57.809311Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nfrom sklearn.linear_model import Lasso\n\nparams = grid.best_params_\noof(params, Lasso, X_scaled, y.values, 3)\nvisualize(params, Lasso)\neval_and_export(params, Lasso, \"Lasso\")","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:29:57.81357Z","iopub.execute_input":"2022-01-07T15:29:57.813948Z","iopub.status.idle":"2022-01-07T15:29:58.444579Z","shell.execute_reply.started":"2022-01-07T15:29:57.813907Z","shell.execute_reply":"2022-01-07T15:29:58.443573Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Elastic Net\n\nLà sự kết hợp của Lasso và Ridge. Công thức của Elastic net tương tự như công thức của Hồi quy tuyến tính, nhưng được cộng thêm thành phần $\\alpha * l1\\_ratio * ||W|| + 0.5 * \\alpha * (1 - l1\\_ratio) * ||W||^2_2$.\n\nTrong lớp ElasticNet của sklearn, các tham số là:\n- alpha: Quyết định ảnh hưởng của Regularization là nhiều hay ít.\n- l1_ratio: Quyết định tỉ lệ bao nhiêu phần của alpha sẽ được dùng làm trọng số cho chuẩn L1, phần còn lại được dùng cho chuẩn L2.\n\nViệc sử dụng chuẩn L1 là sẽ tốt hơn nếu muốn khử các outlier. Do L1 sẽ làm giảm giá trị hệ số đến chính xác $0$.","metadata":{}},{"cell_type":"code","source":"%%time\nfrom sklearn.linear_model import ElasticNet\n\nparameters = {\n    'alpha': [0.01, 0.1, 0.3, 0.6, 1, 2],\n    'l1_ratio': [0.3, 0.5, 0.7]\n}\n\ngrid = training(parameters, ElasticNet)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:29:58.446029Z","iopub.execute_input":"2022-01-07T15:29:58.446346Z","iopub.status.idle":"2022-01-07T15:30:07.42962Z","shell.execute_reply.started":"2022-01-07T15:29:58.446306Z","shell.execute_reply":"2022-01-07T15:30:07.428695Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n\nparams = grid.best_params_\noof(params, ElasticNet, X_scaled, y.values, 3)\nvisualize(params, ElasticNet)\neval_and_export(params, ElasticNet, \"ElasticNet\")","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:30:07.435001Z","iopub.execute_input":"2022-01-07T15:30:07.437723Z","iopub.status.idle":"2022-01-07T15:30:08.116636Z","shell.execute_reply.started":"2022-01-07T15:30:07.437665Z","shell.execute_reply":"2022-01-07T15:30:08.115724Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## SVM\n\nSVM (Support vector machine) gồm 2 loại:\n#### SVM lề cứng\nlà thuật toán hướng đến tìm ra một siêu phẳng sao cho mọi điểm dữ liệu đều được phân loại đúng, và khoảng cách từ điểm dữ liệu được phân loại đúng gần nhất với siêu phẳng phải là lớn nhất, khoảng cách này gọi là lề, được tính bởi công thức: \n\n$$\\delta = \\min_{i=1}^n \\frac{|\\mathbf w^T\\mathbf x_i+b|}{\\|\\mathbf w\\|}$$\n\nTuy nhiên thuật toán yêu cầu là dữ liệu phải khả tách tuyến tính, tức là phải tồn tại một siêu phẳng phân cách dữ liệu. Hàm mục tiêu được tính bằng công thức:\n\n$$\\begin{align*}\\max_{\\mathbf w, b,\\delta}&~~\\delta\\\\\n\\textrm{ràng buộc}&~~ y_i(\\mathbf w^T\\mathbf x_i+b)\\geq \\delta\\|\\mathbf w\\|>0,\\forall i\\end{align*}$$\n\n#### SVM lề mềm: \nCó thể chạy trong trường hợp dữ liệu không khả tách tuyến tính bằng cách sử dụng các slack variable ($\\xi_i$) biểu thị cho lượng vi phạm lề của mỗi điểm. Cụ thể, hàm mục tiêu sẽ được tính bởi công thức:\n\n$$\\begin{align*}\n\\min_{\\mathbf w, b,\\xi}&~~\\frac 1 2 \\|\\mathbf w\\|^2+C\\sum_{i=1}^n \\xi_i\\\\\n\\textrm{ràng buộc}&~~ y_i(\\mathbf w^T\\mathbf x_i+b)\\geq 1-\\xi_i,\\forall i\\\\\n&~~ \\xi_i \\geq 0,\\forall i\n\\end{align*}$$\n\nSlack variable được tính bằng công thức: \n\n$$\\xi_i = \\max(0, 1-y_i(\\mathbf w^T\\mathbf x_i+b))$$\n\nLấy $1-y_i(\\mathbf w^T\\mathbf x_i+b)$ do đây là khoảng cách tới lề ở phía đúng của dữ liệu. Nếu $y_i(\\mathbf w^T\\mathbf x_i+b)$ trong khoảng $(0, 1]$ thì chứng tỏ dữ liệu phân đúng nhưng vi phạm lề. Nếu $y_i(\\mathbf w^T\\mathbf x_i+b)$ trong khoảng $(-\\inf, 0]$ thì chứng tỏ dữ liệu loại sai. Cả 2 trường hợp đều sẽ làm biến slack lớn hơn 0.\n\nViệc cho biến slack vào hàm mục tiêu sẽ giúp kiểm soát mức độ vi phạm của các điểm dữ liệu, song song với tối đa hóa lề.\n\n### SVR\n\nSupport vector regression: Tương tự như SVM, nhưng lần này thuật toán sẽ tìm siêu phẳng và lề sao cho các điểm dữ liệu nằm giữa 2 lề thỏa mãn ràng buộc:\n$$\\forall n: |y_n-(b+W^T x_n')| \\le \\epsilon$$\n\nCác tham số chính:\n- C: Trọng số cho biến slack\n- kernel: Phương pháp ánh xạ đầu vào để có chiều không gian có thể phân lớp tốt hơn.\n- epsilon: Khoảng cách tối thiểu mà sẽ không có điểm dữ liệu nào bị đánh trọng số nếu ở trong khoảng đó.","metadata":{}},{"cell_type":"code","source":"%%time\nfrom sklearn.svm import SVR\nfrom warnings import simplefilter\n\nsimplefilter(action='ignore', category=FutureWarning)\n\nparameters = {\n    'kernel': ['linear', 'poly', 'rbf'],\n    'degree': [0],\n    'gamma': ['scale', 'auto'],\n    'C': [0.3, 1],\n    'epsilon': [0.05, 0.1, 1]\n}\n\ngrid = training(parameters, SVR)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:30:08.121693Z","iopub.execute_input":"2022-01-07T15:30:08.124244Z","iopub.status.idle":"2022-01-07T15:35:07.399739Z","shell.execute_reply.started":"2022-01-07T15:30:08.124188Z","shell.execute_reply":"2022-01-07T15:35:07.398824Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n\nparams = grid.best_params_\noof(params, SVR, X_scaled, y.values, 3)\nvisualize(params, SVR)\neval_and_export(params, SVR, \"SVR\")","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:35:07.400721Z","iopub.execute_input":"2022-01-07T15:35:07.400911Z","iopub.status.idle":"2022-01-07T15:35:12.816331Z","shell.execute_reply.started":"2022-01-07T15:35:07.400887Z","shell.execute_reply":"2022-01-07T15:35:12.815561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### NuSVM\nTương tự với SVR, nhưng sử dụng thêm một biến $\\nu$ (thay cho $C$) để giám sát số lượng vector mẫu và lỗi của lề (slack variable). $\\nu$ là cận trên cho phần lỗi của lề và là cận dưới của phần vector hỗ trợ.\n\nCác tham số chính:\n- nu: Tỉ lệ số support vector mong muốn được giữ lại trên tổng số mẫu.\n- C: Trọng số cho biến slack\n- kernel: Phương pháp ánh xạ đầu vào để có chiều không gian có thể phân lớp tốt hơn.","metadata":{}},{"cell_type":"code","source":"%%time\nfrom sklearn.svm import NuSVR\n\nparameters = {\n    'nu': [0.3, 0.5, 0.75],\n    'kernel': ['linear', 'poly', 'rbf'],\n    'degree': [0, 1],\n    'gamma': ['scale', 'auto'],\n    'C': [0.1, 1, 2]\n}\n\ngrid = training(parameters, NuSVR)","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:52:15.122858Z","iopub.execute_input":"2022-01-07T15:52:15.123353Z","iopub.status.idle":"2022-01-07T15:57:00.702342Z","shell.execute_reply.started":"2022-01-07T15:52:15.123306Z","shell.execute_reply":"2022-01-07T15:57:00.701273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n\nparams = grid.best_params_\noof(params, NuSVR, X_scaled, y.values, 3)\nvisualize(params, NuSVR)\neval_and_export(params, NuSVR, \"NuSVR\")","metadata":{"execution":{"iopub.status.busy":"2022-01-07T15:57:00.704409Z","iopub.execute_input":"2022-01-07T15:57:00.704663Z","iopub.status.idle":"2022-01-07T15:57:07.206771Z","shell.execute_reply.started":"2022-01-07T15:57:00.704631Z","shell.execute_reply":"2022-01-07T15:57:07.205795Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Neural Network\n\nMạng thần kinh lan truyền (Neural Network - NN). Là kết quả của việc kết hợp nhiều lớp Perceptron lại. Do mỗi lớp perceptron chỉ dự đoán được bằng siêu phẳng, nên việc kết hợp nhiều lớp Perceptron lại sẽ cho phép biểu diện được tính chất phi tuyến.\n\nNN sẽ gồm nhiều lớp perceptron nối tiếp nhau. Mỗi lớp sẽ thực hiện ánh xạ dữ liệu từ số chiều đầu và thành một số chiều đầu ra khác nhau, bằng cách nhận ma trận với ma trận $W_i$ là ma trận biến đổi ở lớp thứ i. \n\nỞ các lớp khác với lớp cuối, theo sau đầu ra sẽ là một hàm kích hoạt (activation layer). Activation layer có nhiều loại và chức năng khác nhau: \n- identity: không làm gì cả\n- logistic: biến đổi bằng công thức $f(x) = frac 1 (1 + \\exp(-x))$. Hàm sẽ đảm bảo dữ liệu liên tục và nằm trong khoảng $[0, 1]$\n- tanh: biến đổi bằng hàm $f(x) = \\tanh(x) = \\frac {e^x - e^{-x}} {e^x + e^{-x}}$. Hàm sẽ đảm bảo dữ liệu liên tục và nằm trong khoảng $[-1, 1]$\n- relu: triệt tiêu dữ liệu âm, sử dụng hàm $f(x) = \\max(0, x)$\n\nCác tham số chính của NN trong sklearn:\n- hidden_layer_sizes: là tập số chiều cho các lớp ẩn.\n- activation: chọn hàm kích hoạt.\n- solver: Phương pháp tối ưu, tiêu biểu có sgd và adam, trong đó sgd sẽ chạy từng giá trị đầu vào một. còn adam có thể chạy với một tập nhiều đầu vào.\n- alpha: trọng số L2 cho tham số, tương tự Ridge.\n- batch\\_size: số lượng dữ liệu trong 1 tập có thể được dùng để huấn luyện cùng nhau.\n- learning\\_rate: phương pháp được sử dụng để cập nhật tốc độ học trong suốt quá trình huấn luyện. Các phương pháp có thể được sử dụng:\n    - constant: Giữ nguyên tốc độ học, không thay đổi trong suốt quá trình huấn luyện.\n    - invscaling: Giảm tốc độ học theo từng thời điểm t, bằng cách nhân với một hàm mũ $pow(t, \\text{cơ số})$\n    - adaptive: Sử dụng chiến lược giảm tốc độ học mỗi khi 2 epoch liên kề không làm giảm giá trị của hàm mất mát.\n- learning\\_rate\\_init: tốc độ học, hệ số được sử dụng khi cập nhật đạo hàm.\n- max\\_iter: có thể coi như epoch, số lần huấn luyện lại trên tập dữ liệu","metadata":{}},{"cell_type":"code","source":"def warn(*args, **kwargs):\n    pass\nimport warnings\nwarnings.warn = warn\n\nfrom sklearn.neural_network import MLPRegressor\n\nparameters = {\n    'hidden_layer_sizes': [128, (128, 64)],\n    'activation': ['logistic', 'tanh', 'relu'],\n    'solver': ['adam'],\n    'alpha': [0.01, 0.1],\n    'batch_size': [32, 64],\n    'learning_rate_init': [0.001, 0.01],\n    'learning_rate': ['adaptive'],\n    'shuffle': [True],\n    'max_iter': [20, 25],\n    'early_stopping': [True]\n}\n\ngrid = training(parameters, MLPRegressor)","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2022-01-07T15:49:56.681664Z","iopub.execute_input":"2022-01-07T15:49:56.68219Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nparams = grid.best_params_\noof(params, MLPRegressor, X_scaled, y.values, 3)\nvisualize(params, MLPRegressor)\neval_and_export(params, MLPRegressor, \"MLPRegressor\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Decision Tree\nCây quyết định (Decision Tree) là một thuật toán xây dựng một cây, hoạt động bằng cách chia bộ dữ liệu thành những phần nhỏ hơn và những phần nhỏ hơn lại tiếp tục được xây dựng tương tự. Cụ thể, xuất phát từ một node gốc, cây sẽ chọn 1 điều kiện và chia bộ dữ liệu tương ứng ở mỗi node thành 2 bộ nhỏ hơn tương ứng với 2 node con. Quá trình tiếp tục nếu gặp điều kiện dừng:\n- Đạt độ sâu tối đa\n- Số dữ liệu quá ít\n\nThuật toán xây dựng cây được sklearn sử dụng là CART.\n\nCác tham số chính của cây quyết định:\n- criterion: là hàm đánhn giá chất lượng của một lần chia. Do yêu cầu đề bài sử dụng là MAE nên criterion được xét cũng là MAE.\n- splitter: Phương án để chia cây tại mỗi node. \n- max_depth: Độ sâu tối thiểu của cây. Nếu đạt được độ sâu này thì cây sẽ không chia nữa.\n- min\\_samples\\_leaf: Số dữ liệu tối thiểu ở lá. Nếu số dữ liệu thấp hơn min_samples_leaf thì cây sẽ không chia nữa.\n- max_features: Số lượng cột đặc trưng sẽ được sử dụng.","metadata":{}},{"cell_type":"code","source":"%%time\nfrom sklearn.tree import DecisionTreeRegressor\n\nparameters = {\n    'criterion': ['mae'],\n    'splitter': ['best', 'random'],\n    'max_depth': [7, 9, 13],\n    'max_features': ['sqrt'],\n    'max_leaf_nodes': [8, 16, 32]\n}\n\ngrid = training(parameters, DecisionTreeRegressor)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nparams = grid.best_params_\noof(params, DecisionTreeRegressor, X_scaled, y.values, 3)\nvisualize(params, DecisionTreeRegressor)\neval_and_export(params, DecisionTreeRegressor, \"DecisionTree\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Random Forest\n\nRừng ngẫu nhiên (Random Forest), là thuật toán ensemble, nhưng để ở ngay sau DecisionTree, do rừng thì phải gần cây. Thuật toán sử dụng là tạo một hàm dự đoán dựa trên việc xây dựng các cây quyết định trên các tập dữ liệu con và đưa ra kết quả bằng cách lấy trung bình các dự đoán.\n\nCác tham số chính của random forest trong sklearn:\n- n_estimators:  Số lượng cây được xây dựng.\n- criterion: Phương pháp đánh giá độ tốt của một cách chia. Yêu cầu đề bài là sử dụng MAE để đánh giá, nên criterion ở đây cũng được đặt là MAE.\n- max\\_depth: Độ sâu cây tối đa. Nếu một node đạt được độ sâu này sẽ không chia nữa.\n- min\\_samples\\_split: Số lượng mẫu tối thiểu cần để một node có thể chia tiếp. Nếu số lượng mẫu mà nhỏ hơn min_samples_split thì sẽ không chia nữa.\n- min\\_samples\\_leaf: Số lượng mẫu tối thiểu cho một node lá.\n- max\\_features: Số lượng cột tối đa sẽ được lấy để xây dựng cây.","metadata":{}},{"cell_type":"code","source":"%%time\nfrom sklearn.ensemble import RandomForestRegressor\n\nparameters = {\n    'n_estimators': [50, 100],\n    'criterion': ['mae'],\n    'max_depth': [3, 6],\n    'max_features': ['sqrt'],\n    'min_samples_leaf': [1, 8]\n}\n\ngrid = training(parameters, RandomForestRegressor)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nparams = grid.best_params_\noof(params, RandomForestRegressor, X_scaled, y.values, 3)\nvisualize(params, RandomForestRegressor)\neval_and_export(params, RandomForestRegressor, \"RandomForest\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## KNN\n\nK-láng giềng gần nhất hồi quy (K-Nearest Neighbors Regressor), là lớp thuật toán dựa trên phân cụm K láng giềng gần nhất. Mục tiêu được dự đoán bằng cách nội suy cục bộ (local interpolation) trong tập các láng giềng gần nhất trong tập huấn luyện.\n\nCách nội suy phổ biến nhất là tính trung bình các nhãn của láng giềng. \n\nThuật toán để tìm KNN được sử dụng gồm có:\n- brute force: Tìm bằng thuật toán thường. Mỗi lần chạy, duyệt qua dữ liệu trong tập train, rồi tính distance, chọn K láng giềng gần nhất. Tốn rất nhiều thời gian.\n- K-D Tree: Phương pháp xây dựng cây. Dựa trên việc mã hóa các khoảng cách. Ví dụ, nếu A rất xa so với B, và B lại gần C, thì có thể suy ra C rất xa A. KD Tree có cấu trúc là một cây nhị phân, trong đó, mỗi nhánh sẽ sẽ đại diện cho một vùng quan sát. Do cấu trúc cây nên các vùng quan sát sẽ lồng vào nhau. Cây được xây dựng rất nhanh do không dựa vào các thông tin trong chiều đặc trưng (các cột).\n- Ball tree: Phương pháp xây dụng cây mà mỗi node sẽ là một tập các khối siêu cầu (hyper-sphere). Ball tree sẽ chia dữ liệu bằng cách định nghĩa một điểm tâm C và bán kính r, đại diện cho các điểm nằm trong siêu cầu (C, r). Khi tìm kiếm, có thể sử dụng bất đẳng thức tam giác để tìm nhanh hơn.\n\nCác tham số chính trong sklearn:\n- n\\_neighbors: Số lượng láng giềng sẽ được lấy kết quả.\n- weights: Các đánh trọng số ảnh hưởng của các điểm láng giềng đến kết quả hiện tại của điểm đang xét. Có 2 cách đánh trọng số chính là sử dụng trọng số đều (mọi điểm đóng góp như nhau) và trọng số theo khoảng cách (điểm nào gần đốn góp nhiều hơn)\n- algorithm: Thuật toán được sử dụng.\n- p: Mũ norm của khoảng cách. p = 1, là norm 1, khoảng cách Manhattan. p = 2, là norm 2, khoảng cách Euclide.","metadata":{}},{"cell_type":"code","source":"%%time\nfrom sklearn.neighbors import KNeighborsRegressor\n\nparameters = {\n    'n_neighbors': [3, 7, 13],\n    'weights': ['uniform', 'distance'],\n    'algorithm': ['ball_tree', 'kd_tree']\n}\n\ngrid = training(parameters, KNeighborsRegressor)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n\nparams = grid.best_params_\noof(params, KNeighborsRegressor, X_scaled, y.values, 3)\nvisualize(params, KNeighborsRegressor)\neval_and_export(params, KNeighborsRegressor, \"KNeighbors\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Họ Ensemble\n\nLà tập hợp các thuật toán sử dụng kết hợp kết quả của các mô hình nhỏ hơn nhằm tổng hợp và đưa ra dự đoán.\n\n## Boosting\n\nLà phương pháp kết hợp các thuật toán, mô hình học được xây dựng dựa trên mô hình trước đó. Phương pháp chủ yếu là đánh trọng số cho các mô hình mới thêm vào, từ đó hạn chế sai lầm của các mô hình trưóc.\n\nĐối với boosting, bài toán tối ưu được đặt ra là:\n$$\\min _{c_n=1:N, w_n=1:N} L(y, \\sum_{n=1}^Nc_nw_n)$$\n\nTrong đó, L là giá trị hàm mất mát, y là nhãn, $w_n$ là mô hình học thứ n, $c_n$ là trọng số của $w_n$.\n\nKhông chỉ tìm các mô hình học tốt, Boosting hướng tới xây dựng mô hình học từ các mô hình trước đó, thông qua các trọng số $c_n$. Cụ thể bài toán tối ưu trên có thể được viết thành:\n$$\\min _{c_n, w_n} L(y, W_{n-1} + c_n w_n)$$\n\nVới $W_{n-1} = \\sum _{n=1}^{N-1} c_n w_n$","metadata":{}},{"cell_type":"markdown","source":"## CatBoost\n\nLà mô hình hoạt động chính trên các dữ liệu dàng categorical (dữ liệu theo loại). Một ưu điểm nữa là CatBoost có bộ siêu tham số đầu vào khá tốt. Tốn ít thời gian tinh chỉnh tham số.","metadata":{}},{"cell_type":"code","source":"%%time\n\n# Tốn nhiều thời gian\n\nimport catboost as cb\n\nparameters = {\n    'iterations': [30, 50, 100],\n    'depth': [6,8,10],\n    'learning_rate' : [0.01, 0.05, 0.1],\n    'verbose': [False]\n}\n\ngrid = training(parameters, cb.CatBoostRegressor)\nprint(grid.best_params_)","metadata":{"scrolled":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nparams = grid.best_params_\n\noof_with_evalset(params, cb.CatBoostRegressor, X_scaled, y.values, 3)\n\nvisualize(params, cb.CatBoostRegressor)\n\neval_and_export(params, cb.CatBoostRegressor, \"catboost\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Light Gradient Boosting model.\n\nLight Gradient Boosting Model (LightGBM) nối tiếng nhờ nó nhanh và hiệu quả.\n\nCách hoạt động của LightGBM:\n- Sử dụng leaf-wise growth. Xây dựng cây theo từng node, thay vì từng tầng.\n- Sau khi thực hiện chia cây, lần chia cây tiếp theo chỉ được thực hiện trên node có giá trị hàm mất mát lớn hơn.\n- LGBM sử dụng phương pháp đánh giá dựa vào histogram. Đối với các trường liên tục, thay vì sử dụg các biến độc lập, các giá trị sẽ được chia thành các nhóm liên tục, gọi là các bins. \n\nCác tham số của LightGBM:\n- learning\\_rate: Tốc độ học.\n- max\\_depth: Độ sâu tối đa của cây\n- n\\_estimators: Số lần thực hiện Boosting\n- num\\_leaves: Số lượng lá tối đa trong một cây.\n- subsample: Tỉ lệ dữ liệu được sử dụng.\n- colsample\\_bytree: Tỉ lệ số cột được sử dụng để xây dựng một cây.\n- colsample\\_bynode: Tỉ lệ số cột được sử dụng để chia tại một node.\n- lambda\\_l1: Là chuẩn L1 của Regularization.\n- lambda\\_l2: Là chuẩn L2 của Regularization.\n- min\\_gain\\_to\\_split: Lượng giá trị giảm của hàm mất mát tối thiểu để thực hiện một phép chia cây.","metadata":{}},{"cell_type":"code","source":"%%time\nimport lightgbm as lgb\n\nparameters = {\n    'learning_rate': [0.01],\n    'max_depth': [13, 17],\n    'n_estimators': [1000],\n    'num_leaves': [100],\n    'subsample': [0.6, 0.8],\n    'colsample_bytree': [0.8, 1],\n    'colsample_bynode': [0.8, 1],\n    'reg_lambda': [1, 3],\n    'objective': ['regression_l1']\n}\n\ngrid = training(parameters, lgb.LGBMRegressor)","metadata":{"scrolled":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"params = grid.best_params_\n\noof_with_evalset(params, lgb.LGBMRegressor, X_scaled, y.values, 3)\n\nvisualize(params, lgb.LGBMRegressor)\n\neval_and_export(params, lgb.LGBMRegressor, \"LGBM\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Voting\n\nKết hợp nhiều mô hình dự đoán khác nhau và trả về trung bình các giá trị dự đoán.","metadata":{}},{"cell_type":"code","source":"%%time\nfrom sklearn.ensemble import VotingRegressor\n\nvoting = [\n    ('rf', RandomForestRegressor(criterion='mae', max_depth=6, max_features='sqrt')),\n    ('nuSVM', NuSVR(C=1, degree=0, nu=0.75)),\n    ('svm', SVR(C=1, degree=0, epsilon=1)),\n    ('nn', MLPRegressor(activation='logistic', alpha=0.01, batch_size=64,early_stopping=True, hidden_layer_sizes=128,learning_rate='adaptive', learning_rate_init=0.01, max_iter=25)),\n    ('knn', KNeighborsRegressor(algorithm='ball_tree', n_neighbors=17, weights='distance'))\n]\n\nparams = {\n    'estimators': voting\n}\n\noof(params, VotingRegressor, X_scaled, y.values, 3)\nvisualize(params, VotingRegressor)\neval_and_export(params, VotingRegressor, \"Voting\")","metadata":{"execution":{"iopub.status.busy":"2022-01-07T16:39:43.594318Z","iopub.execute_input":"2022-01-07T16:39:43.594785Z","iopub.status.idle":"2022-01-07T16:42:13.115662Z","shell.execute_reply.started":"2022-01-07T16:39:43.594744Z","shell.execute_reply":"2022-01-07T16:42:13.114711Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Stacking\n\nKết hợp kết quả của nhiều mô hình khác nhau để thực hiện dự đoán. Khác với voting, đầu ra của các mô hình khác nhau sẽ được đánh trọng số bởi một hàm dự đoán cuối.\n\nCác tham số của StackingRegressor của sklearn:\n- estimators: Là tập các mô hình dự đoán sẽ được xếp với nhau.\n- final\\_estimator: Là mô hình được sử dụng để kết hợp tập các mô hình dự đoán với nhau.\n- cv: Số lượng tập dữ liệu được chia ra bởi cross-validation.\n- n\\_jobs: Quy định số lượng quá trình có thể chạy song song.","metadata":{}},{"cell_type":"code","source":"%%time\nfrom sklearn.ensemble import StackingRegressor\n\nstacking = [\n    ('rf', RandomForestRegressor(criterion='mae', max_depth=6, max_features='sqrt')),\n    ('nuSVM', NuSVR(C=1, degree=0, nu=0.75)),\n    ('svm', SVR(C=1, degree=0, epsilon=1)),\n    ('nn', MLPRegressor(activation='logistic', alpha=0.01, batch_size=64,\n             early_stopping=True, hidden_layer_sizes=128,\n             learning_rate='adaptive', learning_rate_init=0.01, max_iter=25)),\n    ('knn', KNeighborsRegressor(algorithm='ball_tree', n_neighbors=17, weights='distance'))\n]\n\nparams = {\n    'estimators': stacking,\n    'cv': 3,\n    'n_jobs': 3\n}\n\noof(params, StackingRegressor, X_scaled, y.values, 3)\nvisualize(params, StackingRegressor)\neval_and_export(params, StackingRegressor, \"StackingRegressor\")","metadata":{"execution":{"iopub.status.busy":"2022-01-07T16:47:03.263755Z","iopub.execute_input":"2022-01-07T16:47:03.264049Z","iopub.status.idle":"2022-01-07T16:50:46.730048Z","shell.execute_reply.started":"2022-01-07T16:47:03.264015Z","shell.execute_reply":"2022-01-07T16:50:46.727171Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Kết quả ","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}