国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

機(jī)器學(xué)習(xí)之PCA與梯度上升法

curried / 2195人閱讀

摘要:主成分分析,簡(jiǎn)稱是一種非監(jiān)督學(xué)習(xí)的機(jī)器算法,主要用于數(shù)據(jù)的降維。對(duì)于的目標(biāo)函數(shù)求使得最大,可以使用梯度上升法來解決。利用梯度公式的梯度上升法實(shí)際上是批量梯度上升法還有隨機(jī)梯度上升法和小批量梯度上升法,本文不涉及。

主成分分析(Principle Component Analysis,簡(jiǎn)稱:PCA)是一種非監(jiān)督學(xué)習(xí)的機(jī)器算法,主要用于數(shù)據(jù)的降維。

PCA 基本原理

以有2個(gè)特征的二維平面舉例,如圖:

橫軸表示特征1,縱軸表示特征2,其中4個(gè)點(diǎn)表示二維的特征樣本。如果要對(duì)樣本進(jìn)行降維降到一維,可以將這些點(diǎn)映射到橫軸、縱軸或者其它軸上如:

映射到不同的軸后樣本間間距會(huì)不一樣,而要找的就是讓樣本間間距最大的軸。假定這個(gè)軸方向?yàn)?$w = (w1, w2)$。

對(duì)于樣本間間距可以用方差 $Var(x) = frac{1}{m}sum_{i=1}^m(x_i-overline x)^2$ 來衡量,方差越大,樣本間越稀疏。

接著進(jìn)行均值歸0(demean)處理,即 $overline x = 0$,使得 $Var(x) = frac{1}{m}sum_{i=1}^m(x_i)^2$。均值歸0處理使得原始樣本發(fā)生了變化轉(zhuǎn)換成了新的樣本 $X$。將其映射到軸 $w$ 上又得到新的樣本 $X_{pr}$,此時(shí)的方差為:

$$ Var(X_{pr}) = frac{1}{m}sum_{i=1}^m(X_{pr}^{(i)})^2 $$

因?yàn)?$X_{pr}^{(i)}$ 是一個(gè)向量 $(X_{pr1}^{(i)}, X_{pr2}^{(i)})$,所以實(shí)際的方差表示為:

$$ Var(X_{pr}) = frac{1}{m}sum_{i=1}^m||X_{pr}^{(i)}||^2 $$

最后計(jì)算 $||X_{pr}^{(i)}||$,如圖所示:

$||X_{pr}^{(i)}|| = X^{(i)}·w$ ($w$ 為單位向量),如此得到了想要的目標(biāo)函數(shù):

求 $w$ 使得 $Var(X_{pr}) = frac{1}{m}sum_{i=1}^m(X^{(i)}·w)^2$ 最大;對(duì)于多維特征,即 $frac{1}{m}sum_{i=1}^m(X_1^{(i)}w_1+X_2^{(i)}w_2+...+X_n^{(i)}w_n)^2$ 最大。

梯度上升法解決PAC問題

在梯度上升法中,$+eta abla f$ 代表了 $f$ 增大的方向。

對(duì)于 PAC 的目標(biāo)函數(shù):求 $w$ 使得 $f(X) = frac{1}{m}sum_{i=1}^m(X_1^{(i)}w_1+X_2^{(i)}w_2+...+X_n^{(i)}w_n)^2$ 最大,可以使用梯度上升法來解決。

$f(X)$ 的梯度為:

