1、定义

根据已知的数据集,通过梯度下降的方法来训练线性回归模型的参数w,从而用线性回归模型来预测数据的未知的类别。

2、一元线性回归

一元线性回归是分析只有一个自变量(自变量x和因变量y)线性相关关系的方法。一个经济指标的数值往往受许多因素影响,若其中只有一个因素是主要的,起决定性作用,则可用一元线性回归进行预测分析。

一元线性回归分析法的预测模型为:

在这里插入图片描述

这个方程对应的图像是一条直线。

3、代价函数-最小二乘法

残差:真实值和预测值之间的差值。用公式表示为:

在这里插入图片描述

在这里插入图片描述

代价函数也称为损失函数为每个真实值与预测值之前的残差平方之和,具体公式如下所示:

在这里插入图片描述

找到合适的参数,使得损失函数的值最小。

由以上公式可知,损失函数为一个二次方程,所以损失函数取最低点时,此时误差最小,拟合程度最高。

在这里插入图片描述

因为,损失函数有两个未知量,因此可以画出一个三维空间中的图像。

在这里插入图片描述

总结:机器学习的目标就是找到代价函数的最小值来实现对数据的最优拟合。

4、梯度下降法

不断改变两个参数的值,直到损失函数到达一个全局最小值,或局部最小值。

在这里插入图片描述

其中红色的区域损失函数的值最大,蓝色的值损失函数的值最小。迭代的过程为,首先设置一个初始值,向着梯度下降的方法迭代。

梯度下降法公式如下所示:

在这里插入图片描述

其中J:损失函数

其中参数1的迭代过程如下所示:

在这里插入图片描述

5、梯度下降法-一元线性回归(实战)

import numpy as np
import matplotlib.pyplot as plt
plt.style.use('ggplot')
#载入数据
data=np.genfromtxt("data.csv",delimiter=",")
#数据为两列,且之间的分割符为','
x_data=data[:,0]#第一列
y_data=data[:,1]#第二列
plt.scatter(x_data,y_data)#画图
plt.show()
#学习率learning rate
lr=0.0001
b=0#截距
k=0#斜率一元线性回归y=k*x+b
epochs=100#迭代次数
#最小二乘法.代价函数
def compute_error(b,k,x_data,y_data):
    t=0
    for i in range(0,len(x_data)):
        t+=(y_data[i]-(k*x_data[i]+b))**2#真实值减去预测值的平方和
    return t/float(len(x_data))/2
def gradient_descent_runner(x_data,y_data,b,k,lr,epochs):#梯度下降法
    #计算总数据量
    m=float(len(x_data))
    #循环epochs次
    for i in range(epochs):
        b_grad=0
        k_grad=0
        #计算梯度的总和再求平均
        for j in range(0,len(x_data)):
            b_grad+=(1/m)*(((k*x_data[i])+b)-y_data[j])#预测值-真实值的和
            k_grad+=(1/m)*x_data[j]*(((k*x_data[j])+b)-y_data[j])
        #更新b和k
        b=b-(lr*b_grad)
        k=k-(lr*k_grad)
        #没迭代10次输出一次图像
        if i%10==0:
            print("epochs:",i)
            plt.plot(x_data,y_data,'b.')
            plt.plot(x_data,k*x_data+b,'r_')
            plt.show()
    return b,k
print("Starting b = {0}, k = {1}, error = {2}".format(b, k, compute_error(b, k, x_data, y_data)))
print("Running...")
b, k = gradient_descent_runner(x_data, y_data, b, k, lr, epochs)
print("After {0} iterations b = {1}, k = {2}, error = {3}".format(epochs, b, k, compute_error(b, k, x_data, y_data)))

运行结果:

在这里插入图片描述

6、sklearn------一元线性回归(实战)

sklearn是基于python语言的机器学习工具包,是目前做机器学习项目当之无愧的第一工具。 sklearn自带了大量的数据集,可供我们练习各种机器学习算法。 sklearn集成了数据预处理、数据特征选择、数据特征降维、分类\回归\聚类模型、模型评估等非常全面算法。

