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

在这里插入图片描述在这里插入图片描述

代码实现:

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()

结果:
在这里插入图片描述

#%% demean

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

X_demean = demean(X)

plt.scatter(X_demean[:,0],X_demean[:,1])
plt.show()

结果:在这里插入图片描述

np.mean(X_demean[:,0])
3.552713678800501e-16
np.mean(X_demean[:,1])
-5.684341886080802e-16

即,结果近似为 0 .

#%% 梯度上升法

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

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

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(df,X,initial_w,eta,n_iters = 1e4,epsilon=1e-8):
    
    w = direction(initial_w)
    cur_iter = 0    # 初值设为0

    while cur_iter < n_iters:
        gradient = df(w,X)
        last_w = w
        w = w + eta * gradient    #'+'上升
        w = direction(w)    #注意:1.每次求一个单位方向
        if(abs(f(w,X) - f(last_w,X)) < epsilon):
            break

        cur_iter += 1

    return w

initial_w = np.random.random(X.shape[1])   #注意:2.不能用0向量开始
initial_w

eta = 0.001

#注意:3.不能使用 StandardScaler 标准化数据

有:

gradient_ascent(df_debug,X_demean,initial_w,eta)
array([0.78728038,0.61659517])
gradient_ascent(df_math,X_demean,initial_w,eta)
array([0.78728038, 0.61659517])
w = gradient_ascent(df_math,X_demean,initial_w,eta)

plt.scatter(X_demean[:,0],X_demean[:,1])
plt.plot([0,w[0]*50],[0,w[1]*50],color='r')
plt.show()

在这里插入图片描述
去掉添加的随机噪音:

X2 = np.empty((100,2))
X2[:,0] = np.random.uniform(0.,100.,size=100)
X2[:,1] = 0.75 * X2[:,0] + 3. 
plt.scatter(X2[:,0],X2[:,1])
plt.show()

在这里插入图片描述

X2_demean = demean(X2)
w2 = gradient_ascent(df_math,X2_demean,initial_w,eta)

plt.scatter(X2_demean[:,0],X2_demean[:,1])
plt.plot([0,w2[0]*50],[0,w2[1]*50],color='r')
plt.show()

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值