最小二乘法
基本思想:
最小二乘法则是一种统计学习优化技术,它的目标是最小化误差平方之和来作为目标,从而找到最优模型,这个模型可以拟合观察数据。 回归学习最常用的损失函数是平方损失函数,在此情况下,回归问题可以用著名的最小二乘法来解决。最小二乘法就是曲线拟合的一种解决方法。最小二乘的思想是使观测点好估计点的距离平方和最小,在古汉语中平方叫做二乘,最小指的是参数的估计值要保证各个观测点与估计点的距离平方和最小。
方程组求解方法:
对于拟合曲线所选择的特征函数,比如,可以用矩阵表示为
引入平方差函数: ,通过微分求最小值,可得:
,如果矩阵
可逆,可得
,可求得特征函数的参数
。
import numpy as np
from matplotlib import pyplot as plt
'''
最小二乘法拟合曲线
x:点的x坐标
y:点的y坐标
k:特征方程的次数
返回特征函数的参数以及预测值
'''
def calculate_wy(x, y, k):
A = []
for index in range(k + 1):
A.append(x ** (k - index))
A = np.array(A).T
B = y_.reshape(y_.shape[0], 1)
ws = np.linalg.inv(A.T.dot(A)).dot(A.T).dot(B) #B=(X^TX)^-1X^TY
pred = A.dot(ws)
return ws,pred
# 随机生成数据
x = np.linspace(-1, 1, 100)
y = 2.3*x*x + 3.5*x + 0.04
y_ = y + np.random.rand(len(x)) - 0.5
#绘制理想曲线以及实际曲线
# calculate A
w, pred_y = calculate_wy(x, y_, 3)
plt.scatter(x, y_)
plt.plot(x, y, 'k-')
plt.plot(x, pred_y, 'r-')
plt.show()
梯度下降法:
网上大佬们关于梯度下降法的介绍都很详细,在这里就说明一下刚开始看的时候比较纠结的问题,就是在最速下降法中,为什么相邻两次搜索方向必正交:
证明:设第k步的步长为
,梯度为
,则有第K+1步的梯度为
即
,两次搜索方向正交
拟合直线的代码实现,学习于stanford的机器学习视频
假设我们拟合y=ax+b的直线,矩阵化后可得:
,通过梯度下降法不断更新参数a,b
raw_X = [3333, 2222, 1111, 555]
raw_Y = [400, 200, 300, 150]
'''
数据的归一化处理,通过X=(X-average(X))/X.max
'''
X = np.array(raw_X)
Y = np.array(raw_Y)
X = X - (1/len(raw_X))*X.sum()
Y = Y - (1/len(raw_X))*Y.sum()
X = 1/X.max() * X
Y = 1/Y.max() * Y
plt.scatter(X, Y)
raw_X = X
raw_Y = Y
# 矩阵化拟合函数 y=ax+b
X = np.vstack((np.array([X.data]), np.ones([1, len(raw_X)]))).T
print(X)
Y = np.array([Y.data]).T
learning_rate = 0.1 # 学习率,用来控制步伐的大小
parameters = np.array([[0], [0]]) # 初始化的参数,设置为0可能会出现除数为0的情况
# 预测函数 y=ax+b
def Prediction(X, paras):
return X.dot(paras)
# 梯度下降函数
Costs = []
maxStep = 70
for step in range(maxStep):
P = Prediction(X, parameters)
# 对学习率的优化,在坡度大的时候取大值,小的时候取小值,防止出现震荡情况
a_ = 1/size * np.sum((P-Y)*X)
b_ = 1/size * np.sum(P-Y)
a = a - learning_rate*a_
b = b - learning_rate*b_
# print(P)
parameters = np.array([[a], [b]])
last_P = Prediction(X, parameters)
cost = abs(np.sum(last_P - Y))
Costs.append(cost)