{ "cells": [ { "cell_type": "markdown", "id": "a4977c16", "metadata": {}, "source": [ "(sec_one_hot)=\n", "# Mã hóa one-hot\n", "\n", "Cách truyền thống nhất để đưa dữ liệu hạng mục về dạng số là mã hóa one-hot. Trong cách mã hóa này, một \"từ điển\" cần được xây dựng chứa tất cả các giá trị khả dĩ của từng dữ liệu hạng mục. Sau đó mỗi giá trị hạng mục sẽ được mã hóa bằng một vector nhị phân với toàn bộ các phần tử bằng 0 trừ một phần tử bằng 1 tương ứng với vị trí của giá trị hạng mục đó trong từ điển.\n", "\n", "Ví dụ, nếu ta có dữ liệu một cột là `\"Sài Gòn\", \"Huế\", \"Hà Nội\"` thì ta thực hiện các bước sau:\n", "\n", "1. Xây dựng từ điển. Trong trường hợp này ta có thể xây dựng từ điển là `[\"Hà Nội\", \"Huế\", \"Sài Gòn\"]`\n", "\n", "2. Sau khi xây dựng được từ điển ta cần lưu lại chỉ số của từng hạng mục trong từ điển. Với từ điển như trên, chỉ số tương ứng là `\"Hà Nội\": 0, \"Huế\": 1, \"Sài Gòn\": 2`.\n", "\n", "3. Cuối cùng, ta mã hóa các giá trị ban đầu như sau:\n", "\n", "Với từ điền thứ nhất:\n", "\n", "| Giá trị | Mã one-hot |\n", "| --- | --- |\n", "| `\"Sài Gòn\"` | `[0, 0, 1]` |\n", "| `\"Huế\"` | `[0, 1, 0]`|\n", "|`\"Hà Nội\"` | `[1, 0, 0]`|\n", "\n", "\n", "Vì mỗi giá trị hạng mục được mã hóa bằng một vector với chỉ một phần tử bằng 1 tại vị trí tương ứng của nó trong từ điển nên vector này được gọi là \"one-hot vector\". Số chiều của vector này đúng bằng số từ trong từ điển. Diễn giải theo một cách khác, mỗi giá trị nhị phân trong vector này thể hiện việc giá trị hạng mục đang xét \"có phải là\" giá trị tương ứng trong từ điển không. Với các giá trị mới không nằm trong từ điển (_out-of-vocabolary hay OOV_), ta có thể mã hóa chúng thành `[0, 0, 0]` theo nghĩa chúng không phải là bất cứ một giá trị nào trong từ điển.\n", "\n", "Có một cách khác phổ biến để mã hóa các giá trị không có trong từ điển là thêm từ `\"unknown\"` vào trong từ điển và tất cả những giá trị mới được xếp vào mục `\"unknown\"` này. Cần lưu ý khi `\"unknown\"` cũng là một giá trị khả dĩ trong tập dữ liệu. Việc mã hóa các giá trị chưa biết bằng cùng một vector có thể gây cho mô hình nhầm lẫn rằng đây là hai giá trị giống nhau. Nếu bằng một cách nào đó, bạn biết các giá trị này xuất hiện nhiều trong tương lai, bạn nên đưa chúng vào trong từ điển một cách cụ thể để có cách mã hóa riêng, tránh trùng lặp với các giá trị khác. Nếu các giá trị này hiếm khi xảy ra, ta có thể cho chung vào một mã và coi như chúng có tính chất giống nhau là \"hiếm\". Cố gắng mã hóa cho từng giá trị hiếm sẽ dẫn đến tình trạng phải dùng nhiều bộ nhớ và mô hình cũng phức tạp hơn để cố gắng học những trường hợp cá biệt, khi đó overfitting dễ xảy ra.\n", "\n", "## Ví dụ với sklearn\n", "\n", "Dưới đây là một ví dụ về việc mã hóa one-hot sử dụng\n", "[`sklearn.preprocessing.OneHotEncoder`](https://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html#sklearn-preprocessing-onehotencoder). Trước tiên," ] }, { "cell_type": "code", "execution_count": 1, "id": "02f62956", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " | location | \n", "population (M) | \n", "
---|---|---|
0 | \n", "Hà Nội | \n", "7.0 | \n", "
1 | \n", "Huế | \n", "9.0 | \n", "
2 | \n", "Sài Gòn | \n", "0.5 | \n", "