[SWE học A.I] Phần 4: Data Prepare & Cleaning

[SWE học A.I] Phần 4: Data Prepare & Cleaning
Bài viết là bài thứ 4 trong 7 bài tại series SWE Học A.I

Các thuật toán học máy (machine learning), học sâu (deep learning) dù cao cấp, hiện đại đến đâu, nhưng chúng vẫn phụ thuộc rất nhiều vào dữ liệu chất lượng cao. Trong thực tế, có rất nhiều dữ liệu đến từ các cảm biến (cảm biến độ ẩm, nhiệt độ, cảm biến trên ô tô, …) và chúng không tránh khỏi việc bị nhiễu, hay dữ liệu hồ sơ từ bệnh viện, cơ quan hành chính, … nơi có khả năng xảy ra các vấn đề như ghi chép sai, …. Vì vậy, việc chuẩn bị và làm sạch dữ liệu trước khi bắt đầu quá trình huấn luyện là cần thiết.

Một loạt các phương pháp đã được phát triển để phục vụ công việc này, được gọi là kỹ thuật chuẩn bị dữ liệu (data preparation) hoặc làm sạch dữ liệu (data cleaning). Ý tưởng là xử lý dữ liệu trước khi đưa vào huấn luyện, để các hệ thống học máy có thể khai thác dữ liệu một cách hiệu quả nhất.

Data Cleaning

Xử lý dữ liệu dạng văn bản

Nếu dữ liệu ở dạng văn bản, chúng ta cần đảm bảo không có lỗi chính tả, ký tự không in được,…..

Ví dụ, nếu chúng ta có một bộ sưu tập ảnh động vật kèm theo tệp văn bản mô tả, và hệ thống phân biệt chữ hoa chữ thường, thì mọi con hươu cao cổ phải được gắn nhãn là “hươu cao cổ” chứ không phải “hươu cao cô” hay “Hươu Cao Cổ”. Chúng ta cũng cần tránh các biến thể như “hươu cao cổ đẹp” hay “hươu cao cổ siêu cao”. Mỗi tham chiếu đến hươu cao cổ phải sử dụng chuỗi ký tự giống hệt nhau.

Ví dụ minh họa: Giả sử chúng ta có một danh sách nhãn sau:

  • hươu cao cổ
  • hươu cao cô
  • Hươu Cao Cổ
  • hươu cao cổ đẹp

Thách thức:

  • Xử lý lỗi chính tả và biến thể ngôn ngữ.
  • Loại bỏ từ bổ nghĩa hoặc cụm từ không cần thiết.
  • Đảm bảo tính nhất quán trong toàn bộ tập dữ liệu.

Để xử lý bài toán này, có thể kể tới 1 số kĩ thuật như stemming, lemmatization.

Stemming

Định nghĩa: Stemming là kỹ thuật giảm một từ về dạng gốc (stem) bằng cách loại bỏ các hậu tố (suffixes) như “-s”, “-es”, “-ed”, hoặc “-ing” (trong tiếng Anh). Trong tiếng Việt, stemming ít phổ biến hơn do ngôn ngữ không có nhiều biến thể hậu tố, nhưng vẫn có thể áp dụng cho các từ ghép hoặc cụm từ

