Trong bài viết này mình sẽ sử dụng một dataset về mối liên hệ giữa tiếng dế kêu trong một giây và nhiệt độ. Bạn có thể tải dataset ở đây
Một giới thiệu nhẹ nhàng về PCA
Để đơn giản hóa mọi thứ, chúng ta sẽ sử dụng dữ liệu đa biến (có nghĩa là 2D) này để giải thích khái niệm PCA.
PCA dựa trên ý tưởng từ đại số tuyến tính: bất kỳ vectơ nào cũng có thể được biểu diễn dưới dạng kết hợp tuyến tính của các vectơ cơ sở.
Dữ liệu được vẽ dưới dạng biểu đồ X/Y, có nghĩa là chúng ta đã chọn hai chiều để mô tả dữ liệu. Hai trục (thực ra là hướng của chúng)
Hướng trục hơi tùy ý, có nghĩa là chúng ta luôn có thể chọn các hướng khác. Ý của tôi là bạn có thể kẻ bất kỳ đường thẳng nào chồng chéo vào đống dữ liệu kia và coi nó như một hướng, Nhưng sẽ tốt hơn nếu tìm ra được hướng mô tả tốt dữ liệu. Ví dụ, chúng ta có thể tìm ra hướng dữ liệu thay đổi nhanh hơn và xác định đó là trục x. Nó chỉ ra rằng hướng mà dữ liệu thay đổi nhiều nhất là thành phần chính đầu tiên. PCA là phương pháp tìm và sắp xếp các hướng chính mà dữ liệu thay đổi.
Tất nhiên, trong ví dụ 2D đơn giản của chúng ta, chúng ta sẽ chỉ có hai thành phần chính, như các trục x-y thông thường, sẽ trực giao với nhau.
Từng bước thực hiện PCA trong python
import numpy as np
import matplotlib.pyplot as plt
from pandas import read_csv
# đọc data
data = read_csv('data.csv')
cs = data["X"].values
temp = data["Y"].values
# Chuẩn hoá bằng việc trừ đi giá bị mean
x = cs - cs.mean()
y = temp - temp.mean()
# Nhóm dữ liệu thành một ma trận duy nhất
datamatrix = np.array([x,y])
# tính toán ma trận hiệp phương sai của ma trận ở trên
covmat = np.cov(datamatrix)
# tìm eigenvalues và eigenvectors của ma trận hiệp phương sai
w,v = np.linalg.eig(covmat)
# Lấy index của eigenvalue lớn nhất
maxeig = np.argmax(w)
# Lấy hệ số góc của đường thẳng đi qua điểm gốc và eigenvector lớn nhất
m = -v[maxeig, 1]/v[maxeig, 0]
line = m*x
hãy xem qua mã từng bước.
Bước 1, đọc dữ liệu và gán dữ liệu đó vào các mảng numpy.
Bước 2, để PCA hoạt động, chúng ta cần loại bỏ giá trị trung bình từ cả hai tọa độ, tức là chúng ta muốn dữ liệu được căn giữa tại điểm gốc của tọa độ x-y
Bước 3, nhóm dữ liệu trong một mảng duy nhất
Bước 4, tính toán ma trận hiệp phương sai của mảng này. Vì chúng ta đang xử lý tập dữ liệu 2D (dữ liệu hai biến), ma trận hiệp phương sai sẽ là 2 × 2
Bước 5, tính toán các eigenvalues và các eigenvectors của ma trận hiệp phương sai.
Bước 6, lấy index của giá trị eigenvalue lớn nhất. Thành phần chính đầu tiên mà chúng ta đang tìm kiếm là eigenvector tương ứng với eigenvalue lớn nhất.
Bước 7, Ta nhận được hệ số góc của đường thẳng song song với thành phần chính
vẽ thành phần chính đầu tiên trên dữ liệu.
plt.scatter(x, y)
plt.xlabel('x')
plt.ylabel('y')
plt.quiver(0,0, x[0], line[0], units = 'xy', scale = 1, color='r', width = 0.2)
plt.axis('equal')
plt.ylim((-18,18))
plt.show()
Xong. Chúng ta đã tìm thấy 2 thành phần chính của dữ liệu đa biến và vẽ thành phần lớn nhất trên biểu đồ của chúng ta. Trong trường hợp đơn giản này, PCA không gì khác hơn là fit đường thẳng với dữ liệu, nhưng nó trở nên rất hữu ích khi nói đến dữ liệu đa biến.
Thực hiện PCA với sklearn
Chỉ với một vài dòng:
from sklearn.decomposition import PCA
datazip = list(zip(x,y))
pca = PCA(n_components=2)
pca.fit(datazip)
# Print the eigenvectors
print(pca.components_)
pca_components_ liệt kê các eigenvectors. Điều này tương đương với ma trận
[imath]w[/imath]
mà chúng ta tìm thấy với ví dụ từng bước, với sự khác biệt duy nhất là các eigenvector đã được sắp xếp theo thứ tự giảm dần. Điều đó có nghĩa là thành phần chính là pca_components_[0].