1. Giới thiệu
Dimensionality Reduction (giảm chiều dữ liệu), như đã được đề cập một vài lần trong blog, là một trong những kỹ thuật quan trọng trong Machine Learning. Các feature vectors trong các bài toán thực tế có thể có số chiều rất lớn, tới vài nghìn. Ngoài ra, số lượng các điểm dữ liệu cũng thường rất lớn. Nếu thực hiện lưu trữ và tính toán trực tiếp trên dữ liệu có số chiều cao này thì sẽ gặp khó khăn cả về việc lưu trữ và tốc độ tính toán. Vì vậy, giảm số chiều dữ liệu là một bước quan trọng trong nhiều bài toán. Đây cũng được coi là một phương pháp nén dữ liệu.
Đang xem: 17, giới thiệu principal component analysis
Dimensionality Reduction, nói một cách đơn giản, là việc đi tìm một hàm số, hàm số này lấy đầu vào là một điểm dữ liệu ban đầu (mathbf{x} in mathbb{R}^D) với (D) rất lớn, và tạo ra một điểm dữ liệu mới (mathbf{z} in mathbb{R}^K) có số chiều (K
Nếu bạn cần ôn tập lại các kiến thức về hệ độc lập tuyến tính, kỳ vọng, phương sai, ma trận hiệp phương sai, bạn có thể đọc Mục 2.
Nếu bạn muốn hiểu nguồn gốc, ý tưởng đứng sau PCA, tại sao PCA lại được thực hiện như vậy, bạn có thể tìm được ở Mục 3.
Nếu bạn không muốn đi sâu vào toán mà chỉ cần hiểu các bước thực hiện PCA, bạn có thể tới ngay Mục 4.
Nếu bạn không muốn hiểu các bước thực hiện mà chỉ muốn biết hàm số thực hiện PCA, một vài ứng dụng của PCA, và có thể thêm các phần mở rộng của PCA, bạn có thể thấy PCA phần 2 có ích, dự tính được ra mắt sau đây một tuần.
Nếu tôi là các bạn, tôi sẽ đọc hết cả bài.
Trước khi đi vào chi tiết của PCA, chúng ta cùng điểm lại một chút về Đại số tuyến tính và Thống kê.
2. Một chút toán
2.1. Norm 2 của ma trận
Chúng ta vẫn thường nhắc nhiều đến norm cho vector nhưng chưa thực sự làm việc nhiều với norm của ma trận (ngoài Frobenius norm). Trong mục này, chúng ta sẽ làm quen với 1 lớp các norm cho ma trận được định nghĩa dựa trên norm của vector. Lớp các norms này còn được gọi là Induced Norms.
Giả sử hàm số (||mathbf{x}||_{alpha}) là một norm bất kỳ của vector (mathbf{x}). Ứng với norm này, định nghĩa norm tương ứng cho ma trận (mathbf{A}):<||mathbf{A}||_{alpha} = max_{mathbf{x}} frac{||mathbf{Ax}||_{alpha}}{||mathbf{x}||_{alpha}}>
chú ý rằng ma trận (mathbf{A}) có thể không vuông và số cột của nó bằng với số chiều của (mathbf{x}). Như vậy, bản thân việc tính toán norm của ma trận là việc giải một bài toán tối ưu. Chú ý rằng hàm tối ưu có cả tử số và mẫu số là các norm trên vectors.
Chúng ta sẽ quan tâm nhiều hơn tới norm 2. Norm 2 của ma trận được định nghĩa là:<||mathbf{A}||_2 = max_{mathbf{x}} frac{||mathbf{Ax}||_2}{||mathbf{x}||_2} ~~~ (1)>
Nhận thấy rằng nếu (mathbf{x}) là nghiệm của bài toán tối ưu ((1)) thì (kmathbf{x}) cũng là nghiệm với (k) là một số thực khác không bất kỳ. Không mất tính tổng quát, ta có thể giả sử mẫu số bằng 1. Khi đó, bài toán tối ưu ((1)) có thể được viết dưới dạng:<||mathbf{A}||_2 = max_{||mathbf{x}||_2 = 1} ||mathbf{Ax}||_2 ~~~ (2)>Nói cách khác, ta cần đi tìm (mathbf{x}) sao cho:<egin{eqnarray}mathbf{x} &=& ext{argmax}_{mathbf{x}} ||mathbf{Ax}||_2^2 & ewline ext{s.t.: } && ||mathbf{x}||_2^2 = 1 & (3)end{eqnarray}>Ở đây, các norm 2 đã được bình phương lên để tránh dấu căn bậc hai. Bài toán ((3)) có thể được giải bằng Phương pháp nhân tử Lagrange vì ràng buộc là một phương trình.
Lagrangian của Bài toán ((3)) là:
Nghiệm của bài toán ((3)) sẽ thoả mãn hệ phương trình:<egin{eqnarray}frac{partial mathcal{L}}{partial mathbf{x}} &=& 2mathbf{A}^Tmathbf{Ax} - 2lambda mathbf{x} = mathbf{0} & (4) ewlinefrac{partial mathcal{L}}{partial lambda} &=& 1 - ||mathbf{x}||_2^2 = 0 & (5)end{eqnarray}>
Từ ((4)) ta có:
Như vậy, norm 2 của một ma trận chính là singular value lớn nhất của ma trận đó. Và nghiệm của bài toán ((3)) chính một là right-singular vector ứng với singular value đó.
Xem thêm: Định Nghĩa Rich Text Format (Rtf) Là Gì? Hĩa Rich Text Format (Rtf) Là Gì?
Với lý luận tương tự, chúng ta có thể suy ra rằng bài toán:
có nghiệm là vector riêng ứng với trị riêng nhỏ nhất của (mathbf{A}^Tmathbf{A}). Khi đó, hàm số đạt giá trị nhỏ nhất bằng chính trị riêng nhỏ nhất này.
2.2. Biễu diễn vector trong các hệ cơ sở khác nhau
Trong không gian (D) chiều , toạ độ của mỗi điểm được xác định dựa trên một hệ toạ độ nào đó. Ở các hệ toạ độ khác nhau, hiển nhiên là toạ độ của mỗi điểm cũng khác nhau.
Tập hợp các vector (mathbf{e}_1, dots, mathbf{e}_D) mà mỗi vector (mathbf{e}_d) có đúng 1 phần tử khác 0 ở thành phần thứ (d) và phần tử đó bằng 1, được gọi là hệ cơ sở đơn vị (hoặc hệ đơn vị) trong không gian (D) chiều. Nếu xếp các vector (mathbf{e}_d, d = 1, 2, dots, D) theo đúng thứ tự đó, ta sẽ được ma trận đơn vị (D) chiều.
Mỗi vector cột (mathbf{x} =
Giả sử có một hệ cơ sở khác (mathbf{u}_1, mathbf{u}_2, dots, mathbf{u}_D) (các vector này độc lập tuyến tính), vậy thì biểu diễn của vector (mathbf{x}) trong hệ cơ sở mới này có dạng:
(mathbf{U}) là ma trận mà cột thứ (d) của nó chính là vector (mathbf{u}_d). Lúc này, vector (mathbf{y}) chính là biểu diễn của (mathbf{x}) trong hệ cơ sở mới. Bộ các số (y_d, d = 1, 2, dots, D) là duy nhất vì (mathbf{y}) có thể tính được bằng:
Trong các ma trận đóng vai trò như hệ cơ sở (mathbf{U}), các ma trận trực giao, tức (mathbf{U}^Tmathbf{U} = mathbf{I}), được quan tâm nhiều hơn vì nghịch đảo của chúng chính là chuyển vị của chúng:
Có thể nhận thấy rằng vector (mathbf{0}) được biểu diễn như nhau trong mọi hệ cơ sở.Hình 1 dưới đây là 1 ví dụ về việc chuyển hệ cơ sở:
Hello anh em, hôm nay chúng ta sẽ cùng tìm hiểu và code thử món Principal Component Analysis (PCA) – tuyệt chiêu giảm chiều dữ liệu nhé!
Khi học lý thuyết thì anh em sẽ thấy các bài toán có vài đặc trưng (features) và vector input thường chỉ có độ dài 1,2 phần tử. Nhưng khi làm việc thực tế thì chúng ta sẽ thường xuyên phải deal với các input có số đặc trưng lớn, dài dằng dặc và chúng ta chả biết bỏ cái nào, dùng cái nào cho vừa hiệu quả vừa đỡ được chi phí tính toán.
Đó là lúc chúng ta nghĩ đến PCA để giảm chiều dữ liệu mà vẫn giữ lại được các đặc trưng tốt để phục vụ cho bài toán của chúng ta!
Trước khi bắt đầu mình xin phép được bỏ qua toàn bộ phần toán phức tạp, chỉ giải thích ở level cơ bản để chúng ta – những người newbie thích ăn mì – có thể hiểu và triển khai được thôi nhé!
Let’s go!
Phần 1 – Vậy PCA là gì?
PCA là viết tắt của Principal Component Analysis. Ta dịch thô sang tiếng Việt là “Phân tích thành phần chính”, tạm hiểu theo cách “nông dân” của mình là ta sẽ phân tích dữ liệu và sau đó tìm ra các thành phần chính của dữ liệu để giữ lại các thành phần đó. Ví dụ dữ liệu của chính ta có N features thì sau khi áp dụng PCA sẽ còn K features chính mà thôi (KGiảm chiều dữ liệu mà vẫn giữ được đặc trưng chính, chỉ mất đi “chút ít” đặc trưng.Tiết kiệm thời gian, chi phí tính toán
Dễ dàng visualize dữ liệu hơn để giúp ta có cái nhìn trực quan hơn.
Okie. Và tất nhiên K features này tất nhiên không được chọn ngẫu nhiên, chúng ta đi tiếp nhé!
Các components ở đây ta nói thực chất là các vectors độc lập tuyến tính được chọn sao cho khi chiếu các điểm dữ liệu lên vector đó thì các điểm dữ liệu có sự variance lớn nhất ( biến động nhiều nhất, phương sai lớn nhất).
Ví dụ như hình trên, chúng ta chọn 2 vector component theo thứ tự: 1st Comp sẽ có mức độ variance lớn nhất, ta chọn trước, sau đó đến 2nd Comp…. và cứ thế. Khi làm thực tế chúng ta sẽ cần xác định hoặc thử sai xem sẽ chọn bao nhiêu components là hợp lý và mang lại kết quả tốt nhất.
Xét một cách nhìn khác thì PCA cũng là một bài toán chuyển hệ tọa độ như hình dưới:
Okie, bây giờ chắc các bạn sẽ thắc mắc tại sao phải chọn comp với mức độ dữ liệu biến thiên variance lớn nhất làm gì nhỉ? Chọn bừa cái nào chả được :D. Haha.
Lý do đây! Ví dụ xét bài toán phân loại classification, ví dụ : Ung thư/ Không ung thư, Spam/Normal…. Bây giờ nếu chúng ta chọn 1 comp mà chiếu lên đó các điểm dữ liệu không high variance, nó đè lên nhau và co cụm lại một chỗ thì làm sao mà phân loại nổi. Nói cách khác là làm sao tìm được đường hay mặt phẳng chia tách các dữ liệu đó thành 2 phần khác nhau cho 2 class khác nhau. Do đó, ta phải chọn comp sao cho khi chiếu data lên comp đó thì nó high variance.
Okie rồi, tạm hiểu như vậy nhé các bạn. Bây giờ chúng ta sẽ thử triển khai với Python xem PCA nó mần răng.
Xem thêm: Team là gì? ý nghĩa và tác dụng của việc lập team là gì? và lợi ích của nó
Phần 2 – Triển khai Principal Component Analysis với Python
Để demo cách chúng ta triển khai PCA với Python, mình sẽ dùng một bộ dữ liệu khá phổ biến và tích hợp sẵn trong Sklearn đó là Breast_Cancer – Ung thư vú. Dữ liệu này có rất nhiều features khác nhau và khá lằng nhằng (do mình không có kiến thức y khoa haha) và dùng nó để minh họa PCA là chuẩn bài rồi.
Đầu tiên là cứ phải import đầy đủ các thư viện cái đã. Phần này là thói quen của mình khi làm việc với data, mình cứ import hết đề phòng thiếu
import pandas as pdimport numpy as npimport matplotlib.pyplot as pltimport seaborn as sns%matplotlib inline
Code language: Java
Script (javascript)Okie, xong rồi! Bây giờ ta sẽ load dữ liệu in ra xem data của chúng ta như nào:
from sklearn.datasets import load_breast_cancer# Đọc dữ liệu từ sklearncancer_set = load_breast_cancer()# Chuyển thành Data
Framecancer_data = pd.Data
Frame(data=cancer_set <"data">, columns=cancer_set<"feature_names">)cancer_data.head()
Code language: PHP (php)Và ta thấy dữ liệu có cả mớ cột