$$ abla f = egin{pmatrix} frac{partial f}{partial w_1} frac{partial f}{partial w_2} cdots frac{partial f}{partial w_n} end{pmatrix} = frac{2}{m} egin{pmatrix} sum_{i=1}^{m}(X_1^{(i)}w_1+X_2^{(i)}w_2+...+X_n^{(i)}w_n)X_1^{(i)} sum_{i=1}^{m}(X_1^{(i)}w_1+X_2^{(i)}w_2+...+X_n^{(i)}w_n)X_2^{(i)} cdots sum_{i=1}^{m}(X_1^{(i)}w_1+X_2^{(i)}w_2+...+X_n^{(i)}w_n)X_n^{(i)} end{pmatrix} = frac{2}{m} egin{pmatrix} sum_{i=1}^{m}(X^{(i)}w)X_1^{(i)} sum_{i=1}^{m}(X^{(i)}w)X_2^{(i)} cdots sum_{i=1}^{m}(X^{(i)}w)X_n^{(i)} end{pmatrix} = frac{2}{m}·X^T(Xw) $$

注:這里略去了轉(zhuǎn)換過程。

利用梯度公式 $
abla f =   frac{2}{m}·X^T(Xw)$ 的梯度上升法實(shí)際上是批量梯度上升法(還有隨機(jī)梯度上升法和小批量梯度上升法,本文不涉及)。
梯度上升法求主成分 求第一主成分

首先定義一組有兩個(gè)特征的數(shù)據(jù)集 $X$,共100個(gè)樣本:

import numpy as np

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)

$X$ 可視化如圖:

demean() 方法對(duì) $X$ 進(jìn)行均值歸0處理:

def demean(X):
    return X - np.mean(X, axis=0)

X_demean = demean(X)

均值歸0處理后的 $X\_demean$ 可視化如圖:

f() 方法求函數(shù) $f$ 的值:

def f(w, X):
    return np.sum(X.dot(w) ** 2) / len(X)

df() 方法根據(jù)梯度公式 $ abla f = frac{2}{m}·X^T(Xw)$ 求梯度:

def df(w, X):
    return X.T.dot(X.dot(w)) * 2 / len(X)

gradient_ascent() 方法為梯度上升法的過程,在 n_iters 次循環(huán)中,每次獲得新的 $w$,如果新的 $w$ 和舊的 $w$ 對(duì)應(yīng)的函數(shù) $f$ 的值的差值滿足精度 epsilon,則表示找到了合適的 $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:
        gradient = df(w, X)
        last_w = w
        w = w + eta * gradient
        w = direction(w)  # 將w轉(zhuǎn)換成單位向量
        if(abs(f(w, X) - f(last_w, X)) < epsilon):
            break
            
        cur_iter += 1
        
    return w

其中調(diào)用了一個(gè)方法 direction(),用于將 $w$ 轉(zhuǎn)換成單位向量:

def direction(w):
    return w / np.linalg.norm(w)

接著使用梯度上升法,先設(shè)定一個(gè)初始的 $w$ 和學(xué)習(xí)率 $eta$:

initial_w = np.random.random(X.shape[1])
eta = 0.001

直接調(diào)用 gradient_ascent() 方法:

w = gradient_ascent(X_demean, initial_w, eta)

將得到的 $w$ 與樣本可視化如圖($w$ 以直線表示):

求前n個(gè)主成分

前面求出了第一主成分,如何求出下一個(gè)主成分呢?以二維特征為例,如圖:

