liuyubobobo《机器学习》学习笔记(十)

主成分分析 PCA


1.主成分分析Principal Component Analysis

是一个非监督的机器学习算法,主要用于数据的降维

通过降维,可以发现更便于人类理解的特征

其他应用:可视化,去噪

2.主成分分析的推导过程

考虑这样一个过程:将二维数据降维到一维

最好的方案为:找到一个轴,使得样本空间的所有点映射到这个轴后,间距最大

样本间间距——方差

主成分分析

首先,将样例的均值归为0(demean),方差公式变为: V a r ( x ) = 1 m ∑ i = 1 m ( x i − x ‾ ) 2 = 1 m ∑ i = 1 m x i 2 Var(x) = \frac{1}{m}\sum_{i=1}^{m}(x_i - \overline{x})^2 = \frac{1}{m}\sum_{i=1}^{m}x_i^2 Var(x)=m1i=1m(xix)2=m1i=1mxi2

在这里插入图片描述

目标为:求一个轴的方向 w = ( w 1 , w 2 ) w = (w_1, w_2) w=(w1,w2),使得所有的样本映射到 w w w以后,有 V a r ( X p r o j e c t ) = 1 m ∑ i = 1 m ∣ ∣ X p r o j e c t ( i ) ∣ ∣ 2 Var(X_{project}) = \frac{1}{m}\sum_{i=1}^m||X_{project}^{(i)}||^2 Var(Xproject)=m1i=1mXproject(i)2 最大

进一步考虑, w w w为单位向量,则 ∣ ∣ X p r o j e c t ( i ) ∣ ∣ ||X_{project}^{(i)}|| Xproject(i)可以写成 X ( i ) X^{(i)} X(i) w w w的点积 X ( i ) ⋅ w X^{(i)}\cdot w X(i)w

在这里插入图片描述

目标变为:求 w w w,使得 V a r ( X p r o j e c t ) = 1 m ∑ i = 1 m ( X ( i ) ⋅ w ) 2 = 1 m ∑ i = 1 m ( X 1 ( i ) w 1 + X 2 ( i ) w 2 + . . . + X n ( i ) w n ) 2 Var(X_{project}) = \frac{1}{m}\sum_{i=1}^{m}(X^{(i)}\cdot w)^2 = \frac{1}{m}\sum_{i=1}^{m}(X_1^{(i)}w_1 + X_2^{(i)}w_2+...+X_n^{(i)}w_n)^2 Var(Xproject)=m1i=1m(X(i)w)2=m1i=1m(X1(i)w1+X2(i)w2+...+Xn(i)wn)2 最大

这是一个目标函数的最优化问题,可以使用梯度上升法来解决

3.使用梯度上升法求解PCA问题

目标:求 w w w,使得 f ( X ) = 1 m ∑ i = 1 m ( X ( i ) ⋅ w ) 2 = 1 m ∑ i = 1 m ( X 1 ( i ) w 1 + X 2 ( i ) w 2 + . . . + X n ( i ) w n ) 2 f(X) = \frac{1}{m}\sum_{i=1}^m (X^{(i)}\cdot w)^2 = \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)=m1i=1m(X(i)w)2=m1i=1m(X1(i)w1+X2(i)w2+...+Xn(i)wn)2 最大

在这里插入图片描述

编程实现

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):   # 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:
        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

initial_w = np.random.random(X.shape[1])    # w不能初始化为0向量,因为这样梯度也为0
eta = 0.001
X_demean = demean(X)
w = gradient_ascent(X_demean, initial_w, eta)
4.求数据的前n个主成分

求出第一主成分后,如何求出下一个主成分?

答:将数据在第一个主成分上的分量去掉,再在新的数据上求第一主成分

在这里插入图片描述

X ( i ) X^{(i)} X(i)去掉第一个主成分上的分量 X p r o j e c t ( i ) X_{project}^{(i)} Xproject(i),得到 X ′ ( i ) X'^{(i)} X(i) X ′ ( i ) = X ( i ) − X p r o j e c t ( i ) X'^{(i)} = X^{(i)} - X_{project}^{(i)} X(i)=X(i)Xproject(i)

