基础知识:
回归是监督学习的这个重要问题,回归用于预测输入变量和输出变量之间的关系;
很好的拟合已知模型,并很好的预测未知模型;
什么是回归:
1,回归问题分为模型的学习和预测两个过程。基于给定训练数据集构建一个模型,根据新的输入数据预测相应的输出;
2,回归问题按照输入变量的个数可以分为一元回归和多元回归;
按照输入变量和输出变量之间的关系类型,可以分为线性回归和非线性回归
一元线性回归:
1,回归分析只涉及两个变量的,称为一元回归分析
2,一元回归的主要任务是从两个相关变量中的一个变量取估计另一个变量,被估计的变量称为因变量(Y);估计出的变量,称自变量(X)。
回归分析就是找一个模型Y=(X)
常用的案例:
根据工资,预测贷款额度---------回归问题
误差:
所有的误差都是独立同分布,且服从呈现高斯曲线的分布
公式(2)exp()指数的分子上(μ-epsion_i),μ是方差(其值为0)
机器学习:现有样本数据,倒过来求参数。
之前方法:现有参数,再求样本。
似然函数:已知发生了某些事件,我们希望知道参数是多少-------我们这里,已知x,y,需要求w,b应为累乘不好算,取log(),转化为累加。这个公式要会推!!!!有时候面试官会让推线性回归!
然后求J(w)最小时,w,b的值。
求偏导----求凸函数极值时
先求b的偏导,w的很难求。
对w求偏导:
这种求解方法:就是最小二乘法。
多元线性回归:
x0=1它是一个截距;在一维的时候,thetaT与theta是等价的。
注:这边由数学公式变成矩阵;
接下来对矩阵求导:
将X^TX看成一个量A,theta看成x,YTY是个常数,求导后为零。矩阵求导公式不需要记。(记住就可以theta公式)
注:
theta是一个有逆的矩阵,矩阵有一个性质:当X是满秩矩阵(方阵)的时候,才有唯一解;不是满秩的时候,它有多个解。那么我们不能知道哪个是最优解。(BAT大公司会让推数学公式)
所以,当遇到多元线性回归的时候,最小二乘法已经不再有效了。
这个时候,我们要用梯度下降算法去求。
补充知识:
(矩阵运算)—转置
矩阵求导公式:
参考:https://blog.csdn.net/daaikuaichuan/article/details/80620518
注意:矩阵的乘法,不能放错元素的位置:
梯度下降算法:
沿着梯度负方向增长,不断更新theta的值(根据规则);有一个步长a(每一次更新了多少),尽可能的小。注:theta是一个向量或者矩阵。
每一个元素都是要求偏导的。
简单实现:
import numpy as np
"""
梯度下降求解
"""
#模拟一元线性回归
X=[4,8,5,10,12]
y=[20,50,30,70,60]
#初始化参数
theta0=theta1=0
#学习率
alpha=0.00001
#迭代次数(开始为0)
cnt=0
#误差
error0=error1=0
#误差需要小于指定的阈值,指定一个阈值,用与检查两次误差的差,以便停止迭代
threshold=0.0000001
while True:
"""
迭代之前,计算梯度
"""
#梯度:diff[0]是theta0的梯度,diff[1]是theta1的梯度
diff=[0,0] #两个梯度都为0
m = len(X)
for i in range(m):
diff[0] += y[i]-(theta0+theta1*X[i])
diff[1] += (y[i]-(theta0+theta1*X[i]))*X[i]
theta0 = theta0+alpha*diff[0]
theta1 = theta1+alpha*diff[1] #批量梯度下降
#计算误差
for i in range(m):
error1 += (y[i]-(theta0+theta1*X[i]))**2
error1 /= m
if abs(error1-error0)<threshold:
break
else:
error0=error1
print(theta0,theta1,cnt)
def predict(theta0,theta1,x_test):
return theta0+theta1*x_test
print(predict(theta0,theta1,15))
···················································
输出:
1.2068624206638512 5.739106302152591 0
87.29345695295272
批量梯度下降:
梯度:沿着梯度的方向找最优值,能最快的找到。根据样本来求梯度,最简单的方式:将所有样本关进去,求梯度(求得的是最优梯度)。
批量梯度下降BGD:m是指平均的梯度;每次沿着梯度的负方向走,不断更新theta值。(最好加上学习率)
迭代终止条件:两次迭代误差很小(自己定义)。
做一个小练习:多远线性回归求theta0,theta1,theta2的值:
import numpy as np
"""
梯度下降求解
y=theta0+theta1*x1+theta2*x2
"""
#模拟多元线性回归
x_train=[[1,0,3],[1,1,3],[1,2,3],[1,3,2],[1,4,4]]
y_train=[95.364,97.217205,75.195834,60.105519,49.342380]
#初始化参数
theta0=theta1=theta2=0
#学习率
alpha=0.001
#迭代次数(开始为0)
cnt=0
#误差
error0=error1=0
#误差需要小于指定的阈值,指定一个阈值,用与检查两次误差的差,以便停止迭代
threshold=0.0000001
while True:
"""
迭代之前,计算梯度
"""
#梯度:diff[0]是theta0的梯度,diff[1]是theta1的梯度,diff[2]是theta2的梯度
diff=[0,0,0] #三个梯度都为0
m = len(y_train)
for i in range(m):
diff[0] += y_train[i]-(theta0+theta1*x_train[i][1]+theta2*x_train[i][2])
diff[1] += (y_train[i]-(theta0+theta1*x_train[i][1]+theta2*x_train[i][2]))*x_train[i][1]
diff[2] += (y_train[i]-(theta0+theta1*x_train[i][1]+theta2*x_train[i][2]))*x_train[i][2]
theta0 = theta0+alpha/m*diff[0]
theta1 = theta1+alpha/m*diff[1]
theta2 = theta2+alpha/m*diff[2] #批量梯度下降
#计算误差
for i in range(m):
error1 += (y_train[i]-(theta0+theta1*x_train[i][1]+theta2*x_train[i][2]))**2
error1 /= m
if abs(error1-error0)<threshold:
break
else:
error0=error1
cnt += 1
print(theta0,theta1,theta2,cnt)
def predict(theta0,theta1,theta2,x_test):
return theta0+theta1*x_test[1]+theta2*x_test[2]
print(predict(theta0,theta1,theta2,[1,4,3]))
···············································
输出结果:
97.94752684129175 -13.027666024195499 1.1822540575125826 164650
49.38573374264368
不除m
theta0 = theta0+alpha/m*diff[0]
theta1 = theta1+alpha/m*diff[1]
theta2 = theta2+alpha/m*diff[2]
···································
结果:
98.03409078963148 -13.028278855264572 1.1549194580234965 37106
批量梯度下降算法非常耗时。
从图中可以看出SGD迭代的次数(theta变多了)较多,在解空间的搜索过程看起来很盲目,但是大体上是往着最优值方向移动。
theta的迭代次数较少。
由于批量梯度下降每次更新参数时,要用到所有的样本数,这样随着样本增加,越来越耗时(电脑主板可能烧了)
少了求和,部分代码:
for i in range(m):
diff[0] = y[i]-(theta0+theta1*X[i])
diff[1] = (y[i]-(theta0+theta1*X[i]))*X[i]
theta0 = theta0+alpha*diff[0]
theta1 = theta1+alpha*diff[1]
·······················································
输出:
0.4137930656912447 4.9655167882949005 11170
74.89654489011475
接下来,小批量梯度下降:
演示代码:
import numpy as np
X=np.arange(0,10,0.5)
m=len(X)
y=2*X+5+np.random.randn(m)
#初始化参数
theta0=theta1=0
#学习率
alpha=0.00001
#迭代次数(开始为0)
cnt=0
#误差
error0=error1=0
#误差需要小于指定的阈值,指定一个阈值,用与检查两次误差的差,以便停止迭代
threshold=0.0000001
while True:
diff=[0,0] #两个梯度都为0
x0=1
for i in range(0,m,2): #2步长
diff[0] += (y[i]-(theta0+theta1*X[i]))*x0
diff[1] += (y[i]-(theta0+theta1*X[i]))*X[i]
theta0 = theta0+alpha*diff[0]
theta1 = theta1+alpha*diff[1]
#计算误差
for i in range(m):
error1 += (y[i]-(theta0+theta1*X[i]))**2
error1 /= m
if abs(error1-error0)<threshold:
break
else:
error0=error1
cnt += 1
print(theta0,theta1,cnt)
·············································
4.569535230315497 1.9815381626289499 86272
总结:
批量梯度下降每次更新使用了所有的训练数据,最小化损失函数,**如果只有一个极小值,那么批量梯度下降是考虑了训练集所有数据,是朝着最小值迭代运动的**,但是缺点是如果样本值很大的话,更新速度会很慢。
随机梯度下降在每次更新的时候,只考虑了一个样本点,这样会大大加快训练数据,也恰好是批量梯度下降的缺点,但是有可能由于训练数据的噪声点较多,**那么每一次利用噪声点进行更新的过程中,就不一定朝着极小值方向更新,但是由于更新多轮,整体还是朝着极小值方向更新,有提高了速度**。
小批量梯度下降是为了解决批量梯度下降法的训练速度慢,以及随机梯度下降法的准确性综合而来,但是这里注意,不同问题的batch是不一样的(只能通过实验结果来调整参数)
只有numpy才能处理高维。以上都是用numpy实现的
来源:CSDN
作者:The Silencer
链接:https://blog.csdn.net/weixin_42676175/article/details/103459214