代码出自【日】立石贤吾.白话机器学习的数学
学习阶段,尽可能记录自己学习中的所有出现的问题和解决方案。
非科班学生,对于代码实现方面较为生疏,在记录时侧重代码理解,不重推导过程。
本章用以复现书中第六章的第六部分代码,正则化回归。
本节也是机器学习的最后一个章节,后续会更新自己的学习心得。
---------------------------------------------------------------------------------------------------------------------------------
import numpy as np
import matplotlib.pyplot as plt
#真实函数
def g(x):
return 0.1*(x**3+x**2+x)
#随机加点数据
train_x=np.linspace(-2,2,8)
train_y=g(train_x)+np.random.rand(train_x.size)*0.06
#train_x是一组从-2到2的等差数列,共八个数,train_y在x0.06(这里也可以变为别的倍数)之前是根据train_x随机上下波动生成的八个数,他和train_x的距离符合正态分布
#之前用的随机数生成都是random.rand,这里用的是random.randn。rand是完全随机生成0-1内的数,randn是根据正态分布形成,在本实验中,未发现区别
#标准化
mu=train_x.mean()
sigma=train_x.std()
def standardize(x):
return (x-mu)/sigma
train_s=standardize(train_x)
#创建训练模型,这里要采用一种能导致过拟合的数据,我们选用十维多项式
def to_matrix(x):
return np.vstack([np.ones(x.size),x,x**2,x**3,x**4,x**5,x**6,x**7,x**8,x**9,x**10]).T
X=to_matrix(train_s)
#参数初始化
theta=np.random.rand(X.shape[1])
#这里是X矩阵第一行的数量,从x**0到x**10共11个数
#预测函数
def f(x):
return np.dot(x,theta)
#本部分为非正则化实现预测
#误差
def E(x,y):
return 0.5*np.sum((y-f(x))**2)
#学习率和初始误差
ETA=1e-4
diff=1
#训练过程
error=E(X,train_y)
while diff>1e-6:
theta=theta-ETA*np.dot(f(X)-train_y,X)
current_error=E(X,train_y)
diff=error-current_error
error=current_error
#保存参数
theta1=theta
#本部分为正则化实现预测
#重新初始化参数
theta=np.random.rand(X.shape[1])
#正则化常量
LAMBDA=1
#误差重置
diff=1
#训练过程(含正则化项)
error=E(X,train_y)
while diff>1e-6:
reg_term=LAMBDA*np.hstack([0,theta[1:]])
theta=theta-ETA*(np.dot(f(X)-train_y,X)+reg_term)
current_error=E(X,train_y)
diff=error-current_error
error=current_error
#对比绘图
x=np.linspace(-2,2,100)
z=standardize(x)
theta2=theta
plt.plot(train_s,train_y,'o')
theta=theta1
plt.plot(z,f(to_matrix(z)),linestyle='dashed')
theta=theta2
plt.plot(z,f(to_matrix(z)))
plt.show()
#注意第一行,x在前文中并未使用,首次出现在p208,这里需要先设定
#虚线部分是未正则化的实现,实线部分是正则化的实现
最终输出结果: