機器學習第九周 主成分分析PCA

機器學習 第九周 主成分分析

學習目標

知識點描述:無監督降維:主成分分析法

學習目標:

  • 主成分分析法的思想及其原理
  • PCA算法的實現及調用
  • 數據降維應用:降噪&人臉識別

學習內容

數據降維1:主成分分析法思想及原理

數據降維2:PCA算法的實現及使用

數據降維3:降維映射及PCA的實現與使用

數據降維之應用:降噪&人臉識別

學習ing

主成分分析 PCA principal Component Analysis, 是一種使用最廣泛的數據降維算法(非監督的機器學習方法),其主要用途在於降維,也可以用來消減迴歸分析和聚類分類中變量的數目。

主成分分析法的步驟:

第一步:樣本歸0;第二步:找到樣本映射後方差最大的單位向量
var(x)=1mi=1m(xix)2,x=00 var(x)=\frac{1}{m}\sum_{i=1}^{m}(x_i-\overline{x})^2,\overline{x}=0 樣本歸0 ,即所有數值減去均值

var(x)=1mi=1mXi2 映射後var(x)=\frac{1}{m}\sum_{i=1}^{m}||X_{映射}^i||^2

X(i)w=X(I).wcosθ,w X^{(i)}w = ||X^{(I)}||.||w||cos \theta,當w時單位向量時

=X(i)cosθ=Xproject(i) =||X^{(i)}||cos \theta = ||X_{project}^{(i)}||

主成分分析的目標是:
w使var(Xproject)=1m(X(i)w)2 求w,使得var(X_{project})=\frac{1}{m}(X^{(i)}w)^2最大
像之前目標函數有了,求最大值的參數。可以使用搜索策略,梯度上升法。
(ak+1,bk+1)=(ak+1+ηLa,bk+1+ηLb) (a_{k+1},b_{k+1})=(a_{k+1}+\eta \frac{\partial L}{\partial{a}},b_{k+1}+\eta \frac{\partial L}{\partial{b}})
在這裏插入圖片描述

求解第一個主成分

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)

對於一組數據,通過傳入解釋方差比例,能夠得到其準確率條件下的降維數據。然後再根據降維後的結果去做其他運算。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章