Stemming có nhiều thuật toán khác nhau, chủ yếu được phát triển cho các ngôn ngữ giàu hình thái học như tiếng Anh.

  1. Porter Stemmer
    • Cách hoạt động:
      • B1: Loại bỏ hậu tố số nhiều (“-s”, “-es”).
      • B2: Xử lý hậu tố “-ing”, “-ed” (ví dụ: “running” → “run”, “played” → “play”).
      • B3-B5: Xử lý các hậu tố phức tạp hơn như “-ational” → “-ate” (ví dụ: “operational” → “operate”).
    • Ưu điểm:
      • Hiệu quả, nhanh, được tối ưu hóa cho tiếng Anh.
      • Không cần từ điển, dựa hoàn toàn trên quy tắc.
    • Nhược điểm:
      • Quá tích cực (over-stemming), có thể tạo ra dạng gốc không có nghĩa (ví dụ: “happiness” → “happi”).
      • Không phù hợp với các ngôn ngữ ít biến thể hình thái như tiếng Việt.
  2. Snowball Stemmer
    • Cách hoạt động:
      • Tương tự Porter, nhưng có thêm các quy tắc tùy chỉnh cho từng ngôn ngữ.
        • Cụ thể, Porter đã được fix cứng các kĩ thuật dữ liệu. Ở Snowball Stemmer, hay Porter2, ta có thể tuỳ chỉnh tập quy tắc này (https://snowballstem.org/texts/introduction.html)
      • Ví dụ: Trong tiếng Anh, “studies” → “studi” (Porter) nhưng Snowball có thể giữ nguyên “study” nếu được tối ưu hóa.
    • Ưu điểm:
      • Linh hoạt, hỗ trợ đa ngôn ngữ.
      • Dễ tùy chỉnh cho các ngôn ngữ mới.
    • Nhược điểm:
      • Vẫn có thể over-stemming hoặc under-stemming (giữ quá nhiều hậu tố).
      • Yêu cầu kiến thức ngôn ngữ học để tạo quy tắc cho tiếng Việt.
  3. Lancaster Stemmer
    • Mô tả: Là thuật toán stemming mạnh mẽ hơn Porter, tập trung vào loại bỏ nhiều hậu tố nhất có thể. Nó được thiết kế để tạo ra dạng gốc ngắn nhất.
    • Cách hoạt động:
      • Áp dụng các quy tắc lặp đi lặp lại để cắt bỏ hậu tố, ví dụ: “happiness” → “happ”. Với Porter, ta đi qua các quy tắc theo thứ tự 1,2,3, … để xử lý. Còn Lancaster sẽ lặp lại liên tục để kiểm tra còn cắt được không
      • Có xu hướng cắt bỏ nhiều hơn Porter, dẫn đến dạng gốc rất ngắn.
    • Ưu điểm:
      • Tạo ra dạng gốc rất gọn, giảm kích thước từ vựng.
    • Nhược điểm:
      • Quá tích cực, thường tạo ra dạng gốc không có nghĩa (over-stemming nghiêm trọng).
      • Không phù hợp cho các ứng dụng yêu cầu ngữ nghĩa rõ ràng.
  4. Regex-based Stemming (Tùy chỉnh)
    • Mô tả: Sử dụng các biểu thức chính quy (regular expressions) để loại bỏ các hậu tố hoặc từ bổ nghĩa theo quy tắc do người dùng định nghĩa. Phù hợp cho các ngôn ngữ như tiếng Việt, nơi không có nhiều hậu tố hình thái học.
    • Cách hoạt động:
      • Xác định các mẫu từ bổ nghĩa (ví dụ: “đẹp”, “siêu cao” trong tiếng Việt).
      • Loại bỏ các mẫu này bằng regex hoặc danh sách từ dừng (stop words).
    • Ưu điểm:
      • Linh hoạt, dễ tùy chỉnh cho tiếng Việt.
      • Không cần từ điển, phù hợp cho các ứng dụng đơn giản.
    • Nhược điểm:
      • Yêu cầu xây dựng quy tắc thủ công.
      • Không xử lý tốt các biến thể phức tạp hoặc ngữ cảnh.
Python
import re
text = "sản phẩm này rất đẹp và cực kỳ tốt"
cleaned = re.sub(r"\b(rất|cực kỳ|quá|hơi|khá|tương đối)\b", "", text)
print(cleaned)
# -> sản phẩm này  đẹp và  tốt (Ví dụ 1 cách triển khai regex)

Kỹ thuậtĐộ chính xácTốc độNguy cơ Over-stemming
Porter StemmerTrung bìnhNhanhTrung bình
Snowball StemmerTrung bình-caoNhanhTrung bình
Lancaster StemmerThấpRất nhanhCao
Regex-basedCao (nếu tùy chỉnh tốt)NhanhThấp
Lemmatization

Lemmatization là quá trình đưa một từ hoặc cụm từ về dạng gốc (lemma) dựa trên từ điển và ngữ cảnh, đảm bảo dạng gốc có nghĩa. Không như stemming, lemmatization yêu cầu phân tích ngữ pháp và ngữ nghĩa, thường sử dụng từ điển ngôn ngữ học.

Tokenizatio

Tokenization là quá trình chia nhỏ văn bản thành các đơn vị nhỏ hơn gọi là token (thường là từ, dấu câu, cụm từ). Ví dụ:

Python
from nltk.tokenize import word_tokenize
text = "The cats are running fast."
print(word_tokenize(text))  # ['The', 'cats', 'are', 'running', 'fast', '.']

POS Tagging

POS (Part-of-Speech) Tagging là quá trình gán loại từ cho mỗi token: danh từ (NN), động từ (VB), tính từ (JJ),

Ví dụ:

Python
from nltk import pos_tag
tokens = ['running', 'fast']
print(pos_tag(tokens))  # [('running', 'VBG'), ('fast', 'RB')]

A. Dictionary-based Lemmatization

Sử dụng từ điển để ánh xạ từng từ về dạng gốc. Một trong các công cụ phổ biến là WordNetLemmatizer của NLTK. WordNetLemmatizer là một bộ lemmatizer sử dụng WordNet – cơ sở dữ liệu ngôn ngữ học lớn nhất tiếng Anh. WordNet ánh xạ các từ về nghĩa gốc dựa vào loại từ.

  1. Tokenization: tách từ.
  2. POS Tagging: xác định loại từ.
  3. Ánh xạ về lemma bằng từ điển
Python
from nltk.stem import WordNetLemmatizer
from nltk.corpus import wordnet

def get_wordnet_pos(treebank_tag):
    if treebank_tag.startswith('J'):
        return wordnet.ADJ
    elif treebank_tag.startswith('V'):
        return wordnet.VERB
    elif treebank_tag.startswith('N'):
        return wordnet.NOUN
    elif treebank_tag.startswith('R'):
        return wordnet.ADV
    return wordnet.NOUN  # default fallback

lemmatizer = WordNetLemmatizer()
tokens = word_tokenize("The leaves are falling from the trees")
tagged = pos_tag(tokens)
lemmatized = [lemmatizer.lemmatize(word, get_wordnet_pos(pos)) for word, pos in tagged]
print(lemmatized)
# ['The', 'leaf', 'be', 'fall', 'from', 'the', 'tree']

Ưu điểm:

  • Độ chính xác cao nếu loại từ được xác định đúng.
  • Giữ nguyên nghĩa và phù hợp cho xử lý ngữ nghĩa.

Nhược điểm:

  • Yêu cầu từ điển đầy đủ cho ngôn ngữ.
  • Không xử lý tốt ngữ cảnh rộng.

B. Rule-based Lemmatization

Kết hợp từ điển và quy tắc để xử lý cả từ có quy tắc và bất quy tắc. Thường được dùng trong ngôn ngữ học tính toán truyền thống.

  1. Áp dụng POS tagging.
  2. Nếu từ là bất quy tắc, tra từ điển đặc biệt.
  3. Nếu không, áp dụng quy tắc ngữ pháp để ánh xạ về lemma.

Ví dụ:

  • “went” → “go”
  • “better” → “good” (khi là tính từ so sánh)
Python
def custom_rule_based_lemmatize(word, pos):
    irregular = {'went': 'go', 'better': 'good'}
    if word in irregular:
        return irregular[word]
    if pos.startswith('V') and word.endswith('ing'):
        return word[:-3]
    return word

print(custom_rule_based_lemmatize("running", "VBG"))  # run
print(custom_rule_based_lemmatize("went", "VBD"))     # go

Ưu điểm:

  • Kiểm soát tốt, dễ tùy chỉnh.
  • Xử lý chính xác từ bất quy tắc.

Nhược điểm:

  • Phức tạp khi số lượng quy tắc nhiều.

C. Statistical / Neural Lemmatization

Sử dụng học máy/học sâu để học ánh xạ từ về lemma dựa trên ngữ cảnh. Có thể dùng mô hình như:

  • RNN, LSTM
  • Transformer (ví dụ: BERT, PhoBERT)
  • Sequence-to-sequence với attention
  1. Huấn luyện mô hình trên tập dữ liệu có gán nhãn word → lemma.
  2. Đầu vào là câu văn (hoặc đoạn văn).
  3. Mô hình dự đoán lemma cho từng từ dựa vào ngữ cảnh.

Trong spaCy:

Python
import spacy
nlp = spacy.load("en_core_web_sm")
doc = nlp("She was running very fast")
print([(token.text, token.lemma_) for token in doc])
# [('She', 'she'), ('was', 'be'), ('running', 'run'), ('very', 'very'), ('fast', 'fast')]
Tổng kết

Nhìn chung có thể hiểu đơn giản như sau:

  • Stemming: Một cách làm nhanh, sử dụng các quy tắc, sử dụng logic để cắt từ giúp đưa về từ chuẩn hoá. Ví dụ cắt go-ing -> go, study-ing -> study
  • Lemmezation: Một cách làm thường chậm hơn Stemming, nhưng có thể hiểu ngữ nghĩa, có thể xử lý các từ như best, better -> good

Kiểm tra lỗi nhập liệu

Chúng ta cần phát hiện các lỗi như thiếu dấu thập phân (ví dụ: 1,000 thay vì 1.000) hoặc nhập sai dấu (ví dụ: –1 thay vì -1). Điều này thường xảy ra trong các dữ liệu tiền tệ, 1,500$ khác hẳn 1.500$ (1 nghìn 500 trăm đô và 1 đô la rưỡi). Hay đôi khi khi đo đạc thời tiết, nếu hôm đó cảm biến hỏng không đo được, người ta để dữ liệu là NaN, là rỗng, là số 0, hoặc -1, ….

Nếu tập dữ liệu về nhiệt độ có giá trị NaN hoặc 0 thay vì nhiệt độ thực. Nếu không sửa, thuật toán có thể hiểu nhầm rằng nhiệt độ bằng 0°C là hợp lệ, dẫn đến dự đoán sai và bị chịu ảnh hưởng rất nhiều (Nó thấy thời tiết đang 40 độ chuyển thành 0 độ rồi lại lên 40 độ). Chúng ta có thể xử lý bằng cách:

Python
import numpy as np
data = pd.Series([25.5, np.nan, 0, 30.2])
data = data.replace(0, np.nan)  # Thay 0 bằng NaN
data = data.fillna(data.mean())  # Điền NaN thành giá trị trung bình

Chuẩn hóa định dạng

Dữ liệu cần được định dạng sao cho phần mềm có thể hiểu đúng. Ví dụ, ký hiệu khoa học (scientific notation) như 7e-3 (0.007) có thể bị một số chương trình hiểu nhầm là (7 × e) – 3, với e là hằng số Euler (~2.7), dẫn đến giá trị khoảng 16 thay vì 0.007. Chúng ta cần kiểm tra và chuẩn hóa định dạng này.

Để đảm bảo tính nhất quán, chúng ta có thể chuyển tất cả các số về dạng thập phân:

Python
value = "7e-3"
corrected_value = float(value)  # Chuyển thành 0.007

Xử lý dữ liệu thiếu

Nếu một mẫu thiếu dữ liệu cho một hoặc nhiều đặc trưng, chúng ta có thể:

  • Điền giá trị thủ công hoặc bằng thuật toán (ví dụ: sử dụng giá trị trung bình).
  • Loại bỏ mẫu đó nếu không thể khôi phục.

Quyết định này phụ thuộc vào bối cảnh cụ thể. Ví dụ, trong một tập dữ liệu y tế, nếu thiếu giá trị huyết áp, việc điền giá trị trung bình có thể không chính xác, và loại bỏ mẫu có thể là lựa chọn tốt hơn.

Các Loại Dữ liệu

Cơ sở dữ liệu thường chứa nhiều loại dữ liệu khác nhau: số thực, chuỗi, số nguyên đại diện cho danh mục, v.v. Mỗi loại dữ liệu cần được xử lý theo cách riêng.

Dữ liệu Số (Numerical Data)

Dữ liệu số là các giá trị số, có thể là số thực (floating-point) hoặc số nguyên (integer), còn được gọi là dữ liệu định lượng (quantitative data). Dữ liệu này có thể được sắp xếp trực tiếp dựa trên giá trị.

Ví dụ: Nhiệt độ (25.5°C, 30.2°C), chiều cao (1.75m, 1.80m).

Dữ liệu Danh mục (Categorical Data)

Dữ liệu danh mục thường là chuỗi mô tả nhãn, như “bò” hoặc “ngựa vằn”. Có hai loại dữ liệu danh mục:

  1. Dữ liệu Thứ tự (Ordinal Data): Có thứ tự tự nhiên, có thể sắp xếp.
    • Ví dụ: Các màu cầu vồng (đỏ, cam, vàng, lục, lam, chàm, tím) có thứ tự theo quang phổ.Ví dụ khác: Các giai đoạn tuổi (trẻ sơ sinh, thiếu niên, người già).
Python
colors = ['đỏ', 'tím', 'cam']
rainbow_order = {'đỏ': 1, 'cam': 2, 'tím': 7}
sorted_colors = sorted(colors, key=lambda x: rainbow_order[x])
# Kết quả: ['đỏ', 'cam', 'tím']
  1. Dữ liệu Danh định (Nominal Data): Không có thứ tự tự nhiên.
    • Ví dụ: Các vật dụng văn phòng (kẹp giấy, máy bấm ghim, đồ chuốt bút chì).
    • Ví dụ: Quần áo (tất, áo sơ mi, găng tay, mũ bowler).
    Chúng ta có thể biến dữ liệu danh định thành thứ tự bằng cách áp đặt một thứ tự tùy ý, ví dụ: sắp xếp quần áo từ đầu đến chân (mũ bowler, áo sơ mi, găng tay, tất).

Chuyển đổi dữ liệu phi số

Thuật toán học máy yêu cầu đầu vào là số, nên dữ liệu chuỗi (hoặc dữ liệu phi số khác) cần được chuyển thành số. Một cách đơn giản là tạo danh sách tất cả các chuỗi trong dữ liệu huấn luyện và gán mỗi chuỗi một số duy nhất bắt đầu từ 0.

Ví dụ minh họa:

Python
from sklearn.preprocessing import LabelEncoder
labels = ['', 'ngựa vằn', '']
encoder = LabelEncoder()
encoded_labels = encoder.fit_transform(labels)  # [0, 1, 0]

Mã hóa One-Hot

Trong một số trường hợp, việc chuyển đổi số nguyên thành danh sách là hữu ích.

Ví dụ ta có một hệ thống dự đoán xem một chú mèo thuộc chủng mèo nào (mèo anh, mèo nga, ….), và đôi khi ta có một số chú mèo lai, nên ta cũng muốn hệ thống không chỉ trả ra kết quả chú mèo là mèo anh hay mèo nga, mà là hệ thống nghĩ chú có tỉ lệ 70% là mèo anh, 30% là mèo nga chẳng hạn. Lúc này, ta có thể có 10 class (mèo anh, mèo nga, ….), ta gọi mèo anh là lớp 1, mèo nga lớp 2, … Khi hệ thống đưa ra dự đoán, hệ thống có thể trả về 10 số (tương ứng 10 class) với mỗi số thể hiện độ tin cậy của hệ thống dự đoán ảnh ta đưa vào thuộc lớp nào.

  • Ví dụ: cho ảnh vào, hệ thống trả ra [0.7, 0.4, 0, 0, 0, …] -> Hệ thống tự tin 70% là mèo anh, 40% là mèo nga, …

Điều này cũng có nghĩa là khi chuẩn bị dữ liệu cho hệ thống để train, thay vì khi huấn luyện trên các ảnh mèo anh – 1, mèo nga – 2, mèo c – 3, …. , số lượng class. Ta sẽ đặt là

  • 1 ảnh dữ liệu mèo anh = [1, 0, 0 ,….] (100% mèo anh)
  • 1 ảnh dữ liệu mèo nga = [0, 1, 0, ….] (100% mèo nga)
  • …. => Chuẩn hoá dạng dữ liệu giúp hệ thống dự đoán.

Việc chuyển đổi một nhãn như 3 hoặc 7 thành danh sách này được gọi là mã hóa one-hot (one-hot encoding), ám chỉ chỉ một phần tử trong danh sách là “nóng” (hot), tức được đánh dấu. Danh sách này đôi khi được gọi là biến giả (dummy variable). Khi cung cấp nhãn lớp cho hệ thống trong quá trình huấn luyện, ta thường sử dụng danh sách mã hóa one-hot này thay vì một số nguyên đơn lẻ.

Một ví dụ tương tự về đánh nhãn cho màu

image 66 - quochung.cyou PTIT
[SWE học A.I] Phần 4: Data Prepare & Cleaning 21
Python
import numpy as np

def one_hot_encode(label, num_classes):
    return np.eye(1, num_classes, k=label, dtype=int)[0]

# Ví dụ: Mã hóa nhãn 3 trong 10 lớp
print(one_hot_encode(3, 10))  # Output: [0 0 0 1 0 0 0 0 0 0]

Chuẩn hóa và Tiêu chuẩn hóa

Ta thường làm việc với các mẫu có đặc trưng trải dài trên các khoảng số khác nhau. Ví dụ, giả sử ta thu thập dữ liệu về một đàn voi bụi châu Phi với bốn đặc trưng:

  1. Tuổi tính bằng giờ (0, 420,000)
  2. Cân nặng tính bằng tấn (0, 7)
  3. Chiều dài đuôi tính bằng cm (120, 155)
  4. Tuổi so với tuổi trung bình lịch sử, tính bằng giờ (−210,000, 210,000)

Các khoảng số này khác biệt đáng kể. Do bản chất số học của các thuật toán, các số lớn có thể ảnh hưởng đến chương trình học nhiều hơn các số nhỏ. Đặc trưng 4 không chỉ lớn mà còn có thể âm.

Để đạt hiệu quả học tốt nhất, ta muốn tất cả dữ liệu có thể so sánh được, hoặc nằm trong cùng một khoảng số.

Chuẩn hóa (Normalization)

Bước đầu tiên phổ biến là chuẩn hóa từng đặc trưng (Feature). Trong thống kê, chuẩn hóa có nghĩa là co giãn dữ liệu vào một khoảng cụ thể, thường là [−1,1] hoặc [0,1], tùy thuộc vào dữ liệu (ví dụ, hệ thống dữ liệu về xác suất bức ảnh có phải quả táo không có thể là [0,1] với 0 là không phải, 1 là tự tin 100% là quả táo).

image 67 - quochung.cyou PTIT
[SWE học A.I] Phần 4: Data Prepare & Cleaning 22
image 68 - quochung.cyou PTIT
[SWE học A.I] Phần 4: Data Prepare & Cleaning 23

Giá trị x được co giãn từ −1 đến 1, và giá trị y được co giãn độc lập từ −1 đến 1. Hình guitar bị lệch vì dữ liệu y ban đầu có khoảng [–0.5, 0.2], cần kéo giãn nhiều hơn so với x [–1, 0].

Chuẩn hóa dữ liệu nhiệt độ (0°C đến 40°C) và độ ẩm (20% đến 80%) vào [0,1].

Python
from sklearn.preprocessing import StandardScaler
import numpy as np

data = np.array([[0, 20], [40, 80]])
scaler = StandardScaler()
standardized_data = scaler.fit_transform(data)
print(standardized_data)

Tiêu chuẩn hóa (Standardization)

Một thao tác phổ biến khác là tiêu chuẩn hóa đặc trưng, gồm hai bước:

  1. Trừ giá trị trung bình của đặc trưng để trung bình bằng 0 (gọi là chuẩn hóa trung bình).
    • Lấy từng giá trị dữ liệu và trừ đi giá trị trung bình của toàn bộ cột.
    • Mục tiêu: Làm cho trung bình (mean) của cột đó trở thành 0.
    • Gọi là: chuẩn hóa trung bình.
  2. Co giãn đặc trưng để có độ lệch chuẩn bằng 1 (chuẩn hóa phương sai).
    • Sau khi đã trừ mean, chia cho độ lệch chuẩn của cột.
    • Mục tiêu: Làm cho dữ liệu có độ lệch chuẩn = 1, tức là không quá phân tán.
    • Gọi là: chuẩn hóa phương sai.
Python
[160, 170, 180]
Mean = (160+170+180)/3 = 170
Std = căn((100 + 0 + 100)/3) = ~8.16
[(160 - 170)/8.16, (170 - 170)/8.16, (180 - 170)/8.16]
=> [-1.22, 0, 1.22]

Chuẩn hóa vs. Tiêu chuẩn hóa: Khi nào dùng cái nào?

  • Chuẩn hóa: Phù hợp khi dữ liệu cần giới hạn trong khoảng cố định, ví dụ, mạng nơ-ron yêu cầu đầu vào [0,1].
  • Tiêu chuẩn hóa: Phù hợp với các thuật toán giả định dữ liệu tuân theo phân phối chuẩn.

Biến đổi Nghịch đảo

Chúng ta đã tìm hiểu về các phép biến đổi khác nhau có thể áp dụng cho dữ liệu. Tuy nhiên, đôi khi chúng ta muốn hoàn tác, hoặc thực hiện biến đổi nghịch đảo (inverse transformation), để dễ dàng so sánh kết quả với dữ liệu gốc.

Ví dụ, giả sử chúng ta làm việc cho sở giao thông của một thành phố có một tuyến đường cao tốc chính. Thành phố nằm ở phía bắc, nơi nhiệt độ thường xuyên xuống dưới mức đóng băng. Các nhà quản lý nhận thấy mật độ giao thông dường như thay đổi theo nhiệt độ, với nhiều người ở nhà hơn vào những ngày lạnh nhất. Để lập kế hoạch sửa chữa đường và các công trình khác, họ muốn biết số lượng xe dự đoán được trong giờ cao điểm sáng (7-8 giờ sáng) dựa trên nhiệt độ. Vì việc đo lường và xử lý dữ liệu mất một khoảng thời gian, chúng ta quyết định đo nhiệt độ lúc nửa đêm và dự đoán số lượng xe vào sáng hôm sau. Hệ thống của chúng ta bắt đầu hoạt động vào giữa mùa đông, nên chúng ta dự kiến nhiệt độ sẽ dao động cả trên và dưới mức đóng băng (0°C).

Trong vài tháng, chúng ta đo nhiệt độ lúc nửa đêm và đếm tổng số xe đi qua một điểm đánh dấu cụ thể trên đường vào khung giờ 7-8 giờ sáng hôm sau.

image 70 - quochung.cyou PTIT
[SWE học A.I] Phần 4: Data Prepare & Cleaning 24

Chúng ta muốn cung cấp dữ liệu này cho một hệ thống học máy (machine learning) để tìm ra mối liên hệ giữa nhiệt độ và mật độ giao thông. Sau khi triển khai, chúng ta nhập một mẫu dữ liệu gồm một đặc trưng (feature) là nhiệt độ (đơn vị độ C) và nhận về một số thực dự đoán số lượng xe trên đường.

Giả sử thuật toán hồi quy (regression algorithm) mà chúng ta sử dụng hoạt động tốt nhất khi dữ liệu đầu vào được chuẩn hóa về khoảng [0,1]. Chúng ta có thể chuẩn hóa dữ liệu về khoảng [0,1] trên cả hai trục

image 71 - quochung.cyou PTIT
[SWE học A.I] Phần 4: Data Prepare & Cleaning 25

Hình này trông giống hình trên, chỉ khác ở chỗ cả hai trục (và dữ liệu) giờ đây đều nằm trong khoảng từ 0 đến 1.

image 72 - quochung.cyou PTIT
[SWE học A.I] Phần 4: Data Prepare & Cleaning 26
image 73 - quochung.cyou PTIT
[SWE học A.I] Phần 4: Data Prepare & Cleaning 27

Giả sử chúng ta đã huấn luyện hệ thống và nó dự đoán tốt số lượng xe từ dữ liệu nhiệt độ.

image 74 - quochung.cyou PTIT
[SWE học A.I] Phần 4: Data Prepare & Cleaning 28

Ngày hôm sau, chúng ta triển khai hệ thống trên một trang web cho các nhà quản lý thành phố. Vào đêm đầu tiên, người quản lý trực ca đo được nhiệt độ lúc nửa đêm là -10°C. Cô ấy mở ứng dụng, tìm ô nhập nhiệt độ, nhập -10 và nhấn nút “Dự đoán giao thông”.

Vấn đề phát sinh

Có vấn đề xảy ra. Chúng ta không thể nhập trực tiếp -10 vào hệ thống đã huấn luyện, vì hệ thống kỳ vọng một số trong khoảng [0,1]. Chúng ta cần biến đổi dữ liệu theo cách nào đó. Cách duy nhất hợp lý là áp dụng cùng phép biến đổi đã dùng cho dữ liệu nhiệt độ khi huấn luyện. Ví dụ, nếu trong tập dữ liệu gốc, -10 được biến đổi thành 0.29, thì khi nhiệt độ là -10°C tối nay, chúng ta nên nhập 0.29, không phải -10.

Đây là lúc chúng ta thấy giá trị của việc lưu phép biến đổi dưới dạng một đối tượng. Chúng ta chỉ cần yêu cầu đối tượng áp dụng cùng phép biến đổi đã sử dụng cho dữ liệu huấn luyện vào dữ liệu mới này. Nếu -10 được biến đổi thành 0.29 trong quá trình huấn luyện, thì bất kỳ đầu vào mới nào là -10 cũng sẽ được biến đổi thành 0.29 khi triển khai.

Giả sử chúng ta nhập đúng nhiệt độ 0.29 vào hệ thống, và nó trả về mật độ giao thông là 0.32. Giá trị này tương ứng với số lượng xe nào đó đã được biến đổi bởi phép biến đổi số lượng xe. Nhưng giá trị này nằm trong khoảng [0,1], vì đó là khoảng dữ liệu huấn luyện biểu thị số lượng xe. Làm thế nào để hoàn tác phép biến đổi này và chuyển nó thành số lượng xe thực tế?

Trong bất kỳ thư viện học máy nào, mỗi đối tượng biến đổi đều đi kèm với một hàm để thực hiện biến đổi nghịch đảo (inverse transformation), giúp hoàn tác phép biến đổi. Trong trường hợp này, nó đảo ngược phép chuẩn hóa đã áp dụng. Nếu đối tượng biến đổi 39 xe thành giá trị chuẩn hóa 0.32, thì phép biến đổi nghịch đảo sẽ chuyển giá trị chuẩn hóa 0.32 trở lại thành 39 xe. Đây là giá trị chúng ta hiển thị cho nhà quản lý thành phố.

image 76 - quochung.cyou PTIT
[SWE học A.I] Phần 4: Data Prepare & Cleaning 29

Vấn đề với dữ liệu ngoài phạm vi

Một vấn đề có thể xảy ra là khi nhận được mẫu mới ngoài phạm vi dữ liệu gốc. Giả sử một đêm nhiệt độ xuống -50°C, thấp hơn nhiều so với giá trị nhỏ nhất trong dữ liệu gốc. Kết quả là giá trị đã biến đổi sẽ là số âm, nằm ngoài khoảng [0,1]. Tương tự, nếu một đêm rất nóng, nhiệt độ dương có thể biến đổi thành giá trị lớn hơn 1, cũng nằm ngoài khoảng [0,1].

Cả hai trường hợp này đều không có vấn đề. Mục đích chuẩn hóa đầu vào về [0,1] là để huấn luyện hiệu quả và kiểm soát các vấn đề số học. Sau khi hệ thống được huấn luyện, chúng ta có thể nhập bất kỳ giá trị nào, và nó sẽ tính toán đầu ra tương ứng. Tuy nhiên, chúng ta vẫn cần chú ý đến dữ liệu. Nếu hệ thống dự đoán số xe âm cho ngày mai, chúng ta không nên lập kế hoạch dựa trên con số đó.

Để minh họa, hãy giả định một tập dữ liệu nhiệt độ từ -20°C đến 20°C và số lượng xe từ 0 đến 1000. Chúng ta áp dụng chuẩn hóa tuyến tính (linear normalization):

  • Chuẩn hóa nhiệt độ:
    • Công thức: x’ = \frac{x – x_{\text{min}}}{x_{\text{max}} – x_{\text{min}}}
    • Với x_{\text{min}} = -20, x_{\text{max}} = 20:
      • Nếu x = -10, thì x’ = \frac{-10 – (-20)}{20 – (-20)} = \frac{10}{40} = 0.25
    • Lưu các tham số x_{\text{min}} = -20x_{\text{max}} = 20.
  • Chuẩn hóa số lượng xe:
    • Công thức tương tự, với y_{\text{min}} = 0, y_{\text{max}} = 1000:
      • Nếu y = 320, thì y’ = \frac{320 – 0}{1000 – 0} = 0.32
  • Biến đổi nghịch đảo:
    • Công thức: x = x’ \cdot (x_{\text{max}} – x_{\text{min}}) + x_{\text{min}}
    • Với đầu ra y’ = 0.32:
      • y = 0.32 \cdot (1000 – 0) + 0 = 320 xe.
Python
from sklearn.preprocessing import MinMaxScaler
import numpy as np

# Dữ liệu giả lập
temps = np.array([-20, -10, 0, 10, 20]).reshape(-1, 1)
cars = np.array([0, 200, 500, 800, 1000]).reshape(-1, 1)

# Tạo và huấn luyện bộ chuẩn hóa
temp_scaler = MinMaxScaler()
car_scaler = MinMaxScaler()
temp_scaled = temp_scaler.fit_transform(temps)
car_scaled = car_scaler.fit_transform(cars)

# Biến đổi dữ liệu mới
new_temp = np.array([[-10]])
new_temp_scaled = temp_scaler.transform(new_temp)  # Kết quả: [[0.25]]

# Giả sử mô hình dự đoán được 0.32
pred_scaled = np.array([[0.32]])
pred_cars = car_scaler.inverse_transform(pred_scaled)  # Kết quả: [[320]]

print(f"Nhiệt độ -10°C -> Chuẩn hóa: {new_temp_scaled[0][0]:.2f}")
print(f"Dự đoán chuẩn hóa 0.32 -> Số xe: {pred_cars[0][0]:.0f}")

Thu gọn tập dữ liệu (Data Shrink)

Chúng ta đã xem xét các cách điều chỉnh số liệu trong dữ liệu và lựa chọn dữ liệu cho từng phép biến đổi. Bây giờ, hãy xem xét một loại biến đổi khác nhằm thu gọn dữ liệu, tạo ra một tập dữ liệu nhỏ hơn tập huấn luyện ban đầu, thường bằng cách loại bỏ hoặc kết hợp các đặc trưng.

Lợi ích của việc này là tăng tốc độ và độ chính xác khi huấn luyện. Ít dữ liệu hơn nghĩa là huấn luyện nhanh hơn, cho phép học nhiều hơn trong cùng khoảng thời gian, dẫn đến hệ thống chính xác hơn.

Lựa chọn đặc trưng (Feature Selection)

Nếu dữ liệu chứa các đặc trưng dư thừa, không liên quan hoặc không hữu ích, chúng ta nên loại bỏ chúng để tiết kiệm thời gian. Quá trình này gọi là lựa chọn đặc trưng (feature selection) hoặc lọc đặc trưng (feature filtering).

Ví dụ, giả sử chúng ta gắn nhãn thủ công hình ảnh của voi, nhập kích thước, loài và các đặc điểm khác vào cơ sở dữ liệu. Vì lý do nào đó, chúng ta có một trường cho số lượng đầu. Voi chỉ có một đầu, nên trường này chỉ toàn số 1, do đó vô dụng và làm chậm quá trình. Chúng ta nên loại bỏ trường này.

Tổng quát hơn, chúng ta có thể loại bỏ các đặc trưng đóng góp rất ít hoặc có ít tác động nhất đến kết quả. Ví dụ, với tập dữ liệu về voi, chiều dài vòi và kích thước tai có thể tương quan chặt chẽ. Nếu vậy, chúng ta có thể loại bỏ một trong hai mà vẫn giữ được thông tin.

Nhiều thư viện cung cấp công cụ để đánh giá tác động của việc loại bỏ từng trường. Chúng ta sử dụng thông tin này để đơn giản hóa cơ sở dữ liệu, tăng tốc học mà không mất quá nhiều độ chính xác. Vì loại bỏ đặc trưng là một phép biến đổi, bất kỳ đặc trưng nào bị loại khỏi tập huấn luyện cũng phải bị loại khỏi dữ liệu tương lai.

Giảm chiều dữ liệu (Dimensionality Reduction)

Một cách khác để thu gọn tập dữ liệu là kết hợp các đặc trưng, để một đặc trưng thay thế cho hai hoặc nhiều đặc trưng. Quá trình này gọi là giảm chiều dữ liệu (dimensionality reduction), với chiều là số lượng đặc trưng.

Ví dụ, chỉ số khối cơ thể (BMI) là một số kết hợp chiều cao và cân nặng. Một số chỉ số sức khỏe có thể được tính toán chỉ với BMI. Ví dụ, biểu đồ giúp người dùng quyết định xem có cần giảm cân có thể được lập chỉ mục bởi tuổi và BMI, chúng ta có thể giảm từ feature (chiều cao, cân nặng) -> (BMI).

Reference:

  • Deep Learning – Andrew Glassner
  • Data Science from Scratch – Joel Grus
Series Navigation<< [SWE học A.I] Phần 3: Một số khái niệm suất thống kê[SWE học A.I] Phần 6: Machine Learning Classification >>

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply