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.
448 lines
20 KiB
448 lines
20 KiB
{
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2,
|
|
"metadata": {
|
|
"colab": {
|
|
"name": "lesson_1-R.ipynb",
|
|
"provenance": [],
|
|
"collapsed_sections": [],
|
|
"toc_visible": true
|
|
},
|
|
"kernelspec": {
|
|
"name": "ir",
|
|
"display_name": "R"
|
|
},
|
|
"language_info": {
|
|
"name": "R"
|
|
},
|
|
"coopTranslator": {
|
|
"original_hash": "c18d3bd0bd8ae3878597e89dcd1fa5c1",
|
|
"translation_date": "2025-09-06T13:45:46+00:00",
|
|
"source_file": "2-Regression/1-Tools/solution/R/lesson_1-R.ipynb",
|
|
"language_code": "vi"
|
|
}
|
|
},
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [],
|
|
"metadata": {
|
|
"id": "YJUHCXqK57yz"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## Giới thiệu về Hồi quy - Bài học 1\n",
|
|
"\n",
|
|
"#### Đặt vấn đề vào bối cảnh\n",
|
|
"\n",
|
|
"✅ Có nhiều phương pháp hồi quy khác nhau, và việc bạn chọn phương pháp nào phụ thuộc vào câu trả lời mà bạn đang tìm kiếm. Nếu bạn muốn dự đoán chiều cao có thể xảy ra của một người ở một độ tuổi nhất định, bạn sẽ sử dụng `hồi quy tuyến tính`, vì bạn đang tìm kiếm một **giá trị số**. Nếu bạn muốn khám phá liệu một loại ẩm thực có nên được coi là thuần chay hay không, bạn đang tìm kiếm một **phân loại danh mục**, vì vậy bạn sẽ sử dụng `hồi quy logistic`. Bạn sẽ học thêm về hồi quy logistic sau này. Hãy suy nghĩ một chút về một số câu hỏi bạn có thể đặt ra với dữ liệu, và phương pháp nào trong số này sẽ phù hợp hơn.\n",
|
|
"\n",
|
|
"Trong phần này, bạn sẽ làm việc với [một tập dữ liệu nhỏ về bệnh tiểu đường](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html). Hãy tưởng tượng rằng bạn muốn thử nghiệm một phương pháp điều trị cho bệnh nhân tiểu đường. Các mô hình Machine Learning có thể giúp bạn xác định bệnh nhân nào sẽ phản ứng tốt hơn với phương pháp điều trị, dựa trên sự kết hợp của các biến số. Ngay cả một mô hình hồi quy rất cơ bản, khi được trực quan hóa, cũng có thể cho thấy thông tin về các biến số giúp bạn tổ chức các thử nghiệm lâm sàng lý thuyết của mình.\n",
|
|
"\n",
|
|
"Vậy thì, hãy bắt đầu nhiệm vụ này nhé!\n",
|
|
"\n",
|
|
"<p >\n",
|
|
" <img src=\"../../images/encouRage.jpg\"\n",
|
|
" width=\"630\"/>\n",
|
|
" <figcaption>Tác phẩm nghệ thuật của @allison_horst</figcaption>\n",
|
|
"\n",
|
|
"<!--<br>Tác phẩm nghệ thuật của @allison_horst-->\n"
|
|
],
|
|
"metadata": {
|
|
"id": "LWNNzfqd6feZ"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 1. Tải bộ công cụ của chúng ta\n",
|
|
"\n",
|
|
"Để thực hiện nhiệm vụ 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 trở nên nhanh hơn, dễ dàng hơn và thú vị hơn!\n",
|
|
"\n",
|
|
"- `tidymodels`: [tidymodels](https://www.tidymodels.org/) là một [bộ sưu tập các gói](https://www.tidymodels.org/packages/) dành cho mô hình hóa và học máy.\n",
|
|
"\n",
|
|
"Bạn có thể cài đặt chúng bằng lệnh sau:\n",
|
|
"\n",
|
|
"`install.packages(c(\"tidyverse\", \"tidymodels\"))`\n",
|
|
"\n",
|
|
"Đ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 mô-đun này chưa và sẽ cài đặt chúng cho bạn nếu thiếu.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "FIo2YhO26wI9"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"source": [
|
|
"suppressWarnings(if(!require(\"pacman\")) install.packages(\"pacman\"))\n",
|
|
"pacman::p_load(tidyverse, tidymodels)"
|
|
],
|
|
"outputs": [
|
|
{
|
|
"output_type": "stream",
|
|
"name": "stderr",
|
|
"text": [
|
|
"Loading required package: pacman\n",
|
|
"\n"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"id": "cIA9fz9v7Dss",
|
|
"colab": {
|
|
"base_uri": "https://localhost:8080/"
|
|
},
|
|
"outputId": "2df7073b-86b2-4b32-cb86-0da605a0dc11"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Bây giờ, hãy tải các gói tuyệt vời này và làm cho chúng khả dụng trong phiên làm việc R hiện tại của chúng ta. (Đây chỉ là minh họa, `pacman::p_load()` đã làm điều đó cho bạn)\n"
|
|
],
|
|
"metadata": {
|
|
"id": "gpO_P_6f9WUG"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# load the core Tidyverse packages\r\n",
|
|
"library(tidyverse)\r\n",
|
|
"\r\n",
|
|
"# load the core Tidymodels packages\r\n",
|
|
"library(tidymodels)\r\n"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "NLMycgG-9ezO"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 2. Bộ dữ liệu tiểu đường\n",
|
|
"\n",
|
|
"Trong bài tập này, chúng ta sẽ áp dụng kỹ năng hồi quy bằng cách dự đoán trên bộ dữ liệu tiểu đường. [Bộ dữ liệu tiểu đường](https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt) bao gồm `442 mẫu` dữ liệu liên quan đến bệnh tiểu đường, với 10 biến đặc trưng dự đoán: `tuổi`, `giới tính`, `chỉ số khối cơ thể`, `huyết áp trung bình`, và `sáu phép đo huyết thanh máu`, cùng với một biến kết quả `y`: một thước đo định lượng về mức độ tiến triển của bệnh sau một năm kể từ thời điểm ban đầu.\n",
|
|
"\n",
|
|
"|Số lượng quan sát|442|\n",
|
|
"|------------------|:---|\n",
|
|
"|Số lượng biến dự đoán|10 cột đầu tiên là các biến dự đoán dạng số|\n",
|
|
"|Kết quả/Mục tiêu|Cột thứ 11 là thước đo định lượng về mức độ tiến triển của bệnh sau một năm kể từ thời điểm ban đầu|\n",
|
|
"|Thông tin về biến dự đoán|- tuổi tính theo năm\n",
|
|
"||- giới tính\n",
|
|
"||- bmi chỉ số khối cơ thể\n",
|
|
"||- bp huyết áp trung bình\n",
|
|
"||- s1 tc, tổng cholesterol trong huyết thanh\n",
|
|
"||- s2 ldl, lipoprotein mật độ thấp\n",
|
|
"||- s3 hdl, lipoprotein mật độ cao\n",
|
|
"||- s4 tch, tổng cholesterol / HDL\n",
|
|
"||- s5 ltg, có thể là logarit của mức triglycerides trong huyết thanh\n",
|
|
"||- s6 glu, mức đường trong máu|\n",
|
|
"\n",
|
|
"> 🎓 Hãy nhớ rằng đây là học có giám sát, và chúng ta cần một mục tiêu 'y' được đặt tên.\n",
|
|
"\n",
|
|
"Trước khi bạn có thể thao tác dữ liệu với R, bạn cần nhập dữ liệu vào bộ nhớ của R hoặc tạo một kết nối để R có thể truy cập dữ liệu từ xa.\n",
|
|
"\n",
|
|
"> Gói [readr](https://readr.tidyverse.org/), một phần của Tidyverse, cung cấp cách nhanh chóng và thân thiện để đọc dữ liệu dạng hình chữ nhật vào R.\n",
|
|
"\n",
|
|
"Bây giờ, hãy tải bộ dữ liệu tiểu đường từ URL nguồn này: <https://www4.stat.ncsu.edu/~boos/var.select/diabetes.html>\n",
|
|
"\n",
|
|
"Ngoài ra, chúng ta sẽ kiểm tra dữ liệu bằng cách sử dụng `glimpse()` và hiển thị 5 hàng đầu tiên bằng `slice()`.\n",
|
|
"\n",
|
|
"Trước khi tiếp tục, hãy giới thiệu một điều mà bạn sẽ thường xuyên gặp trong mã R 🥁🥁: toán tử pipe `%>%`\n",
|
|
"\n",
|
|
"Toán tử pipe (`%>%`) thực hiện các thao tác theo trình tự logic bằng cách chuyển một đối tượng vào một hàm hoặc biểu thức gọi. Bạn có thể nghĩ toán tử pipe như đang nói \"và sau đó\" trong mã của bạn.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "KM6iXLH996Cl"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Import the data set\r\n",
|
|
"diabetes <- read_table2(file = \"https://www4.stat.ncsu.edu/~boos/var.select/diabetes.rwrite1.txt\")\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Get a glimpse and dimensions of the data\r\n",
|
|
"glimpse(diabetes)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Select the first 5 rows of the data\r\n",
|
|
"diabetes %>% \r\n",
|
|
" slice(1:5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "Z1geAMhM-bSP"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"`glimpse()` cho chúng ta thấy rằng dữ liệu này có 442 hàng và 11 cột, với tất cả các cột đều thuộc kiểu dữ liệu `double`.\n",
|
|
"\n",
|
|
"<br>\n",
|
|
"\n",
|
|
"> glimpse() và slice() là các hàm trong [`dplyr`](https://dplyr.tidyverse.org/). Dplyr, một phần của Tidyverse, là một ngữ pháp thao tác dữ liệu cung cấp một tập hợp các động từ nhất quán giúp bạn giải quyết các thách thức phổ biến trong việc thao tác dữ liệu.\n",
|
|
"\n",
|
|
"<br>\n",
|
|
"\n",
|
|
"Bây giờ chúng ta đã có dữ liệu, hãy thu hẹp lại một đặc điểm (`bmi`) để làm mục tiêu cho bài tập này. Điều này sẽ yêu cầu chúng ta chọn các cột mong muốn. Vậy làm thế nào để thực hiện điều này?\n",
|
|
"\n",
|
|
"[`dplyr::select()`](https://dplyr.tidyverse.org/reference/select.html) cho phép chúng ta *chọn* (và tùy chọn đổi tên) các cột trong một khung dữ liệu.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "UwjVT1Hz-c3Z"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Select predictor feature `bmi` and outcome `y`\r\n",
|
|
"diabetes_select <- diabetes %>% \r\n",
|
|
" select(c(bmi, y))\r\n",
|
|
"\r\n",
|
|
"# Print the first 5 rows\r\n",
|
|
"diabetes_select %>% \r\n",
|
|
" slice(1:10)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "RDY1oAKI-m80"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 3. Dữ liệu huấn luyện và kiểm tra\n",
|
|
"\n",
|
|
"Trong học máy có giám sát, việc *chia* dữ liệu thành hai tập hợp là một thực hành phổ biến; một tập (thường lớn hơn) để huấn luyện mô hình, và một tập nhỏ hơn \"giữ lại\" để kiểm tra xem mô hình hoạt động như thế nào.\n",
|
|
"\n",
|
|
"Bây giờ chúng ta đã có dữ liệu sẵn sàng, chúng ta có thể xem liệu máy có thể giúp xác định một cách chia hợp lý giữa các số trong tập dữ liệu này hay không. Chúng ta có thể sử dụng gói [rsample](https://tidymodels.github.io/rsample/), một phần của khung làm việc Tidymodels, để tạo một đối tượng chứa thông tin về *cách* chia dữ liệu, và sau đó sử dụng hai hàm rsample khác để trích xuất các tập huấn luyện và kiểm tra đã được tạo:\n"
|
|
],
|
|
"metadata": {
|
|
"id": "SDk668xK-tc3"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"set.seed(2056)\r\n",
|
|
"# Split 67% of the data for training and the rest for tesing\r\n",
|
|
"diabetes_split <- diabetes_select %>% \r\n",
|
|
" initial_split(prop = 0.67)\r\n",
|
|
"\r\n",
|
|
"# Extract the resulting train and test sets\r\n",
|
|
"diabetes_train <- training(diabetes_split)\r\n",
|
|
"diabetes_test <- testing(diabetes_split)\r\n",
|
|
"\r\n",
|
|
"# Print the first 3 rows of the training set\r\n",
|
|
"diabetes_train %>% \r\n",
|
|
" slice(1:10)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "EqtHx129-1h-"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 4. Huấn luyện mô hình hồi quy tuyến tính với Tidymodels\n",
|
|
"\n",
|
|
"Bây giờ chúng ta đã sẵn sàng để huấn luyện mô hình!\n",
|
|
"\n",
|
|
"Trong Tidymodels, bạn định nghĩa mô hình bằng cách sử dụng `parsnip()` và chỉ định ba khái niệm:\n",
|
|
"\n",
|
|
"- **Loại mô hình** phân biệt các mô hình như hồi quy tuyến tính, hồi quy logistic, mô hình cây quyết định, và nhiều loại khác.\n",
|
|
"\n",
|
|
"- **Chế độ mô hình** bao gồm các tùy chọn phổ biến như hồi quy và phân loại; một số loại mô hình hỗ trợ cả hai chế độ này, trong khi một số chỉ có một chế độ duy nhất.\n",
|
|
"\n",
|
|
"- **Công cụ mô hình** là công cụ tính toán sẽ được sử dụng để khớp mô hình. Thường thì đây là các gói R, chẳng hạn như **`\"lm\"`** hoặc **`\"ranger\"`**\n",
|
|
"\n",
|
|
"Thông tin về mô hình này được lưu trong một đặc tả mô hình, vì vậy hãy cùng xây dựng một đặc tả!\n"
|
|
],
|
|
"metadata": {
|
|
"id": "sBOS-XhB-6v7"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Build a linear model specification\r\n",
|
|
"lm_spec <- \r\n",
|
|
" # Type\r\n",
|
|
" linear_reg() %>% \r\n",
|
|
" # Engine\r\n",
|
|
" set_engine(\"lm\") %>% \r\n",
|
|
" # Mode\r\n",
|
|
" set_mode(\"regression\")\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Print the model specification\r\n",
|
|
"lm_spec"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "20OwEw20--t3"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Sau khi một mô hình đã được *xác định*, mô hình có thể được `ước lượng` hoặc `huấn luyện` bằng cách sử dụng hàm [`fit()`](https://parsnip.tidymodels.org/reference/fit.html), thường sử dụng một công thức và một số dữ liệu.\n",
|
|
"\n",
|
|
"`y ~ .` có nghĩa là chúng ta sẽ khớp `y` làm giá trị dự đoán/mục tiêu, được giải thích bởi tất cả các biến dự đoán/đặc trưng, tức là `.` (trong trường hợp này, chúng ta chỉ có một biến dự đoán: `bmi`).\n"
|
|
],
|
|
"metadata": {
|
|
"id": "_oDHs89k_CJj"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Build a linear model specification\r\n",
|
|
"lm_spec <- linear_reg() %>% \r\n",
|
|
" set_engine(\"lm\") %>%\r\n",
|
|
" set_mode(\"regression\")\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"# Train a linear regression model\r\n",
|
|
"lm_mod <- lm_spec %>% \r\n",
|
|
" fit(y ~ ., data = diabetes_train)\r\n",
|
|
"\r\n",
|
|
"# Print the model\r\n",
|
|
"lm_mod"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "YlsHqd-q_GJQ"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Từ kết quả đầu ra của mô hình, chúng ta có thể thấy các hệ số được học trong quá trình huấn luyện. Chúng đại diện cho các hệ số của đường hồi quy tốt nhất, giúp giảm thiểu tổng lỗi giữa biến thực tế và biến dự đoán.\n",
|
|
"\n",
|
|
"<br>\n",
|
|
"\n",
|
|
"## 5. Dự đoán trên tập kiểm tra\n",
|
|
"\n",
|
|
"Bây giờ chúng ta đã huấn luyện xong một mô hình, chúng ta có thể sử dụng nó để dự đoán sự tiến triển của bệnh y cho tập dữ liệu kiểm tra bằng [parsnip::predict()](https://parsnip.tidymodels.org/reference/predict.model_fit.html). Điều này sẽ được sử dụng để vẽ đường phân cách giữa các nhóm dữ liệu.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "kGZ22RQj_Olu"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Make predictions for the test set\r\n",
|
|
"predictions <- lm_mod %>% \r\n",
|
|
" predict(new_data = diabetes_test)\r\n",
|
|
"\r\n",
|
|
"# Print out some of the predictions\r\n",
|
|
"predictions %>% \r\n",
|
|
" slice(1:5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "nXHbY7M2_aao"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"Woohoo! 💃🕺 Chúng ta vừa huấn luyện một mô hình và sử dụng nó để tạo dự đoán!\n",
|
|
"\n",
|
|
"Khi tạo dự đoán, quy ước của tidymodels luôn là tạo ra một tibble/data frame kết quả với các tên cột được chuẩn hóa. Điều này giúp dễ dàng kết hợp dữ liệu gốc và các dự đoán trong một định dạng có thể sử dụng cho các thao tác tiếp theo như vẽ biểu đồ.\n",
|
|
"\n",
|
|
"`dplyr::bind_cols()` kết hợp các data frame theo cột một cách hiệu quả.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "R_JstwUY_bIs"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Combine the predictions and the original test set\r\n",
|
|
"results <- diabetes_test %>% \r\n",
|
|
" bind_cols(predictions)\r\n",
|
|
"\r\n",
|
|
"\r\n",
|
|
"results %>% \r\n",
|
|
" slice(1:5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "RybsMJR7_iI8"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"## 6. Hiển thị kết quả mô hình\n",
|
|
"\n",
|
|
"Bây giờ, đã đến lúc xem kết quả một cách trực quan 📈. Chúng ta sẽ tạo một biểu đồ phân tán cho tất cả các giá trị `y` và `bmi` của tập kiểm tra, sau đó sử dụng các dự đoán để vẽ một đường ở vị trí phù hợp nhất, giữa các nhóm dữ liệu của mô hình.\n",
|
|
"\n",
|
|
"R có nhiều hệ thống để tạo biểu đồ, nhưng `ggplot2` là một trong những hệ thống thanh lịch và linh hoạt nhất. Điều này cho phép bạn tạo biểu đồ bằng cách **kết hợp các thành phần độc lập**.\n"
|
|
],
|
|
"metadata": {
|
|
"id": "XJbYbMZW_n_s"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"source": [
|
|
"# Set a theme for the plot\r\n",
|
|
"theme_set(theme_light())\r\n",
|
|
"# Create a scatter plot\r\n",
|
|
"results %>% \r\n",
|
|
" ggplot(aes(x = bmi)) +\r\n",
|
|
" # Add a scatter plot\r\n",
|
|
" geom_point(aes(y = y), size = 1.6) +\r\n",
|
|
" # Add a line plot\r\n",
|
|
" geom_line(aes(y = .pred), color = \"blue\", size = 1.5)"
|
|
],
|
|
"outputs": [],
|
|
"metadata": {
|
|
"id": "R9tYp3VW_sTn"
|
|
}
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"source": [
|
|
"✅ Hãy suy nghĩ một chút về điều đang diễn ra ở đây. Một đường thẳng đang chạy qua nhiều điểm dữ liệu nhỏ, nhưng nó thực sự đang làm gì? Bạn có thấy cách mà bạn có thể sử dụng đường này để dự đoán vị trí của một điểm dữ liệu mới, chưa được thấy trước đó, trong mối quan hệ với trục y của biểu đồ không? Hãy thử diễn đạt bằng lời về ứng dụng thực tế của mô hình này.\n",
|
|
"\n",
|
|
"Chúc mừng bạn, bạn đã xây dựng mô hình hồi quy tuyến tính đầu tiên, tạo ra một dự đoán từ nó, và hiển thị nó trên biểu đồ!\n"
|
|
],
|
|
"metadata": {
|
|
"id": "zrPtHIxx_tNI"
|
|
}
|
|
},
|
|
{
|
|
"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 tham khảo chính thức. Đối với các thông tin quan trọng, chúng tôi khuyến nghị sử dụng dịch vụ dịch thuật chuyên nghiệp từ 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"
|
|
]
|
|
}
|
|
]
|
|
} |