from sklearn.linear_model import LinearRegression
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('ggplot')
#载入数据
data=np.genfromtxt("data.csv",delimiter=",")
x_data=data[:,0]#一维数据(100,)
y_data=data[:,1]
plt.scatter(x_data,y_data)
plt.show()
print(x_data.shape)
x_data=data[:,0,np.newaxis]#给数据加一个维度(100,1)要求数据为二维数据
y_data=data[:,1,np.newaxis]
#创建并拟合模型
model=LinearRegression()#创建线性回归模型
model.fit(x_data,y_data)#fit建模
#画图
plt.plot(x_data,y_data,'b.')
plt.plot(x_data,model.predict(x_data),'r.')
plt.show()

结果:

在这里插入图片描述

7、多元线性回归模型

在回归分析中,如果有两个或两个以上的自变量,就称为多元线性回归。

在这里插入图片描述

当y的影响不唯一时则采用多元线性回归,采用超平面来拟合多元线性回归的分布
在这里插入图片描述

代价函数的定义:
在这里插入图片描述

梯度下降法:

在这里插入图片描述

8、梯度下降法-多元线性回归(实战)

数据集为运输的数据集,根据运输的里程和次数来预测运输的时间。

import numpy as np
from numpy import genfromtxt
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
plt.style.use('ggplot')
#载入数据
data=genfromtxt(r"Delivery.csv",delimiter=",")
#切分数据
x_data=data[:,:-1]
y_data=data[:,-1]
#学习率
lr=0.0001
#参数
theta0=0
theta1=0
theta2=0
epochs=100#迭代次数
#最小二乘法
def compute_error(theta0,theta1,theta2,x_data,y_data):
    t=0
    for i in range(0,len(x_data)):
        t+=(y_data[i]-(theta1*x_data[i,0]+theta2*data[i,1]+theta0))**2#真实值减去预测值的平方和
    return t/float(len(x_data))/2
#梯度下降法
def gradient_descent_runner(x_data,y_data,theta0,theta1,theta2,lr,epochs):#梯度下降法
    #计算总数据量
    m=float(len(x_data))
    #循环epochs次
    for i in range(epochs):
        theta0_grad=0
        theta1_grad=0
        theta2_grad=0
        #计算梯度的总和再求平均
        for j in range(0,len(x_data)):
            theta0_grad+=(1/m)*((theta1*x_data[j,0]+theta2*data[j,1]+theta0)-y_data[j])
            theta1_grad+=(1/m)*x_data[j,0]*((theta1*x_data[j,0]+theta2*x_data[j,1]+theta0)-y_data[j])
            theta2_grad+=(1/m)*x_data[j,1]*((theta1*x_data[j,0]+theta2*x_data[j,1]+theta0)-y_data[j])
        #更新theta
        theta0=theta0-(lr*theta0_grad)
        theta1=theta1-(lr*theta1_grad)
        theta2=theta2-(lr*theta2_grad)                          
    return theta0,theta1,theta2
print("Starting theta0 = {0}, theta1 = {1}, theta2= {2},error={3}".format(theta0,theta1,theta2,compute_error(theta0,theta1,theta2, x_data, y_data)))
print("Running...")
theta0,theta1,theta2 = gradient_descent_runner(x_data, y_data, theta0,theta1,theta2, lr, epochs)
print("After {0} iterations theta0={1},theta1={2},theta2={3}, error = {4}".format(epochs,theta0,theta1,theta2,compute_error(theta0,theta1,theta2,x_data, y_data)))
#画3d图
ax=plt.figure().add_subplot(111,projection='3d')
ax.scatter(x_data[:,0],x_data[:,1],y_data,c='b',marker='o',s=50)#点为红色三角,s代表点的大小
x0=x_data[:,0]
x1=x_data[:,1]
#生成网格矩阵
x0,x1=np.meshgrid(x0,x1)
z=theta0+theta1*x0+theta2*x1
#画3d图
ax.plot_surface(x0,x1,z)
#设置坐标轴
ax.set_xlabel('Miles')
ax.set_ylabel('Num of Deliveries')
ax.set_zlabel('Time')
#显示图像
plt.show()


迭代100次后,theta0=0.001622221004377022,theta1=0.08255448397817376,theta2=0.010522070623305712, error = 0.4347682790750528

结果为:

在这里插入图片描述

