import numpy as np
from matplotlib import pyplot as plt
import random
def generate_data(exponent, size,begin, end):
X = np.linspace(begin, end, size)
Y = np.sin(2*X*np.pi)
mu = 0
sigma = 0.12
for i in range(X.size):
X[i] += random.gauss(mu, sigma)
Y[i] += random.gauss(mu, sigma)
train_x = np.zeros((exponent + 1, size))
train_y = Y.reshape(size, 1)
train_x = np.vander(X, exponent + 1, increasing=True)
return train_x, train_y, X, Y
def cal_w(train_x, train_y, lamda,exponent):
return np.linalg.inv(np.dot(train_x.T,train_x)+lamda*np.identity(exponent+1, dtype=float)).dot(train_x.T).dot(train_y)
def lsm(train_x, train_y, lamda,exponent):
w=cal_w(train_x, train_y, lamda,exponent)
poly_fitting = np.poly1d(w[::-1].reshape(train_x.shape[1]))
return poly_fitting
def loss(train_x, train_y, w, lamda):
loss = train_x.dot(w) - train_y
loss = 1 / 2 * np.dot(loss.T, loss) + lamda / 2 * np.dot(w.T, w)
return loss
def gradient_descent(train_x, train_y,lamda,alpha,epsilon,exponent,times):
w = cal_w(train_x, train_y, lamda, exponent)
new_loss = abs(loss(train_x, train_y, w, lamda))
for i in range(times):
old_loss = new_loss
gradient_w = np.dot(train_x.T, train_x).dot(w) - np.dot(train_x.T, train_y) + lamda * w
old_w = w
w -= gradient_w * alpha
new_loss = abs(loss(train_x, train_y, w, lamda))
gradient_w = np.dot(train_x.T, train_x).dot(w) - np.dot(train_x.T, train_y) + lamda * w
if old_loss < new_loss:
w = old_w
alpha /= 2
if (old_loss - new_loss < epsilon)&(np.linalg.norm(gradient_w)<=epsilon) :
break
poly_fitting = np.poly1d(w[::-1].reshape(train_x.shape[1]))
return poly_fitting, i
def conjugate_descent(train_x, train_y,lamda,epsilon,exponent):
A=np.dot(train_x.T, train_x)+lamda*np.identity(exponent+1, dtype=float)
b=np.dot(train_x.T,train_y)
w = np.zeros((train_x.shape[1], 1))
r = b
p = b
i = 0
while True:
i = i + 1
norm_2 = np.dot(r.T, r)
a = norm_2 / np.dot(p.T, A).dot(p)
w = w + a * p
r = r - (a * A).dot(p)
if r.T.dot(r) < epsilon:
break
b = np.dot(r.T, r) / norm_2
p = r + b * p
print(i)
poly_fitting = np.poly1d(w[::-1].reshape(train_x.shape[1]))
return poly_fitting
def plt_show(x, y, poly_fit):
plot1 = plt.plot(x, y, 'co', label='training_data')
real_x = np.linspace(0,1)
real_y = np.sin(real_x * 2 * np.pi)
fit_y = poly_fit(real_x)
plot2 = plt.plot(real_x, fit_y, 'b', label='fit_poly')
plot3 = plt.plot(real_x, real_y, 'r', label='real_ploy')
plt.legend(loc=0)
plt.show()
print(poly_fit)
def Rmse(train_x, train_y,train_size,test_x,test_y,exponent,test_size):
ln_lamda = np.linspace(-10,0,50)
rms_train = np.zeros(50)
rms_test = np.zeros(50)
for i in range(0, 50):
lamda = np.exp(ln_lamda[i])
w = cal_w(train_x, train_y, lamda,exponent)
Ew_train = loss(train_x, train_y,w,lamda)
rms_train[i] = np.sqrt(2 * Ew_train / train_size)
Ew_test=loss(test_x, test_y, w,lamda)
rms_test[i] = np.sqrt(2 * Ew_test / test_size)
train_plot = plt.plot(ln_lamda, rms_train, 'b', label='train')
test_plot = plt.plot(ln_lamda, rms_test, 'r', label='test')
plt.xlabel('lamda')
plt.ylabel('Rms')
plt.legend(loc=0)
plt.show()
def comparsion_show(x, y, poly_fit,punish_poly):
plot1 = plt.plot(x, y, 'co', label='training_data')
real_x = np.linspace(0,1)
real_y = np.sin(real_x * 2 * np.pi)
fit_y = poly_fit(real_x)
plot2 = plt.plot(real_x, fit_y, 'b', label='fit_poly')
plot3 = plt.plot(real_x, real_y, 'r', label='real_ploy')
polt4=plt.plot(real_x,punish_poly(real_x),'k',label='punish_poly')
plt.legend(loc=0)
plt.show()
print(poly_fit)
import DataMaker
import numpy as np
epsilon = 1e-9
import matplotlib.pyplot as plt
if __name__=='__main__':
'''# 最小二乘法求解析解(无正则项) lamda=0
begin, end, exponent,lamda,size = 0, 1, 9, np.exp(-10),20
train_x, train_y, x,y=DataMaker.generate_data(exponent,size,begin,end)
poly = DataMaker.lsm(train_x, train_y,lamda,exponent)
DataMaker.plt_show(x,y,poly)'''
begin, end, exponent, lamda, size = 0, 1, 9, 0, 10
alpha=0.01
train_x, train_y, x, y = DataMaker.generate_data(exponent, size, begin, end)
poly,i=DataMaker.gradient_descent(train_x, train_y,lamda,alpha,epsilon,exponent,times=10000000)
print(i)
DataMaker.plt_show(x, y, poly)
'''begin, end, exponent, lamda, size = 0, 1, 50, np.exp(-10),50
train_x, train_y, x, y = DataMaker.generate_data(exponent, size, begin, end)
poly=DataMaker.conjugate_descent(train_x, train_y,lamda,epsilon,exponent)
DataMaker.plt_show(x, y, poly)
begin, end, exponent, lamda, size = 0, 1, 9, 0, 10
train_x, train_y, x, y = DataMaker.generate_data(exponent, size, begin, end)
test_x, test_y,X,Y=DataMaker.generate_data(exponent,20,0, 1)
DataMaker.Rmse(train_x,train_y,10,test_x,test_y,exponent,20)
begin, end, exponent, lamda, size = 0, 1, 9, np.exp(-10), 10
train_x, train_y, x, y = DataMaker.generate_data(exponent, size, begin, end)
poly = DataMaker.lsm(train_x, train_y, 0, exponent)
punish_poly = DataMaker.lsm(train_x, train_y, lamda, exponent)
DataMaker.comparsion_show(x,y,poly,punish_poly)'''