樣本 $X^{(i)}$ 在第一主成分 $w$ 上的分量為 $(X_{pr1}^{(i)}, X_{pr2}^{(i)})$,下一個(gè)主成分上的分量 $X^{"(i)} = X^{(i)} - (X_{pr1}^{(i)}, X_{pr2}^{(i)})$,因此只需將數(shù)據(jù)在第一主成分上的分量去掉,再對(duì)新的數(shù)據(jù)求第一主成分即可。

first_n_component() 方法用于求 $X$ 的前 n 個(gè)主成分,在 for 循環(huán)中每次求主成分時(shí)都設(shè)定一個(gè)隨機(jī)的 $w$(initial_w),得到一個(gè)主成分后就去掉在這個(gè)主成分上的分量 X_pca = X_pca - X_pca.dot(w).reshape(-1, 1) * w

def first_n_component(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
降維映射

得到了多個(gè)主成分后,就可以通過這些主成分將高維數(shù)據(jù)映射到低維數(shù)據(jù)。

對(duì)于有 m 個(gè)樣本,n 個(gè)特征的高維數(shù)據(jù) $X$(m*n),主成分分析后得到前 k(k

$$ X = egin{pmatrix} X_1^{(1)} X_2^{(1)} cdots X_n^{(1)} X_1^{(2)} X_2^{(2)} cdots X_n^{(2)} cdots cdots cdots cdots X_1^{(m)} X_2^{(m)} ... X_n^{(m)} end{pmatrix}, W_k= egin{pmatrix} W_1^{(1)} W_2^{(1)} cdots W_n^{(1)} W_1^{(2)} W_2^{(2)} cdots W_n^{(2)} cdots cdots cdots cdots W_1^{(k)} W_2^{(k)} ... W_n^{(k)} end{pmatrix} $$

n 維降維到 k 維后的新數(shù)據(jù)為:$X_k = X·W_k^T$。

在這個(gè)降維的過程中可能會(huì)丟失信息。如果原先的數(shù)據(jù)中本身存在一些無用信息,降維也可能會(huì)有降燥效果。

也可以將降維后的新數(shù)據(jù)恢復(fù)到原來的維度:$X_m = X_k·W_k$。

實(shí)現(xiàn) PCA

定義一個(gè)類 PCA,構(gòu)造函數(shù)函數(shù)中 n_components 表示主成分個(gè)數(shù)即降維后的維數(shù),components_ 表示主成分 $W_k$;

函數(shù) fit() 與上面的 first_n_component() 方法一樣,用于求出 $W_k$;

函數(shù) transform() 將 $X$ 映射到各個(gè)主成分分量中,得到 $X_k$,即降維;

函數(shù) transform() 將 $X_k$?映射到原來的特征空間,得到 $X_m$。

import numpy as np


class PCA:
    def __init__(self, n_components):
        self.n_components = n_components
        self.components_ = None

    def fit(self, X, eta=0.001, n_iters=1e4):
        def demean(X):
            return X - np.mean(X, axis=0)

        def f(w, X):
            return np.sum(X.dot(w) ** 2) / len(X)

        def df(w, X):
            return X.T.dot(X.dot(w)) * 2 / len(X)

        def direction(w):
            return w / np.linalg.norm(w)

        def first_component(X, initial_w, eta, n_iters, epsilon=1e-8):
            w = direction(initial_w)
            cur_iter = 0
            
            while cur_iter < n_iters:
                gradient = df(w, X)
                last_w = w
                w = w + eta * gradient
                w = direction(w) 
                if(abs(f(w, X) - f(last_w, X)) < epsilon):
                    break
                    
                cur_iter += 1
                
            return w
        
        X_pca = demean(X)
        self.components_ = np.empty(shape=(self.n_components, X.shape[1]))

        for i in range(self.n_components):
            initial_w = np.random.random(X_pca.shape[1])
            w = first_component(X_pca, initial_w, eta, n_iters)
            self.components_[i:] = w
            
            X_pca = X_pca - X_pca.dot(w).reshape(-1, 1) * w
        
        return self

    def transform(self, X):
        return X.dot(self.components_.T)

    def inverse_transform(self, X):
        return X.dot(self.components_)

?

Scikit Learn 中的 PCA

Scikit Learn 中的 PCA 使用的不是梯度上升法,而是使用的相應(yīng)的數(shù)學(xué)方法。使用方式如下:

from sklearn.decomposition import PCA

pca = PCA(n_components=1)

參數(shù) n_components 表示主成分個(gè)數(shù)。

由于 PCA 降維會(huì)丟失原數(shù)據(jù)的信息,Scikit Learn 中的 PCA 在 0 < n_components < 1 時(shí)表示降維的過程保留多少信息,如:

pca = PCA(0.95)

即保留原數(shù)據(jù) 95% 的信息,此時(shí)程序會(huì)自動(dòng)得到一個(gè) components_

借助 kNN 看 PCA

現(xiàn)在借助于 kNN 分類算法來看一看 PCA 的優(yōu)勢(shì)。首先使用一個(gè)正規(guī)的手寫數(shù)據(jù)集 MNIST 數(shù)據(jù)集,獲取樣本數(shù)據(jù)集的程序?yàn)椋?/p>

import numpy as np
from sklearn.datasets import fetch_mldata

mnist = fetch_mldata("MNIST original")
X, y = mnist["data"], mnist["target"]

# MNIST 數(shù)據(jù)集已經(jīng)默認(rèn)分配好了訓(xùn)練數(shù)據(jù)集和測(cè)試數(shù)據(jù)集,即前60000個(gè)數(shù)據(jù)為訓(xùn)練數(shù)據(jù)
X_train = np.array(X[:60000], dtype=float)
y_train = np.array(y[:60000], dtype=float)
X_test = np.array(X[60000:], dtype=float)
y_test = np.array(y[60000:], dtype=float)

先不使用 PCA 來看看 kNN 算法的效率:

from sklearn.neighbors import KNeighborsClassifier

knn_clf = KNeighborsClassifier()
%time knn_clf.fit(X_train, y_train)

此時(shí) fit 的過程消耗的時(shí)間為:

CPU times: user 29.6 s, sys: 306 ms, total: 29.9 s
Wall time: 30.7 s

接著驗(yàn)證測(cè)試數(shù)據(jù)集的準(zhǔn)確性:

%time knn_clf.score(X_test, y_test)

此過程消耗的時(shí)間為:

CPU times: user 10min 23s, sys: 2.05 s, total: 10min 25s
Wall time: 10min 31s

并且測(cè)試數(shù)據(jù)集的正確率為0.9688。

然后在來看看 PCA 的優(yōu)勢(shì),使用 PCA 時(shí),設(shè)定保留信息為 90%:

from sklearn.decomposition import PCA

pca = PCA(0.9)
pca.fit(X_train)
X_train_reduction = pca.transform(X_train)

knn_clf = KNeighborsClassifier()
%time knn_clf.fit(X_train_reduction, y_train)

此時(shí) fit 的過程消耗的時(shí)間為:

CPU times: user 317 ms, sys: 5.31 ms, total: 323 ms
Wall time: 323 ms

接著驗(yàn)證測(cè)試數(shù)據(jù)集的準(zhǔn)確性:

X_test_reduction = pca.transform(X_test)
%time knn_clf.score(X_test_reduction, y_test)

此過程消耗的時(shí)間為:

CPU times: user 1min 15s, sys: 469 ms, total: 1min 15s
Wall time: 1min 17s

可以看出使用 PCA 后時(shí)間的消耗大大減少,而測(cè)試數(shù)據(jù)集的正確率為0.9728,不僅正確率沒有降低還增加了,這是因?yàn)檫@里的降維過程丟失的信息是無用的信息從而達(dá)到了降燥效果。

源碼地址

Github | ML-Algorithms-Action

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/42653.html

相關(guān)文章

  • 機(jī)器學(xué)習(xí)之梯度下降線性回歸

    摘要:表示學(xué)習(xí)率,是梯度下降法的一個(gè)超參數(shù),其取值影響最優(yōu)解的速度。因此在使用梯度下降法之前,最好進(jìn)行數(shù)據(jù)歸一化。同時(shí)在隨機(jī)梯度下降法中學(xué)習(xí)率的取值是逐漸遞減的,為了防止固定取值的學(xué)習(xí)率使得梯度下降到達(dá)最優(yōu)解附近時(shí)繼續(xù)跳出這個(gè)范圍。 梯度下降法不是一個(gè)機(jī)器學(xué)習(xí)算法,而是一種基于搜索的最優(yōu)化方法,用于最小化一個(gè)效用函數(shù)。 簡(jiǎn)單理解梯度下降法 假設(shè)存在一個(gè)只有一個(gè)參數(shù) $ heta$ 的損失函數(shù)...

    cod7ce 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<