9、sklearn-多元线性回归(实战)

import numpy as np
from numpy import genfromtxt
from sklearn import linear_model
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
plt.style.use('ggplot')
#读入数据
data=genfromtxt(r"Delivery.csv",delimiter=",")
#切分数据
x_data=data[:,:-1]
y_data=data[:,-1]
#创建模型
model=linear_model.LinearRegression()
model.fit(x_data,y_data)
#系数
print("系数:",model.coef_)
print("截距:",model.intercept_)
#测试
x_test=[[102,4]]
predict=model.predict(x_test)
print("predict",predict)
#画3d图
ax=plt.figure().add_subplot(111,projection='3d')
ax.scatter(x_data[:,0],x_data[:,1],y_data,c='b',marker='o',s=50)#点为红色三角,s代表点的大小
x0=x_data[:,0]
x1=x_data[:,1]
#生成网格矩阵
x0,x1=np.meshgrid(x0,x1)
z=model.intercept_+x0*model.coef_[0]+x1*model.coef_[1]
#画3d图
ax.plot_surface(x0,x1,z)
#设置坐标轴
ax.set_xlabel('Miles')
ax.set_ylabel('Num of Deliveries')
ax.set_zlabel('Time')
#显示图像
plt.show()

结果:

在这里插入图片描述

10、多项式回归

多项式回归是线性回归的一种扩展,它可以使我们对非线性关系进行建模。线性回归使用直线来拟合数据,如一次函数y = kx+b。而多项式回归则使用曲线来拟合数据,如二次函数y=ax2+bx+c,三次函数y=ax3+bx^2+cx+d等,具体公式如下所示:

在这里插入图片描述

对于多项式回归建模来说,建模迅速,对于小数据量,简单的关系很有效。缺点就是难以很好的表达高度复杂的数据。

10、sklearn-多项式回归(实战)

数据集为工资数据集,根据城市的水平来预测工资。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
plt.style.use('ggplot')
#载入数据
data=np.genfromtxt("job.csv",delimiter=",")
x_data=data[1:,1]
y_data=data[1:,2]
print(x_data)
print(y_data)
plt.scatter(x_data,y_data)#散点图
plt.show()

x_data=data[1:,1,np.newaxis]
y_data=data[1:,2,np.newaxis]
print(x_data)
#创建并拟合模型
model=LinearRegression()
model.fit(x_data,y_data)
#画图
plt.plot(x_data,y_data,'b.')
plt.plot(x_data,model.predict(x_data),'r')
plt.show()

#定义多项式回归,degree的值可以调节多项式的特征
poly_reg=PolynomialFeatures(degree=5)#多项式方法,degree 为偏置值,2代表平方,3代表三次方
#特征处理
x_poly=poly_reg.fit_transform(x_data)
#定义回归模型
lin_reg=LinearRegression()
#训练模型
lin_reg.fit(x_poly,y_data)
#画图
plt.plot(x_data,y_data,"b.")
plt.plot(x_data,lin_reg.predict(poly_reg.fit_transform(x_data)),c='r')
plt.title('多项式回归')
plt.xlabel('position level')
plt.ylabel('salary')
plt.show()


线性回归拟合结果:

在这里插入图片描述

多项式回归拟合结果:

在这里插入图片描述

11、标准方程法

标准方程法,求解线性回归的另一种方法。
在这里插入图片描述

对theta求导使得结果等于零,求theta

在这里插入图片描述

分子布局(Numerator-layout):分子为列向量或者分母为行向量。

分母布局(Denominator-layout):分子为行向量或者分母为列向量。

梯度下降法与标准方程法的比较

梯度下降法:优点:当特征值非常多的时候也可以很好的工作

缺点:1,需要选择合适的学习率 2.需要迭代很多个周期 3.只能找到最优解的近似值

标准方程法:优点1.不需要学习率 2.不需要迭代 3.可以得到全局最优解

缺点:1.需要计算(XTX)-1 2.时间复杂度大约为n^3 3.n为特征数量

12、标准方程法-线性回归(实战)