编程实现——求数据的前n个主成分

def first_n_components(n, X, eta=0.01, 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 = first_component(X_pca, initial_w, eta)   # 求出第一分量,参考上文梯度上升
        res.append(w)
        X_pca = X_pca - X_pca.dot(w).reshape(-1, 1) * w    # 去掉第一分量
        
    return res
5.高维数据向低维数据映射

将n维数据映射到k维空间上:

在这里插入图片描述

恢复:只是在高维空间内表达低位数据而已

在这里插入图片描述

PCA降维过程中,存在信息丢失,且无法恢复。

如下图,我们将蓝点用PCA降维,恢复后只能得到红点

在这里插入图片描述

6.scikit-learn中的PCA
from sklearn import datasets
from sklearn.model_selection import train_test_split
digits = datasets.load_digits()
X = digits.data
y = digits.target
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=666)

首先,使用KNN进行分类

%%time
# 使用KNN进行分类
from sklearn.neighbors import KNeighborsClassifier
knn_clf = KNeighborsClassifier()
knn_clf.fit(X_train, y_train)
knn_clf.score(X_test, y_test)

Wall time: 13.9 ms

0.9866666666666667

使用PCA进行数据的降维

# 使用PCA进行数据的降维
from sklearn.decomposition import PCA

pca = PCA(n_components=2)
pca.fit(X_train)     # 计算各主成分的方向w
X_train_reduction = pca.transform(X_train)
X_test_reduction = pca.transform(X_test)   # 必须将训练集和测试集降维到同样的低维空间

再使用KNN进行分类

%%time
# 再用KNN进行分类
knn_clf = KNeighborsClassifier()
knn_clf.fit(X_train_reduction, y_train)
knn_clf.score(X_test_reduction, y_test)

Wall time: 3 ms

0.6066666666666667

可以观察到,运行时间有明显的缩短,但是同样的,精度也在下降

这里,我们是将一个64维的数据降维到2维,那么2维是否是最合适的维数呢?

7.寻找最合适的维数

PCA有一个成员变量explained_variance_ratio_,可解释各主成分的方差占总方差的比率,占比越大,主成分越重要

计算上一个例子中的explained_variance_ratio_

pca.explained_variance_ratio_
# array([0.14566817, 0.13735469])

可以看出使用PCA降维到2维,只能解释28%的方差,会丢失70%以上的信息

下图为保留的信息与维数的关系

在这里插入图片描述

PCA可以自动选取合适的降维维数,只需提供欲保留的信息比例

pca = PCA(0.95)  # 至少保持95%的信息
pca.fit(X_train)
pca.n_components_
# 28
X_train_reduction = pca.transform(X_train)
X_test_reduction = pca.transform(X_test)
%%time
knn_clf = KNeighborsClassifier()
knn_clf.fit(X_train_reduction, y_train)
knn_clf.score(X_test_reduction, y_test)

Wall time: 5.53 ms

0.98

在至少保持95%的信息的前提下,PCA将数据降维到28维,运行时间和精度都有很好的保证

8.使用PCA进行降噪

使用PCA降维会丢失一部分信息,但如果其中含有相当一部分噪声,降维后分类任务的精度反而会提升

PCA降噪前

在这里插入图片描述

PCA降噪后(降维再恢复)

在这里插入图片描述

9.特征脸(Eigenface)

在这里插入图片描述

​      我们求出的 W k W_k Wk矩阵,每一行都是一个 n n n维向量,代表一个主成分,而每一行数据同样是一个n维向量,所以我们可以将一个主成分 w w w看作一行数据

​      在人脸识别中,对人脸数据集做PCA,得到全部主成分。将每一个主成分当作一个图像,绘制出来,就得到了特征脸

在这里插入图片描述

图片来源

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值