You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
648 lines
28 KiB
648 lines
28 KiB
{
|
|
"nbformat": 4,
|
|
"nbformat_minor": 0,
|
|
"metadata": {
|
|
"colab": {
|
|
"name": "lesson_12-R.ipynb",
|
|
"provenance": [],
|
|
"collapsed_sections": []
|
|
},
|
|
"kernelspec": {
|
|
"name": "ir",
|
|
"display_name": "R"
|
|
},
|
|
"language_info": {
|
|
"name": "R"
|
|
},
|
|
"coopTranslator": {
|
|
"original_hash": "fab50046ca413a38939d579f8432274f",
|
|
"translation_date": "2025-09-06T14:50:37+00:00",
|
|
"source_file": "4-Classification/3-Classifiers-2/solution/R/lesson_12-R.ipynb",
|
|
"language_code": "vi"
|
|
}
|
|
},
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "jsFutf_ygqSx"
|
|
},
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "HD54bEefgtNO"
|
|
},
|
|
"source": [
|
|
"## Bộ phân loại ẩm thực 2\n",
|
|
"\n",
|
|
"Trong bài học phân loại thứ hai này, chúng ta sẽ khám phá `nhiều cách hơn` để phân loại dữ liệu dạng danh mục. Chúng ta cũng sẽ tìm hiểu về hậu quả của việc chọn một bộ phân loại thay vì bộ phân loại khác.\n",
|
|
"\n",
|
|
"### [**Câu hỏi trước bài giảng**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/23/)\n",
|
|
"\n",
|
|
"### **Điều kiện tiên quyết**\n",
|
|
"\n",
|
|
"Chúng tôi giả định rằng bạn đã hoàn thành các bài học trước vì chúng ta sẽ tiếp tục sử dụng một số khái niệm đã học trước đó.\n",
|
|
"\n",
|
|
"Đối với bài học này, chúng ta sẽ cần các gói sau:\n",
|
|
"\n",
|
|
"- `tidyverse`: [tidyverse](https://www.tidyverse.org/) là một [bộ sưu tập các gói R](https://www.tidyverse.org/packages) được thiết kế để làm cho khoa học dữ liệu nhanh hơn, dễ dàng hơn và thú vị hơn!\n",
|
|
"\n",
|
|
"- `tidymodels`: [tidymodels](https://www.tidymodels.org/) là một [khung làm việc](https://www.tidymodels.org/packages/) bao gồm các gói dành cho mô hình hóa và học máy.\n",
|
|
"\n",
|
|
"- `themis`: [gói themis](https://themis.tidymodels.org/) cung cấp các bước bổ sung trong công thức để xử lý dữ liệu không cân bằng.\n",
|
|
"\n",
|
|
"Bạn có thể cài đặt chúng bằng lệnh:\n",
|
|
"\n",
|
|
"`install.packages(c(\"tidyverse\", \"tidymodels\", \"kernlab\", \"themis\", \"ranger\", \"xgboost\", \"kknn\"))`\n",
|
|
"\n",
|
|
"Ngoài ra, đoạn mã dưới đây sẽ kiểm tra xem bạn đã có các gói cần thiết để hoàn thành module này chưa và cài đặt chúng cho bạn nếu chúng bị thiếu.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "vZ57IuUxgyQt"
|
|
},
|
|
"source": [
|
|
"suppressWarnings(if (!require(\"pacman\"))install.packages(\"pacman\"))\n",
|
|
"\n",
|
|
"pacman::p_load(tidyverse, tidymodels, themis, kernlab, ranger, xgboost, kknn)"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "z22M-pj4g07x"
|
|
},
|
|
"source": [
|
|
"## **1. Một bản đồ phân loại**\n",
|
|
"\n",
|
|
"Trong [bài học trước](https://github.com/microsoft/ML-For-Beginners/tree/main/4-Classification/2-Classifiers-1), chúng ta đã cố gắng giải quyết câu hỏi: làm thế nào để chọn giữa nhiều mô hình? Phần lớn điều này phụ thuộc vào đặc điểm của dữ liệu và loại vấn đề mà chúng ta muốn giải quyết (ví dụ như phân loại hay hồi quy?)\n",
|
|
"\n",
|
|
"Trước đây, chúng ta đã tìm hiểu về các tùy chọn khác nhau khi phân loại dữ liệu bằng bảng gian lận của Microsoft. Framework Machine Learning của Python, Scikit-learn, cung cấp một bảng gian lận tương tự nhưng chi tiết hơn, giúp bạn thu hẹp các bộ ước lượng (một thuật ngữ khác cho các bộ phân loại):\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/map.png\"\n",
|
|
" width=\"700\"/>\n",
|
|
" <figcaption></figcaption>\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "u1i3xRIVg7vG"
|
|
},
|
|
"source": [
|
|
"> Mẹo: [truy cập bản đồ trực tuyến này](https://scikit-learn.org/stable/tutorial/machine_learning_map/) và nhấp theo đường dẫn để đọc tài liệu.\n",
|
|
">\n",
|
|
"> Trang [tham khảo Tidymodels](https://www.tidymodels.org/find/parsnip/#models) cũng cung cấp tài liệu tuyệt vời về các loại mô hình khác nhau.\n",
|
|
"\n",
|
|
"### **Kế hoạch** 🗺️\n",
|
|
"\n",
|
|
"Bản đồ này rất hữu ích khi bạn đã hiểu rõ dữ liệu của mình, vì bạn có thể 'đi bộ' theo các đường dẫn để đưa ra quyết định:\n",
|
|
"\n",
|
|
"- Chúng ta có \\>50 mẫu\n",
|
|
"\n",
|
|
"- Chúng ta muốn dự đoán một danh mục\n",
|
|
"\n",
|
|
"- Chúng ta có dữ liệu được gắn nhãn\n",
|
|
"\n",
|
|
"- Chúng ta có ít hơn 100K mẫu\n",
|
|
"\n",
|
|
"- ✨ Chúng ta có thể chọn Linear SVC\n",
|
|
"\n",
|
|
"- Nếu cách đó không hiệu quả, vì chúng ta có dữ liệu dạng số\n",
|
|
"\n",
|
|
" - Chúng ta có thể thử ✨ KNeighbors Classifier\n",
|
|
"\n",
|
|
" - Nếu cách đó không hiệu quả, thử ✨ SVC và ✨ Ensemble Classifiers\n",
|
|
"\n",
|
|
"Đây là một lộ trình rất hữu ích để làm theo. Bây giờ, hãy bắt đầu ngay với [tidymodels](https://www.tidymodels.org/): một bộ sưu tập các gói R nhất quán và linh hoạt được phát triển để khuyến khích thực hành thống kê tốt 😊.\n",
|
|
"\n",
|
|
"## 2. Chia dữ liệu và xử lý tập dữ liệu không cân bằng.\n",
|
|
"\n",
|
|
"Từ các bài học trước, chúng ta đã học rằng có một tập hợp các thành phần chung giữa các món ăn của chúng ta. Ngoài ra, có sự phân bố không đồng đều về số lượng món ăn.\n",
|
|
"\n",
|
|
"Chúng ta sẽ xử lý những điều này bằng cách:\n",
|
|
"\n",
|
|
"- Loại bỏ các thành phần phổ biến nhất gây nhầm lẫn giữa các món ăn khác nhau, sử dụng `dplyr::select()`.\n",
|
|
"\n",
|
|
"- Sử dụng một `recipe` để tiền xử lý dữ liệu, chuẩn bị cho việc mô hình hóa bằng cách áp dụng thuật toán `over-sampling`.\n",
|
|
"\n",
|
|
"Chúng ta đã xem qua những điều trên trong bài học trước nên việc này sẽ rất dễ dàng 🥳!\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "6tj_rN00hClA"
|
|
},
|
|
"source": [
|
|
"# Load the core Tidyverse and Tidymodels packages\n",
|
|
"library(tidyverse)\n",
|
|
"library(tidymodels)\n",
|
|
"\n",
|
|
"# Load the original cuisines data\n",
|
|
"df <- read_csv(file = \"https://raw.githubusercontent.com/microsoft/ML-For-Beginners/main/4-Classification/data/cuisines.csv\")\n",
|
|
"\n",
|
|
"# Drop id column, rice, garlic and ginger from our original data set\n",
|
|
"df_select <- df %>% \n",
|
|
" select(-c(1, rice, garlic, ginger)) %>%\n",
|
|
" # Encode cuisine column as categorical\n",
|
|
" mutate(cuisine = factor(cuisine))\n",
|
|
"\n",
|
|
"\n",
|
|
"# Create data split specification\n",
|
|
"set.seed(2056)\n",
|
|
"cuisines_split <- initial_split(data = df_select,\n",
|
|
" strata = cuisine,\n",
|
|
" prop = 0.7)\n",
|
|
"\n",
|
|
"# Extract the data in each split\n",
|
|
"cuisines_train <- training(cuisines_split)\n",
|
|
"cuisines_test <- testing(cuisines_split)\n",
|
|
"\n",
|
|
"# Display distribution of cuisines in the training set\n",
|
|
"cuisines_train %>% \n",
|
|
" count(cuisine) %>% \n",
|
|
" arrange(desc(n))"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "zFin5yw3hHb1"
|
|
},
|
|
"source": [
|
|
"### Xử lý dữ liệu không cân bằng\n",
|
|
"\n",
|
|
"Dữ liệu không cân bằng thường ảnh hưởng tiêu cực đến hiệu suất của mô hình. Nhiều mô hình hoạt động tốt nhất khi số lượng quan sát là bằng nhau và do đó thường gặp khó khăn với dữ liệu không cân bằng.\n",
|
|
"\n",
|
|
"Có hai cách chính để xử lý các tập dữ liệu không cân bằng:\n",
|
|
"\n",
|
|
"- thêm các quan sát vào lớp thiểu số: `Over-sampling`, ví dụ sử dụng thuật toán SMOTE, thuật toán này tạo ra các ví dụ mới cho lớp thiểu số một cách tổng hợp bằng cách sử dụng các điểm lân cận gần nhất của các trường hợp này.\n",
|
|
"\n",
|
|
"- loại bỏ các quan sát từ lớp đa số: `Under-sampling`\n",
|
|
"\n",
|
|
"Trong bài học trước, chúng ta đã minh họa cách xử lý các tập dữ liệu không cân bằng bằng cách sử dụng một `recipe`. Recipe có thể được xem như một bản thiết kế mô tả các bước cần áp dụng cho một tập dữ liệu để chuẩn bị cho việc phân tích dữ liệu. Trong trường hợp của chúng ta, mục tiêu là có một phân phối đồng đều về số lượng các loại món ăn trong `training set`. Hãy bắt đầu ngay thôi.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "cRzTnHolhLWd"
|
|
},
|
|
"source": [
|
|
"# Load themis package for dealing with imbalanced data\n",
|
|
"library(themis)\n",
|
|
"\n",
|
|
"# Create a recipe for preprocessing training data\n",
|
|
"cuisines_recipe <- recipe(cuisine ~ ., data = cuisines_train) %>%\n",
|
|
" step_smote(cuisine) \n",
|
|
"\n",
|
|
"# Print recipe\n",
|
|
"cuisines_recipe"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "KxOQ2ORhhO81"
|
|
},
|
|
"source": [
|
|
"Bây giờ chúng ta sẵn sàng để huấn luyện các mô hình 👩💻👨💻!\n",
|
|
"\n",
|
|
"## 3. Vượt ra ngoài các mô hình hồi quy đa thức\n",
|
|
"\n",
|
|
"Trong bài học trước, chúng ta đã tìm hiểu về các mô hình hồi quy đa thức. Hãy khám phá một số mô hình linh hoạt hơn cho bài toán phân loại.\n",
|
|
"\n",
|
|
"### Máy Vector Hỗ Trợ (Support Vector Machines)\n",
|
|
"\n",
|
|
"Trong bối cảnh phân loại, `Máy Vector Hỗ Trợ` là một kỹ thuật học máy cố gắng tìm một *siêu phẳng* (*hyperplane*) để \"tách biệt tốt nhất\" các lớp. Hãy xem một ví dụ đơn giản:\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/svm.png\"\n",
|
|
" width=\"300\"/>\n",
|
|
" <figcaption>https://commons.wikimedia.org/w/index.php?curid=22877598</figcaption>\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "C4Wsd0vZhXYu"
|
|
},
|
|
"source": [
|
|
"H1~ không tách biệt các lớp. H2~ có tách biệt, nhưng chỉ với một khoảng cách nhỏ. H3~ tách biệt chúng với khoảng cách tối đa.\n",
|
|
"\n",
|
|
"#### Bộ phân loại tuyến tính SVM\n",
|
|
"\n",
|
|
"Hỗ trợ phân cụm vector (SVC) là một nhánh của họ các kỹ thuật máy học (ML) thuộc máy vector hỗ trợ (SVM). Trong SVC, siêu phẳng được chọn để phân tách `phần lớn` các quan sát huấn luyện một cách chính xác, nhưng `có thể phân loại sai` một vài quan sát. Bằng cách cho phép một số điểm nằm ở phía sai, SVM trở nên mạnh mẽ hơn trước các giá trị ngoại lai, do đó cải thiện khả năng tổng quát hóa với dữ liệu mới. Tham số điều chỉnh sự vi phạm này được gọi là `cost`, với giá trị mặc định là 1 (xem `help(\"svm_poly\")`).\n",
|
|
"\n",
|
|
"Hãy tạo một SVC tuyến tính bằng cách đặt `degree = 1` trong một mô hình SVM đa thức.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "vJpp6nuChlBz"
|
|
},
|
|
"source": [
|
|
"# Make a linear SVC specification\n",
|
|
"svc_linear_spec <- svm_poly(degree = 1) %>% \n",
|
|
" set_engine(\"kernlab\") %>% \n",
|
|
" set_mode(\"classification\")\n",
|
|
"\n",
|
|
"# Bundle specification and recipe into a worklow\n",
|
|
"svc_linear_wf <- workflow() %>% \n",
|
|
" add_recipe(cuisines_recipe) %>% \n",
|
|
" add_model(svc_linear_spec)\n",
|
|
"\n",
|
|
"# Print out workflow\n",
|
|
"svc_linear_wf"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "rDs8cWNkhoqu"
|
|
},
|
|
"source": [
|
|
"Bây giờ khi chúng ta đã lưu lại các bước tiền xử lý và đặc tả mô hình vào một *workflow*, chúng ta có thể tiến hành huấn luyện SVC tuyến tính và đánh giá kết quả trong quá trình đó. Để đo lường hiệu suất, hãy tạo một tập hợp các chỉ số để đánh giá: `accuracy`, `sensitivity`, `Positive Predicted Value` và `F Measure`.\n",
|
|
"\n",
|
|
"> `augment()` sẽ thêm cột (hoặc các cột) cho dự đoán vào dữ liệu được cung cấp.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "81wiqcwuhrnq"
|
|
},
|
|
"source": [
|
|
"# Train a linear SVC model\n",
|
|
"svc_linear_fit <- svc_linear_wf %>% \n",
|
|
" fit(data = cuisines_train)\n",
|
|
"\n",
|
|
"# Create a metric set\n",
|
|
"eval_metrics <- metric_set(ppv, sens, accuracy, f_meas)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Make predictions and Evaluate model performance\n",
|
|
"svc_linear_fit %>% \n",
|
|
" augment(new_data = cuisines_test) %>% \n",
|
|
" eval_metrics(truth = cuisine, estimate = .pred_class)"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "0UFQvHf-huo3"
|
|
},
|
|
"source": [
|
|
"#### Máy Vector Hỗ Trợ\n",
|
|
"\n",
|
|
"Máy vector hỗ trợ (SVM) là một sự mở rộng của bộ phân loại vector hỗ trợ nhằm đáp ứng ranh giới phi tuyến giữa các lớp. Về cơ bản, SVM sử dụng *kernel trick* để mở rộng không gian đặc trưng, thích nghi với các mối quan hệ phi tuyến giữa các lớp. Một hàm kernel phổ biến và cực kỳ linh hoạt được SVM sử dụng là *Hàm cơ sở xuyên tâm.* Hãy cùng xem cách nó hoạt động trên dữ liệu của chúng ta.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "-KX4S8mzhzmp"
|
|
},
|
|
"source": [
|
|
"set.seed(2056)\n",
|
|
"\n",
|
|
"# Make an RBF SVM specification\n",
|
|
"svm_rbf_spec <- svm_rbf() %>% \n",
|
|
" set_engine(\"kernlab\") %>% \n",
|
|
" set_mode(\"classification\")\n",
|
|
"\n",
|
|
"# Bundle specification and recipe into a worklow\n",
|
|
"svm_rbf_wf <- workflow() %>% \n",
|
|
" add_recipe(cuisines_recipe) %>% \n",
|
|
" add_model(svm_rbf_spec)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Train an RBF model\n",
|
|
"svm_rbf_fit <- svm_rbf_wf %>% \n",
|
|
" fit(data = cuisines_train)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Make predictions and Evaluate model performance\n",
|
|
"svm_rbf_fit %>% \n",
|
|
" augment(new_data = cuisines_test) %>% \n",
|
|
" eval_metrics(truth = cuisine, estimate = .pred_class)"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "QBFSa7WSh4HQ"
|
|
},
|
|
"source": [
|
|
"Tuyệt vời hơn 🤩!\n",
|
|
"\n",
|
|
"> ✅ Vui lòng xem:\n",
|
|
">\n",
|
|
"> - [*Support Vector Machines*](https://bradleyboehmke.github.io/HOML/svm.html), Hands-on Machine Learning with R\n",
|
|
">\n",
|
|
"> - [*Support Vector Machines*](https://www.statlearning.com/), An Introduction to Statistical Learning with Applications in R\n",
|
|
">\n",
|
|
"> để đọc thêm.\n",
|
|
"\n",
|
|
"### Bộ phân loại Hàng xóm Gần nhất\n",
|
|
"\n",
|
|
"*K*-nearest neighbor (KNN) là một thuật toán trong đó mỗi quan sát được dự đoán dựa trên *sự tương đồng* của nó với các quan sát khác.\n",
|
|
"\n",
|
|
"Hãy thử áp dụng nó vào dữ liệu của chúng ta.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "k4BxxBcdh9Ka"
|
|
},
|
|
"source": [
|
|
"# Make a KNN specification\n",
|
|
"knn_spec <- nearest_neighbor() %>% \n",
|
|
" set_engine(\"kknn\") %>% \n",
|
|
" set_mode(\"classification\")\n",
|
|
"\n",
|
|
"# Bundle recipe and model specification into a workflow\n",
|
|
"knn_wf <- workflow() %>% \n",
|
|
" add_recipe(cuisines_recipe) %>% \n",
|
|
" add_model(knn_spec)\n",
|
|
"\n",
|
|
"# Train a boosted tree model\n",
|
|
"knn_wf_fit <- knn_wf %>% \n",
|
|
" fit(data = cuisines_train)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Make predictions and Evaluate model performance\n",
|
|
"knn_wf_fit %>% \n",
|
|
" augment(new_data = cuisines_test) %>% \n",
|
|
" eval_metrics(truth = cuisine, estimate = .pred_class)"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "HaegQseriAcj"
|
|
},
|
|
"source": [
|
|
"Có vẻ như mô hình này không hoạt động tốt lắm. Có lẽ việc thay đổi các tham số của mô hình (xem `help(\"nearest_neighbor\")`) sẽ cải thiện hiệu suất của mô hình. Hãy chắc chắn thử nghiệm điều này.\n",
|
|
"\n",
|
|
"> ✅ Vui lòng tham khảo:\n",
|
|
">\n",
|
|
"> - [Hands-on Machine Learning with R](https://bradleyboehmke.github.io/HOML/)\n",
|
|
">\n",
|
|
"> - [An Introduction to Statistical Learning with Applications in R](https://www.statlearning.com/)\n",
|
|
">\n",
|
|
"> để tìm hiểu thêm về bộ phân loại *K*-Nearest Neighbors.\n",
|
|
"\n",
|
|
"### Bộ phân loại tập hợp (Ensemble classifiers)\n",
|
|
"\n",
|
|
"Các thuật toán tập hợp hoạt động bằng cách kết hợp nhiều bộ ước lượng cơ sở để tạo ra một mô hình tối ưu thông qua:\n",
|
|
"\n",
|
|
"`bagging`: áp dụng một *hàm trung bình* cho một tập hợp các mô hình cơ sở\n",
|
|
"\n",
|
|
"`boosting`: xây dựng một chuỗi các mô hình, trong đó mỗi mô hình kế tiếp cải thiện hiệu suất dự đoán dựa trên mô hình trước.\n",
|
|
"\n",
|
|
"Hãy bắt đầu bằng cách thử nghiệm mô hình Random Forest, mô hình này xây dựng một tập hợp lớn các cây quyết định, sau đó áp dụng một hàm trung bình để tạo ra một mô hình tổng thể tốt hơn.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "49DPoVs6iK1M"
|
|
},
|
|
"source": [
|
|
"# Make a random forest specification\n",
|
|
"rf_spec <- rand_forest() %>% \n",
|
|
" set_engine(\"ranger\") %>% \n",
|
|
" set_mode(\"classification\")\n",
|
|
"\n",
|
|
"# Bundle recipe and model specification into a workflow\n",
|
|
"rf_wf <- workflow() %>% \n",
|
|
" add_recipe(cuisines_recipe) %>% \n",
|
|
" add_model(rf_spec)\n",
|
|
"\n",
|
|
"# Train a random forest model\n",
|
|
"rf_wf_fit <- rf_wf %>% \n",
|
|
" fit(data = cuisines_train)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Make predictions and Evaluate model performance\n",
|
|
"rf_wf_fit %>% \n",
|
|
" augment(new_data = cuisines_test) %>% \n",
|
|
" eval_metrics(truth = cuisine, estimate = .pred_class)"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "RGVYwC_aiUWc"
|
|
},
|
|
"source": [
|
|
"Làm tốt lắm 👏!\n",
|
|
"\n",
|
|
"Hãy cùng thử nghiệm với mô hình Boosted Tree.\n",
|
|
"\n",
|
|
"Boosted Tree định nghĩa một phương pháp tập hợp, tạo ra một chuỗi các cây quyết định tuần tự, trong đó mỗi cây phụ thuộc vào kết quả của các cây trước đó nhằm giảm dần lỗi. Phương pháp này tập trung vào trọng số của các mục bị phân loại sai và điều chỉnh việc khớp cho bộ phân loại tiếp theo để sửa lỗi.\n",
|
|
"\n",
|
|
"Có nhiều cách khác nhau để khớp mô hình này (xem `help(\"boost_tree\")`). Trong ví dụ này, chúng ta sẽ khớp Boosted trees thông qua công cụ `xgboost`.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "Py1YWo-micWs"
|
|
},
|
|
"source": [
|
|
"# Make a boosted tree specification\n",
|
|
"boost_spec <- boost_tree(trees = 200) %>% \n",
|
|
" set_engine(\"xgboost\") %>% \n",
|
|
" set_mode(\"classification\")\n",
|
|
"\n",
|
|
"# Bundle recipe and model specification into a workflow\n",
|
|
"boost_wf <- workflow() %>% \n",
|
|
" add_recipe(cuisines_recipe) %>% \n",
|
|
" add_model(boost_spec)\n",
|
|
"\n",
|
|
"# Train a boosted tree model\n",
|
|
"boost_wf_fit <- boost_wf %>% \n",
|
|
" fit(data = cuisines_train)\n",
|
|
"\n",
|
|
"\n",
|
|
"# Make predictions and Evaluate model performance\n",
|
|
"boost_wf_fit %>% \n",
|
|
" augment(new_data = cuisines_test) %>% \n",
|
|
" eval_metrics(truth = cuisine, estimate = .pred_class)"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "zNQnbuejigZM"
|
|
},
|
|
"source": [
|
|
"> ✅ Vui lòng xem:\n",
|
|
">\n",
|
|
"> - [Machine Learning for Social Scientists](https://cimentadaj.github.io/ml_socsci/tree-based-methods.html#random-forests)\n",
|
|
">\n",
|
|
"> - [Hands-on Machine Learning with R](https://bradleyboehmke.github.io/HOML/)\n",
|
|
">\n",
|
|
"> - [An Introduction to Statistical Learning with Applications in R](https://www.statlearning.com/)\n",
|
|
">\n",
|
|
"> - <https://algotech.netlify.app/blog/xgboost/> - Khám phá mô hình AdaBoost, một lựa chọn thay thế tốt cho xgboost.\n",
|
|
">\n",
|
|
"> để tìm hiểu thêm về các bộ phân loại Ensemble.\n",
|
|
"\n",
|
|
"## 4. Bổ sung - so sánh nhiều mô hình\n",
|
|
"\n",
|
|
"Chúng ta đã xây dựng khá nhiều mô hình trong bài thực hành này 🙌. Việc tạo ra nhiều quy trình làm việc từ các bộ tiền xử lý và/hoặc các đặc tả mô hình khác nhau, sau đó tính toán từng chỉ số hiệu suất một cách riêng lẻ có thể trở nên tẻ nhạt hoặc khó khăn.\n",
|
|
"\n",
|
|
"Hãy xem liệu chúng ta có thể giải quyết vấn đề này bằng cách tạo một hàm để huấn luyện danh sách các quy trình làm việc trên tập huấn luyện, sau đó trả về các chỉ số hiệu suất dựa trên tập kiểm tra. Chúng ta sẽ sử dụng `map()` và `map_dfr()` từ gói [purrr](https://purrr.tidyverse.org/) để áp dụng các hàm cho từng phần tử trong danh sách.\n",
|
|
"\n",
|
|
"> Các hàm [`map()`](https://purrr.tidyverse.org/reference/map.html) cho phép bạn thay thế nhiều vòng lặp for bằng mã ngắn gọn hơn và dễ đọc hơn. Nơi tốt nhất để tìm hiểu về các hàm [`map()`](https://purrr.tidyverse.org/reference/map.html) là chương [iteration](http://r4ds.had.co.nz/iteration.html) trong sách R for Data Science.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "Qzb7LyZnimd2"
|
|
},
|
|
"source": [
|
|
"set.seed(2056)\n",
|
|
"\n",
|
|
"# Create a metric set\n",
|
|
"eval_metrics <- metric_set(ppv, sens, accuracy, f_meas)\n",
|
|
"\n",
|
|
"# Define a function that returns performance metrics\n",
|
|
"compare_models <- function(workflow_list, train_set, test_set){\n",
|
|
" \n",
|
|
" suppressWarnings(\n",
|
|
" # Fit each model to the train_set\n",
|
|
" map(workflow_list, fit, data = train_set) %>% \n",
|
|
" # Make predictions on the test set\n",
|
|
" map_dfr(augment, new_data = test_set, .id = \"model\") %>%\n",
|
|
" # Select desired columns\n",
|
|
" select(model, cuisine, .pred_class) %>% \n",
|
|
" # Evaluate model performance\n",
|
|
" group_by(model) %>% \n",
|
|
" eval_metrics(truth = cuisine, estimate = .pred_class) %>% \n",
|
|
" ungroup()\n",
|
|
" )\n",
|
|
" \n",
|
|
"} # End of function"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "Fwa712sNisDA"
|
|
},
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"metadata": {
|
|
"id": "3i4VJOi2iu-a"
|
|
},
|
|
"source": [
|
|
"# Make a list of workflows\n",
|
|
"workflow_list <- list(\n",
|
|
" \"svc\" = svc_linear_wf,\n",
|
|
" \"svm\" = svm_rbf_wf,\n",
|
|
" \"knn\" = knn_wf,\n",
|
|
" \"random_forest\" = rf_wf,\n",
|
|
" \"xgboost\" = boost_wf)\n",
|
|
"\n",
|
|
"# Call the function\n",
|
|
"set.seed(2056)\n",
|
|
"perf_metrics <- compare_models(workflow_list = workflow_list, train_set = cuisines_train, test_set = cuisines_test)\n",
|
|
"\n",
|
|
"# Print out performance metrics\n",
|
|
"perf_metrics %>% \n",
|
|
" group_by(.metric) %>% \n",
|
|
" arrange(desc(.estimate)) %>% \n",
|
|
" slice_head(n=7)\n",
|
|
"\n",
|
|
"# Compare accuracy\n",
|
|
"perf_metrics %>% \n",
|
|
" filter(.metric == \"accuracy\") %>% \n",
|
|
" arrange(desc(.estimate))\n"
|
|
],
|
|
"execution_count": null,
|
|
"outputs": []
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {
|
|
"id": "KuWK_lEli4nW"
|
|
},
|
|
"source": [
|
|
"[**workflowset**](https://workflowsets.tidymodels.org/) cho phép người dùng tạo và dễ dàng huấn luyện một số lượng lớn mô hình, nhưng chủ yếu được thiết kế để hoạt động với các kỹ thuật lấy mẫu lại như `cross-validation`, một phương pháp mà chúng ta chưa đề cập đến.\n",
|
|
"\n",
|
|
"## **🚀Thử thách**\n",
|
|
"\n",
|
|
"Mỗi kỹ thuật này có một số lượng lớn các tham số mà bạn có thể điều chỉnh, ví dụ như `cost` trong SVMs, `neighbors` trong KNN, `mtry` (Các Dự đoán Được Chọn Ngẫu Nhiên) trong Random Forest.\n",
|
|
"\n",
|
|
"Hãy nghiên cứu các tham số mặc định của từng kỹ thuật và suy nghĩ về việc điều chỉnh các tham số này sẽ ảnh hưởng như thế nào đến chất lượng của mô hình.\n",
|
|
"\n",
|
|
"Để tìm hiểu thêm về một mô hình cụ thể và các tham số của nó, sử dụng: `help(\"model\")` ví dụ `help(\"rand_forest\")`\n",
|
|
"\n",
|
|
"> Trong thực tế, chúng ta thường *ước lượng* các *giá trị tốt nhất* cho các tham số này bằng cách huấn luyện nhiều mô hình trên một `bộ dữ liệu mô phỏng` và đo lường hiệu suất của tất cả các mô hình này. Quá trình này được gọi là **tuning**.\n",
|
|
"\n",
|
|
"### [**Câu hỏi sau bài giảng**](https://gray-sand-07a10f403.1.azurestaticapps.net/quiz/24/)\n",
|
|
"\n",
|
|
"### **Ôn tập & Tự học**\n",
|
|
"\n",
|
|
"Có rất nhiều thuật ngữ chuyên ngành trong các bài học này, vì vậy hãy dành một chút thời gian để xem lại [danh sách này](https://docs.microsoft.com/dotnet/machine-learning/resources/glossary?WT.mc_id=academic-77952-leestott) các thuật ngữ hữu ích!\n",
|
|
"\n",
|
|
"#### CẢM ƠN ĐẾN:\n",
|
|
"\n",
|
|
"[`Allison Horst`](https://twitter.com/allison_horst/) vì đã tạo ra những hình minh họa tuyệt vời giúp R trở nên thân thiện và hấp dẫn hơn. Tìm thêm các hình minh họa tại [bộ sưu tập của cô ấy](https://www.google.com/url?q=https://github.com/allisonhorst/stats-illustrations&sa=D&source=editors&ust=1626380772530000&usg=AOvVaw3zcfyCizFQZpkSLzxiiQEM).\n",
|
|
"\n",
|
|
"[Cassie Breviu](https://www.twitter.com/cassieview) và [Jen Looper](https://www.twitter.com/jenlooper) vì đã tạo ra phiên bản Python gốc của module này ♥️\n",
|
|
"\n",
|
|
"Chúc học tập vui vẻ,\n",
|
|
"\n",
|
|
"[Eric](https://twitter.com/ericntay), Đại sứ Sinh viên Microsoft Learn Vàng.\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/r_learners_sm.jpeg\"\n",
|
|
" width=\"569\"/>\n",
|
|
" <figcaption>Tác phẩm nghệ thuật của @allison_horst</figcaption>\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n---\n\n**Tuyên bố miễn trừ trách nhiệm**: \nTài liệu này đã được dịch bằng dịch vụ dịch thuật AI [Co-op Translator](https://github.com/Azure/co-op-translator). Mặc dù chúng tôi cố gắng đảm bảo độ chính xác, xin lưu ý rằng các bản dịch tự động có thể chứa lỗi hoặc không chính xác. Tài liệu gốc bằng ngôn ngữ bản địa nên được coi là nguồn thông tin chính thức. Đối với các thông tin quan trọng, khuyến nghị sử dụng dịch vụ dịch thuật chuyên nghiệp bởi con người. Chúng tôi không chịu trách nhiệm cho bất kỳ sự hiểu lầm hoặc diễn giải sai nào phát sinh từ việc sử dụng bản dịch này.\n"
|
|
]
|
|
}
|
|
]
|
|
} |