import numpy as np
from numpy import genfromtxt
import matplotlib.pyplot as plt
plt.style.use('ggplot')
#载入数据
data=np.genfromtxt("data.csv",delimiter=",")
x_data=data[:,0,np.newaxis]#newaxis加一个维度
y_data=data[:,1,np.newaxis]
#给样本添加偏置项
X_data=np.concatenate((np.ones((100,1)),x_data),axis=1)#左边为100行1列的全1矩阵,右边为x_data,concatenate合并两个矩阵
#标准方程法求解回归参数
def weights(xArr,yArr):
    xMat=np.mat(xArr)
    yMat=np.mat(yArr)#转化为矩阵的形式
    xTx=xMat.T*xMat#矩阵乘法,看矩阵的值是否为零,若为零则没有逆矩阵
    #计算矩阵的值,如果值为0,说明该矩阵没有逆矩阵
    if np.linalg.det(xTx)==0.0:
        print("该矩阵没有逆矩阵")
        return 
    ws=xTx.I*xMat.T*yMat#.I为逆矩阵
    return ws
ws=weights(X_data,y_data)
#画图
x_test=np.array([[20],[80]])
y_test=ws[0]+x_test*ws[1]
plt.plot(x_data,y_data,'b.')
plt.plot(x_test,y_test,'r')
plt.show()

结果:

在这里插入图片描述

13、特征缩放

在这里插入图片描述

若多个特征相差较大的情况下,梯度下降法将会出现问题。若出现这种情况将有两种处理方式:数据归一化和均值标准化。

数据归一化

数据归一化就是把数据的取值范围处理为[0,1]或者[-1,1]之间.

任意数据转化为[0,1]之间:newValue=(oldValue-min)/(max-min)

例如:(1,3,5)

(1-1)/(5-1)=0

(3-1)/(5-1)=0.5

(5-1)/(5-1)=1

任意数据转化为[-1,1]之间:newValue=((oldValue-min)/(max-min)-0.5)*2

例如:(1,3,5)

((1-1)/(5-1)-0.5)*2=-1

((3-1)/(5-1)-0.5)*2=0

((5-1)/(5-1)-0.5)*2=1

均值标准化

x为特征数据,u为数据的平均值,s为数据的方差

newValue=(oldValue-u)/s

例如:(1,3,5,7,9)

u=(1+3+5+7+9)/5=5

s=((1-5)2+(3-5)2+(5-5)2+(7-5)2+(9-5)^2)/5=8

(1-5)/8=-1/2

(3-5)/8=-1/4

(5-5)/8=0

(7-5)/8=1/4

(9-5)/8=1/2

14、交叉验证法

交叉验证法是一种测试的方法,若数据集太少的话,只分为训练集和验证集,得到的结果将不是很准确。若数据样本太少,将会使用交叉验证法来扩充模型的训练样本。交叉验证法一般把数据集划分为10分,每次使用不用的数据来进行模型的验证,会得到10个误差。最后把10个误差的平均值最为模型的最后误差。

在这里插入图片描述

15、过拟合

在这里插入图片描述

若训练的误差较大时,则称为欠拟合。若训练的模型过复杂,在训练集中的loss=0,则称为过拟合。过拟合在训练集中表现的很好,在测试集中表现差。正确拟合在训练集和测试集中都表现的很好。
在这里插入图片描述

如何防止过拟合?

1、减少特征

2、增加数据量

3、正则化(regularized)

在这里插入图片描述

16、岭回归(Ridge Regression)

在这里插入图片描述

lamda为岭系数,I为单位矩阵。

为了解决矩阵不可逆的情况(数据特征大于样本点数)lamda一本为比较小的数
在这里插入图片描述

岭回归最早用来处理特征数多于样本的情况,现在也用于在估计中加入偏差,从而得到更好的估计。同时也可以解决多重共线性的问题。岭回归是一种有偏估计。

在这里插入图片描述

选择lamda值,使的各回归系数的岭估计基本稳定,残差平方和增大不太多。上图中每条线代表不同的参数。

17、sklearn-岭回归

数据集为Longley数据集。

