機器學習 第九周 主成分分析
學習目標
知識點描述:無監督降維:主成分分析法
學習目標:
- 主成分分析法的思想及其原理
- PCA算法的實現及調用
- 數據降維應用:降噪&人臉識別
學習內容
學習ing
主成分分析 PCA principal Component Analysis, 是一種使用最廣泛的數據降維算法(非監督的機器學習方法),其主要用途在於降維,也可以用來消減迴歸分析和聚類分類中變量的數目。
主成分分析法的步驟:
第一步:樣本歸0;第二步:找到樣本映射後方差最大的單位向量
主成分分析的目標是:
像之前目標函數有了,求最大值的參數。可以使用搜索策略,梯度上升法。
求解第一個主成分
import numpy as np
import matplotlib.pyplot as plt
X = np.empty([100,2])
X[:,0] = np.random.uniform(0.,100.,size =100)
X[:,1] = 0.75 * X[:,0] + 3. + np.random.normal(0.,10.,size = 100)
plt.scatter(X[:,0],X[:,1])
plt.show()
#第一步歸0 ,axis按列計算均值
def demean(X):
return (X - np.mean(X, axis= 0 ))
X_demean = demean(X)
plt.scatter(X_demean[:, 0],X_demean[:, 1])
plt.show()
#X_demean
#目標函數的定義
def f(w,X):
return np.sum(X.dot(w)**2) /len(X[:,0])
#梯度
def df_math(w,X):
return 2*X.T.dot(X.dot(w)) / len(X[:,0])
#驗證梯度調式
def df_debug(w, X, epsilon = 0.0001):
res = np.empty(len(w))
for i in range(len(w)):
w_1 = w.copy()
w_1[i] += epsilon
w_2 = w.copy
w_2[i] -= epsilon
res[i] = (f(w_1,X) - f(w_2, X)) / (2*epsilon)
return res
def direction(w):#求第二範數,計算單位向量
return w / np.linalg.norm(w)
#梯度上升法代碼
def gradient_ascent(X,initial_w ,eta ,n_iters=1e4, epsilon = 1e-8):
w = direction(initial_w)
cur_iter = 0
while cur_iter < n_iters:
last_w = w
gradient = df_math( w, X)
w = last_w + eta * gradient
#w每次計算前均是單位向量
w = direction(w)
if abs(f(w,X) - f(last_w,X)) < epsilon :
break
cur_iter += 1
return w
#
initial_w = np.random.random(X.shape[1])
eta = 0.001
w = gradient_ascent(X, initial_w , eta)
w
array([0.77535907, 0.63152063])
plt.scatter(X_demean[:,0] ,X_demean[:,1])
plt.plot([0,w[0]*30],[0,w[1]*30] ,color='red')# x,y (0,0) (21,18) 連線
y = w[0] * X_demean[:,0] + w[1] * X_demean[:,1]
plt.plot(X)
plt.show()
求解第二個主成分
X_new = X - X.dot(w).reshape(-1,1)*w #w?
plt.scatter(X_new[:,0],X_new[:,1])
plt.show()
w_new = gradient_ascent(X_new ,initial_w , eta)
w_new
#array([-0.63150239, 0.77537393])
求解前n個主成分
#求解前n個主成分
def first_n_componet(n, X,eta = 0.001, n_iters = 1e4, epsilon = 1e-8):
X_pca = X.copy()
X_pca = demean(X_pca)
res = []
for i in range(n):
initial_w = np.random.random(X_pca.shape[1])
w = gradient_ascent(X_pca, initial_w, eta)
res.append(w)
X_pca = X_pca - X_pca.dot(w).reshape(-1,1) * w
return res
res = first_n_componet(2, X)
res
#[array([0.7676373 , 0.64088453]), array([-0.64086321, 0.7676551 ])]
K維的選擇影響最終的結果精度,在sklearn中定義解釋方差比例,通過提前定義解釋的百分比pca.explained_variance_ratio,可以得到降維的k。繼而根據前n個主成分進行求解。
from sklearn.decomposition import PCA
pca = PCA(n_components = 1)#直接傳入主成分個數
pca.fit(X)
X_reduction = pca.transform(X) #降維
pca = PCA(0.95)
pca.fit(X_train)
# 輸出:
PCA(copy=True, iterated_power='auto', n_components=0.95, random_state=None,
svd_solver='auto', tol=0.0, whiten=False)
對於一組數據,通過傳入解釋方差比例,能夠得到其準確率條件下的降維數據。然後再根據降維後的結果去做其他運算。