PCA實現教程
資料是機器學習模型的生命燃料。對於特定的問題,總有很多機器學習技術可供選擇,但如果沒有很多好的資料,問題將不能很好的解決。資料通常是大部分機器學習應用程式中效能提升背後的驅動因素。
有時,資料可能很複雜。在那麼多的資料中,知道哪些資料是真正重要的,具有一定的挑戰性。降維是一種可以幫助我們更好地瞭解資料的技術,它減少了資料集的特徵數量,因此只剩下最重要的部分特徵。
主成分分析(PCA)是一種用於降維的簡單而強大的技術。通過它,我們可以直接減少特徵變數的數量,從而減少重要特徵並節省計算量。從高層次來看,PCA有三個主要步驟:
(1)計算資料的協方差矩陣;
(2)計算該協方差矩陣的特徵值和向量;
(3)通過特徵值和向量來只選擇最重要的特徵向量,然後將資料轉換為這些向量以降低維度。
(1)計算協方差矩陣
PCA 產生一個特徵子空間,使特徵向量的方差最大化。因此,為了正確計算這些特徵向量的方差,必須對它們進行適當的平衡。為實現此目的,我們首先將資料歸一化為零均值和單位方差,以便在計算中對每個特徵進行加權。假設我們的資料集為X:
from sklearn.preprocessing import StandardScaler X = StandardScaler().fit_transform(X)
兩個變數的協方差衡量它們是如何“相關”的。如果兩個變數的協方差是正的,那麼當一個變數增加時,另一個變數增加;在協方差為負的情況下,特徵變數的值將在相反方向上改變。協方差矩陣只是一個數組,其中每個值基於矩陣中的x-y位置指定兩個特徵變數之間的協方差。公式是:
其中帶有上劃線的x是X的每個特徵的均值向量,將轉置矩陣乘以原始矩陣時,我們最終將每個資料點的每個特徵相乘!在numpy程式碼中實現如下:
import numpy as np # Compute the mean of the data mean_vec = np.mean(X, axis=0) # Compute the covariance matrix cov_mat = (X - mean_vec).T.dot((X - mean_vec)) / (X.shape[0]-1) # OR we can do this with one line of numpy: cov_mat = np.cov(X.T)
(2)計算特徵值和向量
我們的協方差矩陣的特徵向量(主成分)表示新特徵空間的向量方向,而特徵值表示這些向量的大小。由於我們正在研究協方差矩陣,因此特徵值量化了每個向量的貢獻方差。
如果特徵向量具有相應的高幅度特徵值,則意味著我們的資料在特徵空間中沿著該向量具有高方差。因此,該向量包含有關資料的大量資訊,因為沿著該向量的任何移動都會導致大的“方差”。另一方面,具有小特徵值的向量具有低方差,因此當沿著該向量移動時,我們的資料不會有很大變化。由於在沿著特定特徵向量移動時沒有任何變化,即改變該特徵向量的值不會對我們的資料產生很大影響,那麼我們可以說這個特徵不是很重要,可以忽略它。
這是PCA中特徵值和向量的全部本質,找到表示資料最重要的向量,並丟棄其餘的向量。計算協方差矩陣的特徵向量和值是一個簡單的單線性的numpy。之後,我們將根據它們的特徵值按降序對特徵向量進行排序。
# Compute the eigen values and vectors using numpy eig_vals, eig_vecs = np.linalg.eig(cov_mat) # Make a list of (eigenvalue, eigenvector) tuples eig_pairs = [(np.abs(eig_vals[i]), eig_vecs[:,i]) for i in range(len(eig_vals))] # Sort the (eigenvalue, eigenvector) tuples from high to low eig_pairs.sort(key=lambda x: x[0], reverse=True)
(3)對映到新的向量上
此時,我們有一個特徵向量列表,這些特徵向量基於它們的特徵值按照資料集的“重要性”進行排序。現在要做的是選擇最重要的特徵向量並丟棄其餘的,可以通過查看向量的可解釋方差百分比來巧妙地做到這一點。該百分比量化了總100%中每個主成分可歸因於多少資訊(方差)。
我們舉一個例子來說明。假設一個最初有10個特徵向量的資料集。在計算協方差矩陣之後,特徵值是:
[12,10,8,7,5,1,0.1,0.03,0.005,0.0009]
該陣列的總和= 43.1359,但前6個值代表:43 / 43.1359 =總數的99.68%!這意味著我們的前6個特徵向量有效地保持了99.68%有關資料集的資訊。因此,可以丟棄最後4個特徵向量,因為它們只包含0.32%的資訊,這就節省了40%的計算量。
因此,我們可以簡單地定義一個閾值,這個閾值可以決定是保留還是丟棄每個特徵向量。在下面的程式碼中,設定閾值97%來決定每個特徵向量是否丟棄。
# Only keep a certain number of eigen vectors based on # the "explained variance percentage" which tells us how # much information (variance) can be attributed to each # of the principal components exp_var_percentage = 0.97 # Threshold of 97% explained variance tot = sum(eig_vals) var_exp = [(i / tot)*100 for i in sorted(eig_vals, reverse=True)] cum_var_exp = np.cumsum(var_exp) num_vec_to_keep = 0 for index, percentage in enumerate(cum_var_exp): if percentage > exp_var_percentage: num_vec_to_keep = index + 1 break
最後一步是將我們的資料實際投射到決定保留的向量上。我們通過構建投影矩陣來做到這一點:我們將通過相乘將資料投影到新的向量上。為了建立它,簡單地與決定保留的所有特徵向量進行連線,最後一步是簡單地在原始資料和投影矩陣之間取點積。
維度降低了!
# Compute the projection matrix based on the top eigen vectors num_features = X.shape[1] proj_mat = eig_pairs[0][1].reshape(num_features,1) for eig_vec_idx in range(1, num_vec_to_keep): proj_mat = np.hstack((proj_mat, eig_pairs[eig_vec_idx][1].reshape(num_features,1))) # Project the data pca_data = X.dot(proj_mat)
資料科學書推薦
想要了解更多有關資料科學的資訊? ofollow,noindex" target="_blank"> 這本書 是我在這個主題上看到的最好的,提供了實用且易於理解的課程。
本文由 阿里云云棲社群 組織翻譯。
文章原標題《principal-component-analysis-your-tutorial-and-code》
作者: George Seif 譯者:烏拉烏拉,審校:。
文章為簡譯,更為詳細的內容,請檢視 原文 。