import numpy as np
from numpy import genfromtxt
from sklearn import linear_model
import matplotlib.pyplot as plt
plt.style.use('ggplot')
#读入数据
data=genfromtxt(r"longley.csv",delimiter=",")
#切分数据
x_data=data[1:,2:]
y_data=data[1:,1]
#创建模型
#生成50个值
alphas_to_test=np.linspace(0.001,1)#0.001-1之间随机50个值
#创建模型,保存误差值
model=linear_model.RidgeCV(alphas=alphas_to_test,store_cv_values=True)#RidgeCV交叉验证
model.fit(x_data,y_data)
#画图
#岭系数跟loss的关系
plt.plot(alphas_to_test,model.cv_values_.mean(axis=0))
#选取岭系数值的位置
plt.plot(model.alpha_,min(model.cv_values_.mean(axis=0)),'ro')
plt.show()

结果:

在这里插入图片描述

18、标准方程法-岭回归

import numpy as np
from numpy import genfromtxt
from sklearn import linear_model
import matplotlib.pyplot as plt
#读入数据
data=genfromtxt(r"longley.csv",delimiter=",")
#切分数据
x_data=data[1:,2:]
y_data=data[1:,1,np.newaxis]
#给样本添加偏置量
X_data=np.concatenate((np.ones((16,1)),x_data),axis=1)
#岭回归标准方程法求解回归参数
def weights(xArr,yArr,lam=0.2):
    xMat=np.mat(xArr)
    yMat=np.mat(yArr)#转化为矩阵的形式
    xTx=xMat.T*xMat#矩阵乘法,看矩阵的值是否为零,若为零则没有逆矩阵
    #计算矩阵的值,如果值为0,说明该矩阵没有逆矩阵
    rxTx=xTx+np.eye(xMat.shape[1])*lam
    if np.linalg.det(rxTx)==0.0:
        print("该矩阵没有逆矩阵")
        return 
    ws=rxTx.I*xMat.T*yMat#.I为逆矩阵
    return ws
ws=weights(X_data,y_data)
print(ws)
#计算预测值
np.mat(X_data)*np.mat(ws)

19、LASSO

LASSO是由1996年Robert Tibshirani首次提出,全称Least absolute shrinkage and selection operator。该方法是一种压缩估计。它通过构造一个惩罚函数得到一个较为精炼的模型,使得它压缩一些回归系数,即强制系数绝对值之和小于某个固定值;同时设定一些回归系数为零。因此保留了子集收缩的优点,是一种处理具有复共线性数据的有偏估计。

代价函数

在这里插入图片描述

在这里插入图片描述

黑色代表代价函数最小的值,红的圈圈,每一圈代表的代价函数的值相同。蓝色代表lamda的限定范围,在限定范围的情况下,代价函数的值越小越好。

20、sklearn-LASSO

import numpy as np
from numpy import genfromtxt
from sklearn import linear_model
#读入数据
data=genfromtxt(r"longley.csv",delimiter=",")
print(data)
#划分数据
x_data=data[1:,2:]
y_data=data[1:,1]
print(x_data)
print(y_data)
#创建模型
model=linear_model.LassoCV()#创建LASSO模型,CV交叉验证,自动选取100个值,选最小的为正则项系数
model.fit(x_data,y_data)
#Lasso系数
#lasso使得几个系数直接等于0,这几个系数线性相关则选取一个系数,其他设为0
print(model.alpha_)
#相关系数
print(model.coef_)
model.predict(x_data[-2,np.newaxis])#预测

21、弹性网(Elastic Net)

在这里插入图片描述

当q=2时为岭回归,当q=1时为LASSO。

在这里插入图片描述

弹性网相当于结合了岭回归和LASSO。相当于两者的综合。

import numpy as np
from numpy import genfromtxt
from sklearn import linear_model
#读入数据
data=genfromtxt(r"longley.csv",delimiter=",")
#划分数据
x_data=data[1:,2:]
y_data=data[1:,1]
#创建模型
model=linear_model.ElasticNetCV()#创建弹性网模型
model.fit(x_data,y_data)
#弹性网系数系数
print(model.alpha_)
#相关系数
print(model.coef_)
model.predict(x_data[-2,np.newaxis])#预测

参考:https://blog.csdn.net/suotanyu1595/article/details/120362070

参考视频:https://www.bilibili.com/video/BV1Rt411q7WJ?p=23&vd_source=166e4ef02c5e9ffa3f01c2406aec1508

更多推荐